event.c (3002B)
1 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail> 2 * See LICENSE file for license details. 3 */ 4 #include "event.h" 5 6 typedef bool (*Handler)(Window*, void*, XEvent*); 7 void (*event_debug)(XEvent*); 8 long event_lastconfigure; 9 long event_xtime; 10 bool event_looprunning; 11 12 EventHandler event_handler[LASTEvent] = { 13 [ButtonPress] = (EventHandler)event_buttonpress, 14 [ButtonRelease] = (EventHandler)event_buttonrelease, 15 [ClientMessage] = (EventHandler)event_clientmessage, 16 [ConfigureNotify] = (EventHandler)event_configurenotify, 17 [ConfigureRequest] = (EventHandler)event_configurerequest, 18 [DestroyNotify] = (EventHandler)event_destroynotify, 19 [EnterNotify] = (EventHandler)event_enternotify, 20 [Expose] = (EventHandler)event_expose, 21 [FocusIn] = (EventHandler)event_focusin, 22 [FocusOut] = (EventHandler)event_focusout, 23 [KeyPress] = (EventHandler)event_keypress, 24 [KeyRelease] = (EventHandler)event_keyrelease, 25 [LeaveNotify] = (EventHandler)event_leavenotify, 26 [MapNotify] = (EventHandler)event_mapnotify, 27 [MapRequest] = (EventHandler)event_maprequest, 28 [MappingNotify] = (EventHandler)event_mappingnotify, 29 [MotionNotify] = (EventHandler)event_motionnotify, 30 [PropertyNotify] = (EventHandler)event_propertynotify, 31 [ReparentNotify] = (EventHandler)event_reparentnotify, 32 [SelectionClear] = (EventHandler)event_selectionclear, 33 [SelectionNotify] = (EventHandler)event_selection, 34 [UnmapNotify] = (EventHandler)event_unmapnotify, 35 }; 36 37 void 38 _event_handle(Window *w, ulong offset, XEvent *event) { 39 Handler f; 40 HandlersLink *l; 41 42 if(w->handler && (f = structmember(w->handler, Handler, offset))) 43 if(!f(w, w->aux, event)) 44 return; 45 46 for(l=w->handler_link; l; l=l->next) 47 if((f = structmember(l->handler, Handler, offset))) 48 if(!f(w, l->aux, event)) 49 return; 50 } 51 52 void 53 event_dispatch(XEvent *e) { 54 if(event_debug) 55 event_debug(e); 56 57 if(e->type < nelem(event_handler)) { 58 if(event_handler[e->type]) 59 event_handler[e->type](e); 60 }else 61 xext_event(e); 62 } 63 64 void 65 event_check(void) { 66 XEvent ev; 67 68 while(XPending(display)) { 69 XNextEvent(display, &ev); 70 event_dispatch(&ev); 71 } 72 } 73 74 void 75 event_loop(void) { 76 XEvent ev; 77 78 event_looprunning = true; 79 while(event_looprunning) { 80 XNextEvent(display, &ev); 81 event_dispatch(&ev); 82 } 83 } 84 85 uint 86 event_flush(long event_mask, bool dispatch) { 87 XEvent ev; 88 uint n = 0; 89 90 while(XCheckMaskEvent(display, event_mask, &ev)) { 91 if(dispatch) 92 event_dispatch(&ev); 93 n++; 94 } 95 return n; 96 } 97 98 static int 99 findenter(Display *d, XEvent *e, XPointer v) { 100 long *l; 101 102 USED(d); 103 l = (long*)v; 104 if(*l) 105 return false; 106 if(e->type == EnterNotify) 107 return true; 108 if(e->type == MotionNotify) 109 (*l)++; 110 return false; 111 } 112 113 /* This isn't perfect. If there were motion events in the queue 114 * before this was called, then it flushes nothing. If we don't 115 * check for them, we might lose a legitamate enter event. 116 */ 117 uint 118 event_flushenter(void) { 119 XEvent e; 120 long l; 121 int n; 122 123 l = 0; 124 n = 0; 125 while(XCheckIfEvent(display, &e, findenter, (void*)&l)) 126 n++; 127 return n; 128 } 129