[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29890] branches/soc-2010-merwin/ experimental/tap/event-tap.c: improved tablet support for low-level Mac event explorer

Mike Erwin significant.bit at gmail.com
Sat Jul 3 08:56:16 CEST 2010


Revision: 29890
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29890
Author:   merwin
Date:     2010-07-03 08:56:15 +0200 (Sat, 03 Jul 2010)

Log Message:
-----------
improved tablet support for low-level Mac event explorer

Modified Paths:
--------------
    branches/soc-2010-merwin/experimental/tap/event-tap.c

Modified: branches/soc-2010-merwin/experimental/tap/event-tap.c
===================================================================
--- branches/soc-2010-merwin/experimental/tap/event-tap.c	2010-07-03 06:50:52 UTC (rev 29889)
+++ branches/soc-2010-merwin/experimental/tap/event-tap.c	2010-07-03 06:56:15 UTC (rev 29890)
@@ -58,11 +58,6 @@
 		if ( not autoRepeat )
 			{
 			int keyCode = CGEventGetIntegerValueField( event, kCGKeyboardEventKeycode );
-			if ( keyCode == 53 ) // escape quits
-				{
-				CFRunLoopStop( CFRunLoopGetCurrent());
-				return NULL;
-				}
 			
 			const UniCharCount max = 20;
 			UniChar characters[ max ];
@@ -72,8 +67,15 @@
 			CFStringRef string = CFStringCreateWithCharacters( NULL, characters, actual );
 			char cstring[ max ];
 			CFStringGetCString( string, cstring, max, kCFStringEncodingASCII );
+			CFRelease(string);
 
 			printf("  key code: %d '%s'\n", keyCode, cstring );
+
+			if ( keyCode == 53 ) // escape quits
+				{
+				CFRunLoopStop( CFRunLoopGetCurrent());
+				return NULL;
+				}
 			}
 		}
 	else if ( mouseState != None )
@@ -96,6 +98,9 @@
 				printf("unknown\n");
 			}
 
+		static bool hasPressure = false;
+		static bool hasTilt = false;
+
 		if (mouseState & Proximity)
 			{
 			int pointer_type = CGEventGetIntegerValueField(event, kCGTabletProximityEventPointerType);
@@ -116,7 +121,7 @@
 					printf("unknown\n");
 				}
 
-			int entering = CGEventGetIntegerValueField(event, kCGTabletProximityEventEnterProximity);
+			bool entering = CGEventGetIntegerValueField(event, kCGTabletProximityEventEnterProximity);
 			if (entering)
 				{
 				printf("  entering\n");
@@ -141,11 +146,20 @@
 				if (cap & kTransducerButtonsBitMask)
 					printf("  - buttons\n");
 				if (cap & kTransducerTiltXBitMask)
+					{
 					printf("  - tilt x\n");
+					hasTilt = true;
+					}
 				if (cap & kTransducerTiltYBitMask)
+					{
 					printf("  - tilt y\n");
+					hasTilt = true;
+					}
 				if (cap & kTransducerPressureBitMask)
+					{
 					printf("  - pressure\n");
+					hasPressure = true;
+					}
 				if (cap & kTransducerTangentialPressureBitMask)
 					printf("  - tangential pressure\n");
 				if (cap & kTransducerOrientInfoBitMask)
@@ -154,78 +168,106 @@
 					printf("  - rotation\n");
 				}
 			else
+				{
 				printf("  leaving\n");
+				hasPressure = false;
+				hasTilt = false;
+				}
 			}
 		else // not proximity
 			{
 			CGPoint location = CGEventGetLocation( event );
 			printf("  location: %.2f,%.2f\n", location.x, location.y );
-			}
 
