The mapping from XInput button mask to the standard X event button mask is not 1...
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 9 Aug 2012 01:36:31 +0000 (01:36 +0000)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 9 Aug 2012 01:36:31 +0000 (01:36 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1386 7f0cb862-5218-0410-a997-914c9d46530a

src/x11/fg_xinput_x11.c

index f98a7ed..023e068 100644 (file)
@@ -13,6 +13,9 @@
 #include <X11/Xlib.h>
 #include <X11/extensions/XInput2.h>
 
+/* 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