static value caml_gr_wait_event_blocking(int mask) { struct event_data ev; /* Increase the selected events if needed */ caml_gr_event_mask |= mask; /* Pop events from queue until one matches */ do { /* Wait for event queue to be non-empty */ WaitForSingleObject(caml_gr_queue_semaphore, INFINITE); /* Pop oldest event in queue */ EnterCriticalSection(&caml_gr_queue_mutex); ev = caml_gr_queue[caml_gr_head]; /* Queue should never be empty at this point, but just in case... */ if (QueueIsEmpty) { ev.kind = 0; } else { caml_gr_head = (caml_gr_head + 1) % SIZE_QUEUE; } LeaveCriticalSection(&caml_gr_queue_mutex); /* Check if it matches */ } while ((ev.kind & mask) == 0); return caml_gr_wait_allocate_result(ev.mouse_x, ev.mouse_y, ev.button, ev.kind == EVENT_KEY_PRESSED, ev.key); }
static value caml_gr_wait_event_poll(void) { int mouse_x, mouse_y, button, key, keypressed; Window rootwin, childwin; int root_x, root_y, win_x, win_y; unsigned int modifiers; unsigned int i; if (XQueryPointer(caml_gr_display, caml_gr_window.win, &rootwin, &childwin, &root_x, &root_y, &win_x, &win_y, &modifiers)) { mouse_x = win_x; mouse_y = win_y; } else { mouse_x = -1; mouse_y = -1; } button = modifiers & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask); /* Look inside event queue for pending KeyPress events */ key = 0; keypressed = False; for (i = caml_gr_head; i != caml_gr_tail; i = (i + 1) % SIZE_QUEUE) { if (caml_gr_queue[i].kind == KeyPress) { keypressed = True; key = caml_gr_queue[i].key; break; } } return caml_gr_wait_allocate_result(mouse_x, mouse_y, button, keypressed, key); }
static value caml_gr_wait_event_in_queue(long mask) { struct event_data * ev; /* Pop events in queue until one matches mask. */ while (caml_gr_head != caml_gr_tail) { ev = &(caml_gr_queue[caml_gr_head]); caml_gr_head = (caml_gr_head + 1) % SIZE_QUEUE; if ((ev->kind == KeyPress && (mask & KeyPressMask)) || (ev->kind == ButtonPress && (mask & ButtonPressMask)) || (ev->kind == ButtonRelease && (mask & ButtonReleaseMask)) || (ev->kind == MotionNotify && (mask & PointerMotionMask))) return caml_gr_wait_allocate_result(ev->mouse_x, ev->mouse_y, ev->button, ev->kind == KeyPress, ev->key); } return Val_false; }
static value caml_gr_wait_event_poll(void) { int key, keypressed, i; /* Look inside event queue for pending KeyPress events */ EnterCriticalSection(&caml_gr_queue_mutex); key = 0; keypressed = 0; for (i = caml_gr_head; i != caml_gr_tail; i = (i + 1) % SIZE_QUEUE) { if (caml_gr_queue[i].kind == EVENT_KEY_PRESSED) { keypressed = 1; key = caml_gr_queue[i].key; break; } } LeaveCriticalSection(&caml_gr_queue_mutex); /* Use global vars for mouse position and buttons */ return caml_gr_wait_allocate_result(GET_X_LPARAM(last_pos), GET_Y_LPARAM(last_pos), last_button, keypressed, key); }