+static void on_key_event(xcb_key_press_event_t *event, int up)
+{
+ xcb_window_t xcb = event->event == root ?
+ event->child : event->event;
+ win_t *win = win_get(xcb);
+ event_t ev = keycode_to_event(event->detail);
+ mod_t mod = mask_to_mod(event->state, up);
+ ptr_t ptr = list_to_ptr(&event->root_x);
+ printf("on_key_event: xcb=%u -> win=%p\n", xcb, win);
+ wm_handle_event(win, ev, mod, ptr);
+}
+
+static void on_button_event(xcb_button_press_event_t *event, int up)
+{
+ xcb_window_t xcb = event->event == root ?
+ event->child : event->event;
+ win_t *win = win_get(xcb);
+ event_t ev = button_to_event(event->detail);
+ mod_t mod = mask_to_mod(event->state, up);
+ ptr_t ptr = list_to_ptr(&event->root_x);
+ printf("on_button_event: xcb=%u -> win=%p\n", xcb, win);
+
+ if (!wm_handle_event(win, ev, mod, ptr))
+ xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
+ else if (!up)
+ xcb_grab_pointer(conn, 1, xcb,
+ XCB_EVENT_MASK_POINTER_MOTION |
+ XCB_EVENT_MASK_BUTTON_RELEASE,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC,
+ 0, 0, XCB_CURRENT_TIME);
+ else
+ xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
+
+}
+
+static void on_motion_notify(xcb_motion_notify_event_t *event)
+{
+ xcb_window_t xcb = event->event == root ?
+ event->child : event->event;
+ win_t *win = win_get(xcb);
+ ptr_t ptr = list_to_ptr(&event->root_x);
+ printf("on_motion_notify: xcb=%u -> win=%p - %d,%d / %d.%d\n", xcb, win,
+ ptr.x, ptr.y, ptr.rx, ptr.ry);
+ wm_handle_ptr(win, ptr);
+}
+