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 _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs