/** * \brief This function is called when an Extension Event is received * and calls the corresponding callback functions for these events. */ void fgHandleExtensionEvents( XEvent* base_ev ) { int i, button = 0; XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); if ( XGetEventData( fgDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); /*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: fgState.Modifiers = fghGetXModifiers( ((XIEnterEvent*)event)->mods.base ); INVOKE_WCB( *window, MultiEntry, ( event->deviceid, (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) )); #if _DEBUG fgPrintXILeaveEvent((XILeaveEvent*)event); #endif break; case XI_ButtonPress: case XI_ButtonRelease: fgState.Modifiers = fghGetXModifiers( 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) )); INVOKE_WCB( *window, Mouse, ( (event->detail)-1, (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP), event->event_x, event->event_y )); break; case XI_Motion: fgState.Modifiers = fghGetXModifiers( 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 ) ); INVOKE_WCB( *window, Motion, ( event->event_x, event->event_y ) ); } else { INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); INVOKE_WCB( *window, Passive, ( event->event_x, event->event_y ) ); } #if _DEBUG fgPrintXIDeviceEvent(event); #endif break; default: #if _DEBUG fgWarning( "Unknown XI2 device event:" ); fgPrintXIDeviceEvent( event ); #endif break; } fgState.Modifiers = INVALID_MODIFIERS; } XFreeEventData( fgDisplay.Display, cookie ); }
/** * \brief This function is called when an Extension Event is received * and calls the corresponding callback functions for these events. */ 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 = 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 = event->mods.base; 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 ); }