[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29561] branches/soc-2010-merwin/intern/ ghost/intern: fixed tablet mouse spasm bug and refactored event handling

Mike Erwin significant.bit at gmail.com
Sat Jun 19 12:35:01 CEST 2010


Revision: 29561
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29561
Author:   merwin
Date:     2010-06-19 12:35:01 +0200 (Sat, 19 Jun 2010)

Log Message:
-----------
fixed tablet mouse spasm bug and refactored event handling

Modified Paths:
--------------
    branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.h
    branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.mm

Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.h
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.h	2010-06-19 10:32:41 UTC (rev 29560)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.h	2010-06-19 10:35:01 UTC (rev 29561)
@@ -251,14 +251,28 @@
 	virtual GHOST_TSuccess init();
 
     /**
-     * Handles a tablet event.
+     * Handles a tablet pen event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
-	 * @param eventType The type of the event. It needs to be passed separately as it can be either directly in the event type, or as a subtype if combined with a mouse button event
      * @return Indication whether the event was handled. 
      */
-    GHOST_TSuccess handleTabletEvent(void *eventPtr, short eventType);
+    GHOST_TSuccess handleTabletEvent(void *eventPtr);
     
 	/**
+     * Handles a tablet proximity event. Sets pen or mouse ID for later events.
+     * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+    GHOST_TSuccess handleTabletProximity(void *eventPtr);
+
+	/** Tablet Mouse and Pen IDs, used to correlate events with the tool that caused them. */
+	int m_tablet_mouse_id;
+	int m_tablet_pen_id;
+
+	static const int TOOL_ID_NONE = -1;
+
+	GHOST_TTabletMode m_tablet_pen_mode;
+
+	/**
      * Handles a mouse event.
      * @param eventPtr	An NSEvent pointer (casted to void* to enable compilation in standard C++)
      * @return Indication whether the event was handled. 

Modified: branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-06-19 10:32:41 UTC (rev 29560)
+++ branches/soc-2010-merwin/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-06-19 10:35:01 UTC (rev 29561)
@@ -31,6 +31,7 @@
 
 /*For the currently not ported to Cocoa keyboard layout functions (64bit & 10.6 compatible)*/
 #include <Carbon/Carbon.h>
+//#include <HIToolbox/Events.h>
 
 #include <sys/time.h>
 #include <sys/types.h>
@@ -553,6 +554,9 @@
 	m_isGestureInProgress = false;
 	m_cursorDelta_x=0;
 	m_cursorDelta_y=0;
+	m_tablet_mouse_id = TOOL_ID_NONE;
+	m_tablet_pen_id = TOOL_ID_NONE;
+	m_tablet_pen_mode = GHOST_kTabletModeNone;
 	m_outsideLoopEventProcessed = false;
 	m_needDelayedApplicationBecomeActiveEventProcessing = false;
 	m_displayManager = new GHOST_DisplayManagerCocoa ();
@@ -575,10 +579,9 @@
 	sysctl( mib, 2, rstring, &len, NULL, 0 );
 	
 	//Hack on MacBook revision, as multitouch avail. function missing
