static void glwtHandleKeyEvent(GLWTWindow *win, struct input_event event) { int key = keymap_lookup(event.code); glwtUpdateMod(key, event.value); if(event.code < BTN_MISC || event.code >= KEY_OK) { if(win && win->win_callback) { GLWTWindowEvent wevent; wevent.type = event.value==0 ? GLWT_WINDOW_KEY_UP : GLWT_WINDOW_KEY_DOWN; wevent.key.keysym = key; wevent.key.scancode = event.code; wevent.key.mod = glwt.linux_input.keyboard.mod; win->win_callback( win, &wevent, win->userdata ); } } else if(BTN_MOUSE <= event.code && event.code < BTN_JOYSTICK) { if(win && win->win_callback) { GLWTWindowEvent wevent; wevent.type = event.value==0 ? GLWT_WINDOW_BUTTON_UP : GLWT_WINDOW_BUTTON_DOWN; wevent.button.button = event.code-BTN_MOUSE; wevent.button.mod = glwt.linux_input.keyboard.mod; wevent.button.x = glwt.linux_input.mouse.x; wevent.button.y = glwt.linux_input.mouse.y; win->win_callback( win, &wevent, win->userdata ); } if(event.value) glwt.linux_input.mouse.buttons |= 1<<(event.code-BTN_MOUSE); else glwt.linux_input.mouse.buttons &= ~(1<<(event.code-BTN_MOUSE)); } else if(BTN_JOYSTICK <= event.code && event.code < BTN_GAMEPAD) { // joystick button } else if(BTN_GAMEPAD <= event.code && event.code < BTN_DIGI) { // gamepad button } }
static int xlib_handle_event() { XEvent event; int num_handled_events = 0; while(XCheckMaskEvent(glwt.x11.display, ~0, &event) || XCheckTypedEvent(glwt.x11.display, ClientMessage, &event)) { ++num_handled_events; GLWTWindow *win = 0; if(XFindContext( glwt.x11.display, event.xany.window, glwt.x11.xcontext, (XPointer*)&win) != 0) continue; switch(event.type) { case ConfigureNotify: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = GLWT_WINDOW_RESIZE; e.resize.width = event.xconfigure.width; e.resize.height = event.xconfigure.height; win->win_callback(win, &e, win->userdata); } break; case MapNotify: case UnmapNotify: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = event.type == MapNotify ? GLWT_WINDOW_SHOW : GLWT_WINDOW_HIDE; e.dummy.dummy = 0; win->win_callback(win, &e, win->userdata); } break; case Expose: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = GLWT_WINDOW_EXPOSE; e.dummy.dummy = 0; win->win_callback(win, &e, win->userdata); } break; case KeyPress: case KeyRelease: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = event.type == KeyPress ? GLWT_WINDOW_KEY_DOWN : GLWT_WINDOW_KEY_UP; e.key.keysym = keymap_lookup(&glwt.x11.keymap, XkbKeycodeToKeysym(glwt.x11.display, event.xkey.keycode, 0, 0)); e.key.scancode = event.xkey.keycode; e.key.mod = mapKeyMod(event.xkey.state); win->win_callback(win, &e, win->userdata); } break; case FocusIn: case FocusOut: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = event.type == FocusIn ? GLWT_WINDOW_FOCUS_IN : GLWT_WINDOW_FOCUS_OUT; e.dummy.dummy = 0; win->win_callback(win, &e, win->userdata); } break; case ButtonPress: case ButtonRelease: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = event.type == ButtonPress ? GLWT_WINDOW_BUTTON_DOWN : GLWT_WINDOW_BUTTON_UP; e.button.x = event.xbutton.x; e.button.y = event.xbutton.y; e.button.button = event.xbutton.button; // todo: make these consistent on different platforms e.button.mod = mapKeyMod(event.xbutton.state); win->win_callback(win, &e, win->userdata); } break; case MotionNotify: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = GLWT_WINDOW_MOUSE_MOTION; e.motion.x = event.xmotion.x; e.motion.y = event.xmotion.y; e.motion.buttons = mapButtons(event.xmotion.state); win->win_callback(win, &e, win->userdata); } break; case EnterNotify: case LeaveNotify: if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = event.type == EnterNotify ? GLWT_WINDOW_MOUSE_ENTER : GLWT_WINDOW_MOUSE_LEAVE; e.dummy.dummy = 0; win->win_callback(win, &e, win->userdata); } break; case ClientMessage: if((Atom)event.xclient.data.l[0] == glwt.x11.atoms.WM_DELETE_WINDOW) { win->closed = 1; if(win->win_callback) { GLWTWindowEvent e; e.window = win; e.type = GLWT_WINDOW_CLOSE; e.dummy.dummy = 0; win->win_callback(win, &e, win->userdata); } } else if((Atom)event.xclient.data.l[0] == glwt.x11.atoms._NET_WM_PING) { event.xclient.window = RootWindow(glwt.x11.display, glwt.x11.screen_num); XSendEvent( glwt.x11.display, event.xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, &event); } break; default: break; } } return num_handled_events; }