Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/freeglut/src/x11/fg_xinput_x11.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* Written for XI1 by Nikolas Doerfler <doerflen@in.tum.de> (c) 2008 * | |
| 2 * Rewritten for XI2 by Florian Echtler <echtler@in.tum.de> (c) 2009 */ | |
| 3 | |
| 4 #include <GL/freeglut.h> | |
| 5 | |
| 6 #include "../fg_internal.h" | |
| 7 | |
| 8 #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H | |
| 9 | |
| 10 #include <errno.h> | |
| 11 #include <stdarg.h> | |
| 12 | |
| 13 #include <X11/Xlib.h> | |
| 14 #include <X11/extensions/XInput2.h> | |
| 15 | |
| 16 /* convert the XInput button state mask to the regular X mouse event button mask */ | |
| 17 #define BUTTON_MASK(xistate) ((xistate) << 8) | |
| 18 | |
| 19 /* import function from fg_main.c */ | |
| 20 extern int fgPlatformGetModifiers( int state ); | |
| 21 | |
| 22 /* extension opcode for XInput */ | |
| 23 int xi_opcode = -1; | |
| 24 | |
| 25 /** | |
| 26 * \brief Sets window up for XI2 events. | |
| 27 */ | |
| 28 void fgRegisterDevices( Display* dpy, Window* win ) { | |
| 29 | |
| 30 XIEventMask mask; | |
| 31 unsigned char flags[2] = { 0, 0 }; | |
| 32 int event, error; | |
| 33 | |
| 34 /*Display* dpy = fgDisplay.pDisplay.Display; | |
| 35 Window* win = glutGetXWindow();*/ | |
| 36 | |
| 37 /* get XInput extension opcode */ | |
| 38 if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; } | |
| 39 | |
| 40 /* Select for motion events */ | |
| 41 mask.deviceid = XIAllMasterDevices; | |
| 42 mask.mask_len = 2; | |
| 43 mask.mask = flags; | |
| 44 | |
| 45 XISetMask(mask.mask, XI_Enter); | |
| 46 XISetMask(mask.mask, XI_Motion); | |
| 47 XISetMask(mask.mask, XI_ButtonPress); | |
| 48 XISetMask(mask.mask, XI_ButtonRelease); | |
| 49 XISetMask(mask.mask, XI_Leave); | |
| 50 /*XISetMask(mask.mask, XI_KeyPress); | |
| 51 XISetMask(mask.mask, XI_KeyRelease); | |
| 52 XISetMask(mask.mask, XI_DeviceChanged); | |
| 53 XISetMask(mask.mask, XI_RawEvent); | |
| 54 XISetMask(mask.mask, XI_FocusIn); | |
| 55 XISetMask(mask.mask, XI_FocusOut); | |
| 56 XISetMask(mask.mask, XI_HierarchyChanged);*/ | |
| 57 | |
| 58 XISelectEvents( dpy, *win, &mask, 1 ); | |
| 59 } | |
| 60 | |
| 61 | |
| 62 void fgPrintXILeaveEvent(XILeaveEvent* event) | |
| 63 { | |
| 64 char* mode = ""; | |
| 65 char* detail = ""; | |
| 66 int i; | |
| 67 | |
| 68 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n", | |
| 69 event->root, event->event, event->child); | |
| 70 switch(event->mode) | |
| 71 { | |
| 72 case NotifyNormal: mode = "NotifyNormal"; break; | |
| 73 case NotifyGrab: mode = "NotifyGrab"; break; | |
| 74 case NotifyUngrab: mode = "NotifyUngrab"; break; | |
| 75 case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; | |
| 76 } | |
| 77 switch (event->detail) | |
| 78 { | |
| 79 case NotifyAncestor: detail = "NotifyAncestor"; break; | |
| 80 case NotifyVirtual: detail = "NotifyVirtual"; break; | |
| 81 case NotifyInferior: detail = "NotifyInferior"; break; | |
| 82 case NotifyNonlinear: detail = "NotifyNonlinear"; break; | |
| 83 case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; | |
| 84 case NotifyPointer: detail = "NotifyPointer"; break; | |
| 85 case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; | |
| 86 case NotifyDetailNone: detail = "NotifyDetailNone"; break; | |
| 87 } | |
| 88 printf(" mode: %s (detail %s)\n", mode, detail); | |
| 89 printf(" flags: %s %s\n", event->focus ? "[focus]" : "", | |
| 90 event->same_screen ? "[same screen]" : ""); | |
| 91 printf(" buttons:"); | |
| 92 for (i = 0; i < event->buttons.mask_len * 8; i++) | |
| 93 if (XIMaskIsSet(event->buttons.mask, i)) | |
| 94 printf(" %d", i); | |
| 95 printf("\n"); | |
| 96 | |
| 97 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n", | |
| 98 event->mods.locked, event->mods.latched, | |
| 99 event->mods.base); | |
| 100 printf(" group: locked 0x%x latched 0x%x base 0x%x\n", | |
| 101 event->group.locked, event->group.latched, | |
| 102 event->group.base); | |
| 103 | |
| 104 printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y); | |
| 105 printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y); | |
| 106 | |
| 107 } | |
| 108 | |
| 109 | |
| 110 void fgPrintXIDeviceEvent(XIDeviceEvent* event) | |
| 111 { | |
| 112 double *val; | |
| 113 int i; | |
| 114 | |
| 115 printf(" device: %d (%d)\n", event->deviceid, event->sourceid); | |
| 116 printf(" detail: %d\n", event->detail); | |
| 117 printf(" buttons:"); | |
| 118 for (i = 0; i < event->buttons.mask_len * 8; i++) | |
| 119 if (XIMaskIsSet(event->buttons.mask, i)) | |
| 120 printf(" %d", i); | |
| 121 printf("\n"); | |
| 122 | |
| 123 printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n", | |
| 124 event->mods.locked, event->mods.latched, | |
| 125 event->mods.base); | |
| 126 printf(" group: locked 0x%x latched 0x%x base 0x%x\n", | |
| 127 event->group.locked, event->group.latched, | |
| 128 event->group.base); | |
| 129 printf(" valuators:"); | |
| 130 | |
| 131 val = event->valuators.values; | |
| 132 for (i = 0; i < event->valuators.mask_len * 8; i++) | |
| 133 if (XIMaskIsSet(event->valuators.mask, i)) | |
| 134 printf(" %d: %.2f", i, *val++); | |
| 135 printf("\n"); | |
| 136 | |
| 137 printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n", | |
| 138 event->root, event->event, event->child); | |
| 139 printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y); | |
| 140 printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y); | |
| 141 | |
| 142 } | |
| 143 | |
| 144 /** | |
| 145 * \brief This function is called when an Extension Event is received | |
| 146 * and calls the corresponding callback functions for these events. | |
| 147 */ | |
| 148 void fgHandleExtensionEvents( XEvent* base_ev ) | |
| 149 { | |
| 150 XEvent std_ev; /* standard single-pointer event to be added to the event queue */ | |
| 151 int i, button = 0; | |
| 152 XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); | |
| 153 | |
| 154 /* initialize the generic fields from base_ev */ | |
| 155 std_ev.xany = base_ev->xany; | |
| 156 | |
| 157 if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { | |
| 158 | |
| 159 XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); | |
| 160 XIEnterEvent *evcross; | |
| 161 /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/ | |
| 162 | |
| 163 SFG_Window* window = fgWindowByHandle( event->event ); | |
| 164 if (!window) return; | |
| 165 | |
| 166 switch (cookie->evtype) { | |
| 167 case XI_Enter: | |
| 168 case XI_Leave: | |
| 169 evcross = (XIEnterEvent*)event; | |
| 170 | |
| 171 fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base ); | |
| 172 INVOKE_WCB( *window, MultiEntry, ( | |
| 173 event->deviceid, | |
| 174 (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) | |
| 175 )); | |
| 176 #if _DEBUG | |
| 177 fgPrintXILeaveEvent((XILeaveEvent*)event); | |
| 178 #endif | |
| 179 | |
| 180 /* Also process the standard crossing event */ | |
| 181 std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify; | |
| 182 std_ev.xcrossing.window = evcross->event; | |
| 183 std_ev.xcrossing.root = evcross->root; | |
| 184 std_ev.xcrossing.subwindow = evcross->child; | |
| 185 std_ev.xcrossing.x = evcross->event_x; | |
| 186 std_ev.xcrossing.y = evcross->event_y; | |
| 187 std_ev.xcrossing.x_root = evcross->root_x; | |
| 188 std_ev.xcrossing.y_root = evcross->root_y; | |
| 189 std_ev.xcrossing.mode = evcross->mode; | |
| 190 std_ev.xcrossing.detail = evcross->detail; | |
| 191 std_ev.xcrossing.same_screen = evcross->same_screen; | |
| 192 std_ev.xcrossing.focus = evcross->focus; | |
| 193 std_ev.xcrossing.state = BUTTON_MASK(*(unsigned int*)evcross->buttons.mask); | |
| 194 | |
| 195 XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); | |
| 196 break; | |
| 197 | |
| 198 case XI_ButtonPress: | |
| 199 case XI_ButtonRelease: | |
| 200 fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); | |
| 201 INVOKE_WCB( *window, MultiButton, ( | |
| 202 event->deviceid, | |
| 203 event->event_x, | |
| 204 event->event_y, | |
| 205 event->detail-1, | |
| 206 (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP) | |
| 207 )); | |
| 208 | |
| 209 /* Also process the standard button event */ | |
| 210 std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; | |
| 211 std_ev.xbutton.window = event->event; | |
| 212 std_ev.xbutton.root = event->root; | |
| 213 std_ev.xbutton.subwindow = event->child; | |
| 214 std_ev.xbutton.x = event->event_x; | |
| 215 std_ev.xbutton.y = event->event_y; | |
| 216 std_ev.xbutton.x_root = event->root_x; | |
| 217 std_ev.xbutton.y_root = event->root_y; | |
| 218 std_ev.xbutton.state = event->mods.base; | |
| 219 std_ev.xbutton.button = event->detail; | |
| 220 | |
| 221 XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); | |
| 222 break; | |
| 223 | |
| 224 case XI_Motion: | |
| 225 fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); | |
| 226 for (i = 0; i < event->buttons.mask_len; i++) { | |
| 227 if (event->buttons.mask[i]) { | |
| 228 button = 1; | |
| 229 } | |
| 230 } | |
| 231 if (button) { | |
| 232 INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) ); | |
| 233 } else { | |
| 234 INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); | |
| 235 } | |
| 236 #if _DEBUG | |
| 237 fgPrintXIDeviceEvent(event); | |
| 238 #endif | |
| 239 | |
| 240 /* Also process the standard motion event */ | |
| 241 std_ev.type = MotionNotify; | |
| 242 std_ev.xmotion.window = event->event; | |
| 243 std_ev.xmotion.root = event->root; | |
| 244 std_ev.xmotion.subwindow = event->child; | |
| 245 std_ev.xmotion.time = event->time; | |
| 246 std_ev.xmotion.x = event->event_x; | |
| 247 std_ev.xmotion.y = event->event_y; | |
| 248 std_ev.xmotion.x_root = event->root_x; | |
| 249 std_ev.xmotion.y_root = event->root_y; | |
| 250 std_ev.xmotion.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask); | |
| 251 std_ev.xmotion.is_hint = NotifyNormal; | |
| 252 | |
| 253 XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); | |
| 254 break; | |
| 255 | |
| 256 default: | |
| 257 #if _DEBUG | |
| 258 fgWarning( "Unknown XI2 device event:" ); | |
| 259 fgPrintXIDeviceEvent( event ); | |
| 260 #endif | |
| 261 break; | |
| 262 } | |
| 263 fgState.Modifiers = INVALID_MODIFIERS; | |
| 264 } | |
| 265 XFreeEventData( fgDisplay.pDisplay.Display, cookie ); | |
| 266 } | |
| 267 | |
| 268 #endif |