-		if (mouseState & Move)
-			{
-			int dx = CGEventGetIntegerValueField( event, kCGMouseEventDeltaX );
-			int dy = CGEventGetIntegerValueField( event, kCGMouseEventDeltaY );
-			printf("  delta: %d,%d\n", dx, dy );
- 			}
+			if (mouseState & Move)
+				{
+				int dx = CGEventGetIntegerValueField( event, kCGMouseEventDeltaX );
+				int dy = CGEventGetIntegerValueField( event, kCGMouseEventDeltaY );
+				printf("  delta: %d,%d\n", dx, dy );
+				}
 
-		if (mouseState & Button)
-			{
-			int buttons = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber);
-			printf("  buttons: ");
+			if (mouseState & Button)
+				{
+				int buttons = CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber);
+				printf("  buttons:");
 
-			// is this a bit mask or a single value?
-			if (buttons)
-				{
-				for (int i = 0; i < 32; ++i) // Quartz supports 32 buttons
-					if (buttons & (1 << i))
-						printf(" %d", i + 1);			
-				printf("\n");
+				// is this a bit mask or a single value? (it's a bit mask)
+				if (buttons)
+					{
+					for (int i = 0; i < 32; ++i) // Quartz supports 32 buttons
+						if (buttons & (1 << i))
+							printf(" %d", i + 1);			
+					printf("\n");
+					}
+				else
+					printf(" none\n");
 				}
-			else
-				printf(" none\n");
-			}
 
-		
-		if (subtype == kCGEventMouseSubtypeTabletPoint) // contact or hover
-			{
-			int dev_id = CGEventGetIntegerValueField(event, kCGTabletEventDeviceID);
-			// Graphire has same id for all tools, but Intuos can tell the difference
-			printf("  device id: %d\n", dev_id);
+			if (type == kCGEventTabletPointer or subtype == kCGEventMouseSubtypeTabletPoint) // contact or hover
+				{
+				int dev_id = CGEventGetIntegerValueField(event, kCGTabletEventDeviceID);
+				// Graphire has same id for all tools, but Intuos can tell the difference
+				printf("  device id: %d\n", dev_id);
 
-			int x = CGEventGetIntegerValueField(event, kCGTabletEventPointX);
-			int y = CGEventGetIntegerValueField(event, kCGTabletEventPointY);
-//			int z = CGEventGetIntegerValueField(event, kCGTabletEventPointZ);
-			printf("  abs position: %d,%d\n", x, y);
+				int x = CGEventGetIntegerValueField(event, kCGTabletEventPointX);
+				int y = CGEventGetIntegerValueField(event, kCGTabletEventPointY);
+				// int z = CGEventGetIntegerValueField(event, kCGTabletEventPointZ);
+				// Airbrush wheel provides z (pretty sure), otherwise unused
 
+				printf("  abs position: %d,%d\n", x, y);
 
-			int buttons = CGEventGetIntegerValueField(event, kCGTabletEventPointButtons);
-			printf("  tablet buttons:", buttons);
-			if (buttons)
-				{
-				for (int i = 0; i < 32; ++i) // does Wacom support only 16 buttons?
-					if (buttons & (1 << i))
-						printf(" %d", i + 1);			
-				printf("\n");
-				}
-			else
-				printf(" none\n");
 
-//			int v1 = CGEventGetIntegerValueField(event, kCGTabletEventVendor1);
-//			int v2 = CGEventGetIntegerValueField(event, kCGTabletEventVendor2);
-//			int v3 = CGEventGetIntegerValueField(event, kCGTabletEventVendor3);
-			
-//			if (buttons & 1) // tip/eraser in contact (not hovering)
-				{
-				float pressure = CGEventGetDoubleValueField(event, kCGTabletEventPointPressure);
-				printf("  pressure: %.3f\n", pressure);
+				int buttons = CGEventGetIntegerValueField(event, kCGTabletEventPointButtons);
+				printf("  tablet buttons:", buttons);
+				if (buttons)
+					{
+					for (int i = 0; i < 32; ++i) // does Wacom support only 16 buttons?
+						if (buttons & (1 << i))
+							printf(" %d", i + 1);			
+					printf("\n");
+					}
+				else
+					printf(" none\n");
 
-				float mouse_pressure = CGEventGetDoubleValueField(event, kCGMouseEventPressure);
-				printf("  mouse pressure: %.3f\n", mouse_pressure);
+	//			int v1 = CGEventGetIntegerValueField(event, kCGTabletEventVendor1);
+	//			int v2 = CGEventGetIntegerValueField(event, kCGTabletEventVendor2);
+	//			int v3 = CGEventGetIntegerValueField(event, kCGTabletEventVendor3);
+				
+				if (buttons & 1) // tip/eraser in contact (not hovering)
+					{
+					if (hasPressure)
+						{
+						// Could jam pressure bits into fractional part of float
+						// or just scale it as expected.
+						// One is very fast by avoiding int/float conversion.
+						// The other is easier to read.
+						// Could always provide conversion functions...
+						// u16 pack_u16(float);
+						// float unpack_u16(u16);
 
-//				double tilt_x = CGEventGetDoubleValueField(event, kCGTabletEventTiltX);
-//				double tilt_y = CGEventGetDoubleValueField(event, kCGTabletEventTiltY);
-//				printf("  tilt: %.4f,%.4f\n", tilt_x, tilt_y);
+						int pressure = CGEventGetIntegerValueField(event, kCGTabletEventPointPressure);
+						float f_pressure = (1.f / 65535.f) * pressure;
+						printf("  pressure: %.3f\n", f_pressure);
+
+//						float f_pressure = CGEventGetDoubleValueField(event, kCGTabletEventPointPressure);
+						// f_pressure ranges from zero to 2.0, probably due to an incorrect division:
+						// Dividing by MAX_S16 instead of by MAX_U16 would cause that.
+
+//						int mouse_pressure = CGEventGetIntegerValueField(event, kCGMouseEventPressure);
+//						float f_mouse_pressure = CGEventGetDoubleValueField(event, kCGMouseEventPressure);
+						// f_mouse_pressure is in the proper zero to 1.0 range.
+//						float my_mouse_pressure = (1.f / 255.f) * mouse_pressure;
+//						printf("  mouse pressure: %d %.3f\n", mouse_pressure, my_mouse_pressure);
+						}
+					
+					if (hasTilt)
+						{
+						double tilt_x = CGEventGetDoubleValueField(event, kCGTabletEventTiltX);
+						double tilt_y = CGEventGetDoubleValueField(event, kCGTabletEventTiltY);
+						// is tilt also native int, then converted to float?
+						printf("  tilt: %.3f,%.3f\n", tilt_x, tilt_y);
+						}
+					}
 				}
 			}
 		}