-	if (strstr(rstring,"MacBookAir") ||
-		(strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')))
-		m_hasMultiTouchTrackpad = true;
-	else m_hasMultiTouchTrackpad = false;
+	m_hasMultiTouchTrackpad =
+		(strstr(rstring,"MacBookAir") ||
+		(strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9')));
 	
 	free( rstring );
 	rstring = NULL;
@@ -593,7 +596,6 @@
 
 GHOST_TSuccess GHOST_SystemCocoa::init()
 {
-	
     GHOST_TSuccess success = GHOST_System::init();
     if (success) {
 		//ProcessSerialNumber psn;
@@ -879,105 +881,117 @@
 {
 	bool anyProcessed = false;
 	NSEvent *event;
-	
-	//	SetMouseCoalescingEnabled(false, NULL);
+	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
 	//TODO : implement timer ??
 	
-	/*do {
-		GHOST_TimerManager* timerMgr = getTimerManager();
+	do {
+		event = [NSApp nextEventMatchingMask:NSAnyEventMask
+									untilDate:[NSDate distantPast]
+									  inMode:NSDefaultRunLoopMode
+									 dequeue:YES];
+		if (event==nil)
+			break;
 		
-		 if (waitForEvent) {
-		 GHOST_TUns64 next = timerMgr->nextFireTime();
-		 double timeOut;
-		 
-		 if (next == GHOST_kFireTimeNever) {
-		 timeOut = kEventDurationForever;
-		 } else {
-		 timeOut = (double)(next - getMilliSeconds())/1000.0;
-		 if (timeOut < 0.0)
-		 timeOut = 0.0;
-		 }
-		 
-		 ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
-		 }
-		 
-		 if (timerMgr->fireTimers(getMilliSeconds())) {
-		 anyProcessed = true;
-		 }*/
+		anyProcessed = true;
 		
-		do {
-			NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-			event = [NSApp nextEventMatchingMask:NSAnyEventMask
-									   untilDate:[NSDate distantPast]
-										  inMode:NSDefaultRunLoopMode
-										 dequeue:YES];
-			if (event==nil) {
-				[pool drain];
+		switch ([event type]) {
+			case NSKeyDown:
+			case NSKeyUp:
+			case NSFlagsChanged:
+				handleKeyEvent(event);
+				// resend to ensure Mac-wide events are handled
+				[NSApp sendEvent:event];
 				break;
-			}
-			
-			anyProcessed = true;
-			
-			switch ([event type]) {
-				case NSKeyDown:
-				case NSKeyUp:
-				case NSFlagsChanged:
-					handleKeyEvent(event);
-					
-					/* Support system-wide keyboard shortcuts, like Exposé, ...) =>included in always NSApp sendEvent */
-					/*		if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
-					 [NSApp sendEvent:event];
-					 }*/
-					break;
-					
-				case NSLeftMouseDown:
-				case NSLeftMouseUp:
-				case NSRightMouseDown:
-				case NSRightMouseUp:
-				case NSMouseMoved:
-				case NSLeftMouseDragged:
-				case NSRightMouseDragged:
-				case NSScrollWheel:
-				case NSOtherMouseDown:
-				case NSOtherMouseUp:
-				case NSOtherMouseDragged:
-				case NSEventTypeMagnify:
-				case NSEventTypeRotate:
-				case NSEventTypeBeginGesture:
-				case NSEventTypeEndGesture:
-					handleMouseEvent(event);
-					break;
-					
-				case NSTabletPoint:
-				case NSTabletProximity:
-					handleTabletEvent(event,[event type]);
-					break;
-					
-					/* Trackpad features, fired only from OS X 10.5.2
-					 case NSEventTypeGesture:
-					 case NSEventTypeSwipe:
-					 break; */
-					
-					/*Unused events
-					 NSMouseEntered       = 8,
-					 NSMouseExited        = 9,
-					 NSAppKitDefined      = 13,
-					 NSSystemDefined      = 14,
-					 NSApplicationDefined = 15,
-					 NSPeriodic           = 16,
-					 NSCursorUpdate       = 17,*/
-					
-				default:
-					break;
-			}
-			//Resend event to NSApp to ensure Mac wide events are handled
-			[NSApp sendEvent:event];
-			[pool drain];
-		} while (event!= nil);		
-	//} while (waitForEvent && !anyProcessed); Needed only for timer implementation
+				
+			case NSLeftMouseDown:
+			case NSLeftMouseUp:
+			case NSLeftMouseDragged:
+
+			case NSRightMouseDown:
+			case NSRightMouseUp:
+			case NSRightMouseDragged:
+
+			case NSOtherMouseDown:
+			case NSOtherMouseUp:
+			case NSOtherMouseDragged:
+
+			case NSMouseMoved:
+				switch ([event subtype])
+					{
+					case NSMouseEventSubtype:
+						handleMouseEvent(event);
+						break;
+					case NSTabletPointEventSubtype:
+						handleTabletEvent(event);
+						break;
+					case NSTabletProximityEventSubtype:
+						// I think only LMB down/up sends this
+						handleTabletProximity(event);
+						break;
+
+					// Mac OS 10.6 introduces a Touch subtype
+					// that we ignore for now.
+					}
+				break;
+
+			case NSScrollWheel:
+				handleMouseEvent(event);
+				break;
+				
+			case NSTabletProximity:
+				handleTabletProximity(event);
+				break;
+
+			case NSTabletPoint:
+				if ([event deviceID] == m_tablet_pen_id)
+					handleTabletEvent(event);
+				else {
+					// Treat tablet mouse like any other mouse.
+					// TODO: teach Windows and Linux the same trick
+
+					// It continues to send events even when still, to mimic the pen's
+					// ability to vary pressure without moving. Since the mouse is
+					// unable to vary its pressure, filter them out as noise!
+
+					bool didMove = [event deltaX] != 0 and [event deltaY] != 0;
+					if (didMove)
+						handleMouseEvent(event);
+					// NSLeftMouseDown gets sent for the initial point, so this is safe.
+				}
+				break;
+				
+			case NSEventTypeMagnify:
+			case NSEventTypeRotate:
+			case NSEventTypeBeginGesture:
+			case NSEventTypeEndGesture:
+				handleMouseEvent(event);
+				// break out into handleGestureEvent?
+				break;
+
+			/* Trackpad features, fired only from OS X 10.5.2
+				 case NSEventTypeGesture:
+				 case NSEventTypeSwipe:
+				 break; */
+				
+			default:
+				break;
+			/*	Unused events:
+				NSMouseEntered       = 8,
+				NSMouseExited        = 9,
+				NSAppKitDefined      = 13,
+				NSSystemDefined      = 14,
+				NSApplicationDefined = 15,
+				NSPeriodic           = 16,
+				NSCursorUpdate       = 17,*/
+		}
+	} while (event != nil);		
 	
-	if (m_needDelayedApplicationBecomeActiveEventProcessing) handleApplicationBecomeActiveEvent();
+	[pool drain];
 	
+	if (m_needDelayedApplicationBecomeActiveEventProcessing)
+		handleApplicationBecomeActiveEvent();
+	
 	if (m_outsideLoopEventProcessed) {
 		m_outsideLoopEventProcessed = false;
 		return true;
@@ -986,6 +1000,7 @@
     return anyProcessed;
 }
 
+
 //Note: called from NSApplication delegate
 GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
 {
@@ -1360,57 +1375,81 @@
 	else return NO;
 }
 
-GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventType)
+GHOST_TSuccess GHOST_SystemCocoa::handleTabletProximity(void *eventPtr)
 {
 	NSEvent *event = (NSEvent *)eventPtr;
-	GHOST_IWindow* window;
-	
-	window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
+	GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)
+		m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
+
 	if (!window) {
 		//printf("\nW failure for event 0x%x",[event type]);
 		return GHOST_kFailure;
 	}
 	
-	GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
-	
-	switch (eventType) {
-		case NSTabletPoint:
-			ct.Pressure = [event pressure];
-			ct.Xtilt = [event tilt].x;
-			ct.Ytilt = [event tilt].y;
+	GHOST_TabletData& ct = window->GetCocoaTabletData();
+
+	GHOST_TTabletMode active_tool;
+	int* tool_id_ptr;
+
+	switch ([event pointingDeviceType])
+		{
+		case NSPenPointingDevice:
+			active_tool = GHOST_kTabletModeStylus;
+			tool_id_ptr = &m_tablet_pen_id;
 			break;
-		
-		case NSTabletProximity:
-			ct.Pressure = 0;
-			ct.Xtilt = 0;
-			ct.Ytilt = 0;
-			if ([event isEnteringProximity])
-			{
-				//pointer is entering tablet area proximity
-				switch ([event pointingDeviceType]) {
-					case NSPenPointingDevice:

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list