The mapping from XInput button mask to the standard X event button mask is not 1-1, fixed.
git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1386 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
03fea19290
commit
b8ea74d51e
@ -13,6 +13,9 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/XInput2.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 */
|
/* import function from freeglut_main.c */
|
||||||
extern int fgPlatformGetModifiers( int state );
|
extern int fgPlatformGetModifiers( int state );
|
||||||
|
|
||||||
@ -112,9 +115,9 @@ void fgPrintXIDeviceEvent(XIDeviceEvent* event)
|
|||||||
printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
|
printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
|
||||||
printf(" detail: %d\n", event->detail);
|
printf(" detail: %d\n", event->detail);
|
||||||
printf(" buttons:");
|
printf(" buttons:");
|
||||||
for (i = 0; i < event->buttons.mask_len * 8; i++)
|
for (i = 0; i < event->buttons.mask_len * 8; i++)
|
||||||
if (XIMaskIsSet(event->buttons.mask, i))
|
if (XIMaskIsSet(event->buttons.mask, i))
|
||||||
printf(" %d", i);
|
printf(" %d", i);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\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 )
|
void fgHandleExtensionEvents( XEvent* base_ev )
|
||||||
{
|
{
|
||||||
XEvent std_ev; /* standard single-pointer event to be added to the event queue */
|
XEvent std_ev; /* standard single-pointer event to be added to the event queue */
|
||||||
int i, button = 0;
|
int i, button = 0;
|
||||||
XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
|
XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
|
||||||
|
|
||||||
/* initialize the generic fields from base_ev */
|
/* initialize the generic fields from base_ev */
|
||||||
std_ev.xany = base_ev->xany;
|
std_ev.xany = base_ev->xany;
|
||||||
|
|
||||||
if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
|
if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
|
||||||
|
|
||||||
XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
|
XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
|
||||||
XIEnterEvent *evcross;
|
XIEnterEvent *evcross;
|
||||||
/*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
|
/*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
|
||||||
|
|
||||||
SFG_Window* window = fgWindowByHandle( event->event );
|
SFG_Window* window = fgWindowByHandle( event->event );
|
||||||
if (!window) return;
|
if (!window) return;
|
||||||
|
|
||||||
switch (cookie->evtype) {
|
switch (cookie->evtype) {
|
||||||
case XI_Enter:
|
case XI_Enter:
|
||||||
case XI_Leave:
|
case XI_Leave:
|
||||||
evcross = (XIEnterEvent*)event;
|
evcross = (XIEnterEvent*)event;
|
||||||
|
|
||||||
fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base );
|
fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base );
|
||||||
INVOKE_WCB( *window, MultiEntry, (
|
INVOKE_WCB( *window, MultiEntry, (
|
||||||
event->deviceid,
|
event->deviceid,
|
||||||
(event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
|
(event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
|
||||||
));
|
));
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
fgPrintXILeaveEvent((XILeaveEvent*)event);
|
fgPrintXILeaveEvent((XILeaveEvent*)event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Also process the standard crossing event */
|
/* Also process the standard crossing event */
|
||||||
std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify;
|
std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify;
|
||||||
std_ev.xcrossing.window = evcross->event;
|
std_ev.xcrossing.window = evcross->event;
|
||||||
std_ev.xcrossing.root = evcross->root;
|
std_ev.xcrossing.root = evcross->root;
|
||||||
std_ev.xcrossing.subwindow = evcross->child;
|
std_ev.xcrossing.subwindow = evcross->child;
|
||||||
std_ev.xcrossing.x = evcross->event_x;
|
std_ev.xcrossing.x = evcross->event_x;
|
||||||
std_ev.xcrossing.y = evcross->event_y;
|
std_ev.xcrossing.y = evcross->event_y;
|
||||||
std_ev.xcrossing.x_root = evcross->root_x;
|
std_ev.xcrossing.x_root = evcross->root_x;
|
||||||
std_ev.xcrossing.y_root = evcross->root_y;
|
std_ev.xcrossing.y_root = evcross->root_y;
|
||||||
std_ev.xcrossing.mode = evcross->mode;
|
std_ev.xcrossing.mode = evcross->mode;
|
||||||
std_ev.xcrossing.detail = evcross->detail;
|
std_ev.xcrossing.detail = evcross->detail;
|
||||||
std_ev.xcrossing.same_screen = evcross->same_screen;
|
std_ev.xcrossing.same_screen = evcross->same_screen;
|
||||||
std_ev.xcrossing.focus = evcross->focus;
|
std_ev.xcrossing.focus = evcross->focus;
|
||||||
std_ev.xcrossing.state = *(unsigned int*)evcross->buttons.mask;
|
std_ev.xcrossing.state = BUTTON_MASK(*(unsigned int*)evcross->buttons.mask);
|
||||||
|
|
||||||
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XI_ButtonPress:
|
case XI_ButtonPress:
|
||||||
case XI_ButtonRelease:
|
case XI_ButtonRelease:
|
||||||
fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
|
fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
|
||||||
INVOKE_WCB( *window, MultiButton, (
|
INVOKE_WCB( *window, MultiButton, (
|
||||||
event->deviceid,
|
event->deviceid,
|
||||||
event->event_x,
|
event->event_x,
|
||||||
event->event_y,
|
event->event_y,
|
||||||
event->detail-1,
|
event->detail-1,
|
||||||
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
|
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
|
||||||
));
|
));
|
||||||
|
|
||||||
/* Also process the standard button event */
|
/* Also process the standard button event */
|
||||||
std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
|
std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease;
|
||||||
std_ev.xbutton.window = event->event;
|
std_ev.xbutton.window = event->event;
|
||||||
std_ev.xbutton.root = event->root;
|
std_ev.xbutton.root = event->root;
|
||||||
std_ev.xbutton.subwindow = event->child;
|
std_ev.xbutton.subwindow = event->child;
|
||||||
std_ev.xbutton.x = event->event_x;
|
std_ev.xbutton.x = event->event_x;
|
||||||
std_ev.xbutton.y = event->event_y;
|
std_ev.xbutton.y = event->event_y;
|
||||||
std_ev.xbutton.x_root = event->root_x;
|
std_ev.xbutton.x_root = event->root_x;
|
||||||
std_ev.xbutton.y_root = event->root_y;
|
std_ev.xbutton.y_root = event->root_y;
|
||||||
std_ev.xbutton.state = *(unsigned int*)event->buttons.mask;
|
std_ev.xbutton.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask);
|
||||||
std_ev.xbutton.button = event->detail;
|
std_ev.xbutton.button = event->detail;
|
||||||
|
|
||||||
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XI_Motion:
|
case XI_Motion:
|
||||||
fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
|
fgState.Modifiers = fgPlatformGetModifiers( event->mods.base );
|
||||||
for (i = 0; i < event->buttons.mask_len; i++) {
|
for (i = 0; i < event->buttons.mask_len; i++) {
|
||||||
if (event->buttons.mask[i]) {
|
if (event->buttons.mask[i]) {
|
||||||
button = 1;
|
button = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (button) {
|
if (button) {
|
||||||
INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) );
|
INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) );
|
||||||
} else {
|
} else {
|
||||||
INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
|
INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
|
||||||
}
|
}
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
fgPrintXIDeviceEvent(event);
|
fgPrintXIDeviceEvent(event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Also process the standard motion event */
|
/* Also process the standard motion event */
|
||||||
std_ev.type = MotionNotify;
|
std_ev.type = MotionNotify;
|
||||||
std_ev.xmotion.window = event->event;
|
std_ev.xmotion.window = event->event;
|
||||||
std_ev.xmotion.root = event->root;
|
std_ev.xmotion.root = event->root;
|
||||||
std_ev.xmotion.subwindow = event->child;
|
std_ev.xmotion.subwindow = event->child;
|
||||||
std_ev.xmotion.time = event->time;
|
std_ev.xmotion.time = event->time;
|
||||||
std_ev.xmotion.x = event->event_x;
|
std_ev.xmotion.x = event->event_x;
|
||||||
std_ev.xmotion.y = event->event_y;
|
std_ev.xmotion.y = event->event_y;
|
||||||
std_ev.xmotion.x_root = event->root_x;
|
std_ev.xmotion.x_root = event->root_x;
|
||||||
std_ev.xmotion.y_root = event->root_y;
|
std_ev.xmotion.y_root = event->root_y;
|
||||||
std_ev.xmotion.state = *(unsigned int*)event->buttons.mask;
|
std_ev.xmotion.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask);
|
||||||
std_ev.xmotion.is_hint = NotifyNormal;
|
std_ev.xmotion.is_hint = NotifyNormal;
|
||||||
|
|
||||||
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
fgWarning( "Unknown XI2 device event:" );
|
fgWarning( "Unknown XI2 device event:" );
|
||||||
fgPrintXIDeviceEvent( event );
|
fgPrintXIDeviceEvent( event );
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fgState.Modifiers = INVALID_MODIFIERS;
|
fgState.Modifiers = INVALID_MODIFIERS;
|
||||||
}
|
}
|
||||||
XFreeEventData( fgDisplay.pDisplay.Display, cookie );
|
XFreeEventData( fgDisplay.pDisplay.Display, cookie );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user