From: John Tsiombikas Date: Thu, 9 Aug 2012 01:36:31 +0000 (+0000) Subject: The mapping from XInput button mask to the standard X event button mask is not 1... X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=6dc97d7f1133eab6d075159c38f9cbd816de84e7;p=freeglut The mapping from XInput button mask to the standard X event button mask is not 1-1, fixed. git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1386 7f0cb862-5218-0410-a997-914c9d46530a --- diff --git a/src/x11/fg_xinput_x11.c b/src/x11/fg_xinput_x11.c index f98a7ed..023e068 100644 --- a/src/x11/fg_xinput_x11.c +++ b/src/x11/fg_xinput_x11.c @@ -13,6 +13,9 @@ #include #include +/* convert the XInput button state mask to the regular X mouse event button mask */ +#define BUTTON_MASK(xistate) ((xistate) << 8) + /* import function from freeglut_main.c */ extern int fgPlatformGetModifiers( int state ); @@ -112,9 +115,9 @@ void fgPrintXIDeviceEvent(XIDeviceEvent* event) printf(" device: %d (%d)\n", event->deviceid, event->sourceid); printf(" detail: %d\n", event->detail); printf(" buttons:"); - for (i = 0; i < event->buttons.mask_len * 8; i++) - if (XIMaskIsSet(event->buttons.mask, i)) - printf(" %d", i); + for (i = 0; i < event->buttons.mask_len * 8; i++) + if (XIMaskIsSet(event->buttons.mask, i)) + printf(" %d", i); printf("\n"); printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n", @@ -144,122 +147,122 @@ void fgPrintXIDeviceEvent(XIDeviceEvent* event) */ void fgHandleExtensionEvents( XEvent* base_ev ) { - XEvent std_ev; /* standard single-pointer event to be added to the event queue */ - int i, button = 0; - XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); - - /* initialize the generic fields from base_ev */ - std_ev.xany = base_ev->xany; - - if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { - - XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); - XIEnterEvent *evcross; - /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/ - - SFG_Window* window = fgWindowByHandle( event->event ); - if (!window) return; - - switch (cookie->evtype) { - case XI_Enter: - case XI_Leave: - evcross = (XIEnterEvent*)event; - - fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base ); - INVOKE_WCB( *window, MultiEntry, ( - event->deviceid, - (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) - )); - #if _DEBUG - fgPrintXILeaveEvent((XILeaveEvent*)event); - #endif - - /* Also process the standard crossing event */ - std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify; - std_ev.xcrossing.window = evcross->event; - std_ev.xcrossing.root = evcross->root; - std_ev.xcrossing.subwindow = evcross->child; - std_ev.xcrossing.x = evcross->event_x; - std_ev.xcrossing.y = evcross->event_y; - std_ev.xcrossing.x_root = evcross->root_x; - std_ev.xcrossing.y_root = evcross->root_y; - std_ev.xcrossing.mode = evcross->mode; - std_ev.xcrossing.detail = evcross->detail; - std_ev.xcrossing.same_screen = evcross->same_screen; - std_ev.xcrossing.focus = evcross->focus; - std_ev.xcrossing.state = *(unsigned int*)evcross->buttons.mask; - - XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); - break; - - case XI_ButtonPress: - case XI_ButtonRelease: - fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); - INVOKE_WCB( *window, MultiButton, ( - event->deviceid, - event->event_x, - event->event_y, - event->detail-1, - (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP) - )); - - /* Also process the standard button event */ - std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; - std_ev.xbutton.window = event->event; - std_ev.xbutton.root = event->root; - std_ev.xbutton.subwindow = event->child; - std_ev.xbutton.x = event->event_x; - std_ev.xbutton.y = event->event_y; - std_ev.xbutton.x_root = event->root_x; - std_ev.xbutton.y_root = event->root_y; - std_ev.xbutton.state = *(unsigned int*)event->buttons.mask; - std_ev.xbutton.button = event->detail; - - XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); - break; - - case XI_Motion: - fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); - for (i = 0; i < event->buttons.mask_len; i++) { - if (event->buttons.mask[i]) { - button = 1; - } - } - if (button) { - INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) ); - } else { - INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); - } - #if _DEBUG - fgPrintXIDeviceEvent(event); - #endif - - /* Also process the standard motion event */ - std_ev.type = MotionNotify; - std_ev.xmotion.window = event->event; - std_ev.xmotion.root = event->root; - std_ev.xmotion.subwindow = event->child; - std_ev.xmotion.time = event->time; - std_ev.xmotion.x = event->event_x; - std_ev.xmotion.y = event->event_y; - std_ev.xmotion.x_root = event->root_x; - std_ev.xmotion.y_root = event->root_y; - std_ev.xmotion.state = *(unsigned int*)event->buttons.mask; - std_ev.xmotion.is_hint = NotifyNormal; - - XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); - break; - - default: - #if _DEBUG - fgWarning( "Unknown XI2 device event:" ); - fgPrintXIDeviceEvent( event ); - #endif - break; - } - fgState.Modifiers = INVALID_MODIFIERS; - } - XFreeEventData( fgDisplay.pDisplay.Display, cookie ); + XEvent std_ev; /* standard single-pointer event to be added to the event queue */ + int i, button = 0; + XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); + + /* initialize the generic fields from base_ev */ + std_ev.xany = base_ev->xany; + + if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { + + XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); + XIEnterEvent *evcross; + /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/ + + SFG_Window* window = fgWindowByHandle( event->event ); + if (!window) return; + + switch (cookie->evtype) { + case XI_Enter: + case XI_Leave: + evcross = (XIEnterEvent*)event; + + fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base ); + INVOKE_WCB( *window, MultiEntry, ( + event->deviceid, + (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) + )); + #if _DEBUG + fgPrintXILeaveEvent((XILeaveEvent*)event); + #endif + + /* Also process the standard crossing event */ + std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify; + std_ev.xcrossing.window = evcross->event; + std_ev.xcrossing.root = evcross->root; + std_ev.xcrossing.subwindow = evcross->child; + std_ev.xcrossing.x = evcross->event_x; + std_ev.xcrossing.y = evcross->event_y; + std_ev.xcrossing.x_root = evcross->root_x; + std_ev.xcrossing.y_root = evcross->root_y; + std_ev.xcrossing.mode = evcross->mode; + std_ev.xcrossing.detail = evcross->detail; + std_ev.xcrossing.same_screen = evcross->same_screen; + std_ev.xcrossing.focus = evcross->focus; + std_ev.xcrossing.state = BUTTON_MASK(*(unsigned int*)evcross->buttons.mask); + + XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); + break; + + case XI_ButtonPress: + case XI_ButtonRelease: + fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); + INVOKE_WCB( *window, MultiButton, ( + event->deviceid, + event->event_x, + event->event_y, + event->detail-1, + (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP) + )); + + /* Also process the standard button event */ + std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; + std_ev.xbutton.window = event->event; + std_ev.xbutton.root = event->root; + std_ev.xbutton.subwindow = event->child; + std_ev.xbutton.x = event->event_x; + std_ev.xbutton.y = event->event_y; + std_ev.xbutton.x_root = event->root_x; + std_ev.xbutton.y_root = event->root_y; + std_ev.xbutton.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask); + std_ev.xbutton.button = event->detail; + + XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); + break; + + case XI_Motion: + fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); + for (i = 0; i < event->buttons.mask_len; i++) { + if (event->buttons.mask[i]) { + button = 1; + } + } + if (button) { + INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) ); + } else { + INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); + } + #if _DEBUG + fgPrintXIDeviceEvent(event); + #endif + + /* Also process the standard motion event */ + std_ev.type = MotionNotify; + std_ev.xmotion.window = event->event; + std_ev.xmotion.root = event->root; + std_ev.xmotion.subwindow = event->child; + std_ev.xmotion.time = event->time; + std_ev.xmotion.x = event->event_x; + std_ev.xmotion.y = event->event_y; + std_ev.xmotion.x_root = event->root_x; + std_ev.xmotion.y_root = event->root_y; + std_ev.xmotion.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask); + std_ev.xmotion.is_hint = NotifyNormal; + + XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); + break; + + default: + #if _DEBUG + fgWarning( "Unknown XI2 device event:" ); + fgPrintXIDeviceEvent( event ); + #endif + break; + } + fgState.Modifiers = INVALID_MODIFIERS; + } + XFreeEventData( fgDisplay.pDisplay.Display, cookie ); } #endif