@@ -240,8 +282,18 @@
 	{
 	void* refcon = NULL;
 
-	CFMachPortRef port = CGEventTapCreate( kCGSessionEventTap, kCGHeadInsertEventTap, 0 /* active */, kCGEventMaskForAllEvents, callback, refcon );
+//	ProcessSerialNumber* psn;
+//	OSErr error = GetCurrentProcess(psn);
+//	if (error)
+//		printf("<!> GetCurrentProcess returned %d\n", error);
 
+// Can't get psn because this is a command-line program. Blender could install an app-local (psn) tap though...
+//	CFMachPortRef port = CGEventTapCreateForPSN( psn, kCGAnnotatedSessionEventTap, kCGTailAppendEventTap, kCGEventMaskForAllEvents, callback, refcon );
+
+	// kCGAnnotatedSessionEventTap kCGSessionEventTap kCGHIDEventTap
+	// Wasn't getting tablet pressure until I switched to Annotated.
+	CFMachPortRef port = CGEventTapCreate( kCGAnnotatedSessionEventTap, kCGTailAppendEventTap, 0, kCGEventMaskForAllEvents, callback, refcon );
+
 	if ( port and CGEventTapIsEnabled( port ))
 		puts("tap installed");
 	else





More information about the Bf-blender-cvs mailing list