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 = translate_key(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; }
LRESULT CALLBACK glwtWin32WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { GLWTWindow *win = (GLWTWindow*)GetWindowLongPtr(hwnd, 0); if(win) { switch(uMsg) { case WM_PAINT: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = GLWT_WINDOW_EXPOSE; event.dummy.dummy = 0; win->win_callback(win, &event, win->userdata); } ValidateRect(hwnd, NULL); return 0; case WM_KEYUP: case WM_KEYDOWN: case WM_SYSKEYUP: case WM_SYSKEYDOWN: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN) ? GLWT_WINDOW_KEY_DOWN : GLWT_WINDOW_KEY_UP; event.key.keysym = translate_key(wParam, lParam); event.key.scancode = (lParam >> 16) & 0xff; event.key.mod = GetModifiers(); win->win_callback(win, &event, win->userdata); } if(uMsg == WM_SYSKEYUP || uMsg == WM_SYSKEYDOWN) break; return 0; case WM_LBUTTONUP: case WM_LBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_XBUTTONUP: case WM_XBUTTONDOWN: case WM_MOUSEWHEEL: case WM_MOUSEHWHEEL: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = ( uMsg == WM_LBUTTONUP || uMsg == WM_MBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_XBUTTONUP || uMsg == WM_MOUSEWHEEL || uMsg == WM_MOUSEHWHEEL ) ? GLWT_WINDOW_BUTTON_DOWN : GLWT_WINDOW_BUTTON_UP; event.button.x = LOWORD(lParam); event.button.y = HIWORD(lParam); event.button.button = (uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDOWN) ? 0 : (uMsg == WM_MBUTTONUP || uMsg == WM_MBUTTONDOWN) ? 1 : (uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDOWN) ? 2 : (uMsg == WM_XBUTTONUP || uMsg == WM_XBUTTONDOWN) ? (HIWORD(wParam) == XBUTTON1 ? 5 : 6) : (uMsg == WM_MOUSEWHEEL) ? (GET_WHEEL_DELTA_WPARAM(wParam) < 0 ? 3 : 4) : (uMsg == WM_MOUSEHWHEEL) ? (GET_WHEEL_DELTA_WPARAM(wParam) < 0 ? 7 : 8) : 0; event.button.mod = GetModifiers(); win->win_callback(win, &event, win->userdata); } return 0; case WM_MOUSEMOVE: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = GLWT_WINDOW_MOUSE_MOTION; event.motion.x = GET_X_LPARAM(lParam); event.motion.y = GET_Y_LPARAM(lParam); event.motion.buttons = (wParam & MK_LBUTTON ? (1 << 0) : 0) | (wParam & MK_RBUTTON ? (1 << 1) : 0) | (wParam & MK_MBUTTON ? (1 << 2) : 0) | (wParam & MK_XBUTTON1 ? (1 << 5) : 0) | (wParam & MK_XBUTTON2 ? (1 << 6) : 0); win->win_callback(win, &event, win->userdata); } { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; tme.hwndTrack = hwnd; TrackMouseEvent(&tme); if(tme.dwFlags != TME_LEAVE) { tme.cbSize = sizeof(tme); tme.dwFlags = TME_HOVER|TME_LEAVE; tme.hwndTrack = hwnd; tme.dwHoverTime = 1; TrackMouseEvent(&tme); } } return 0; case WM_SETFOCUS: case WM_KILLFOCUS: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = uMsg == WM_SETFOCUS ? GLWT_WINDOW_FOCUS_IN : GLWT_WINDOW_FOCUS_OUT; event.dummy.dummy = 0; win->win_callback(win, &event, win->userdata); } return 0; case WM_MOUSEHOVER: case WM_MOUSELEAVE: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = (uMsg == WM_MOUSEHOVER ? GLWT_WINDOW_MOUSE_ENTER : GLWT_WINDOW_MOUSE_LEAVE); event.dummy.dummy = 0; win->win_callback(win, &event, win->userdata); } { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = uMsg == WM_MOUSEHOVER ? TME_LEAVE : TME_HOVER; tme.hwndTrack = hwnd; tme.dwHoverTime = 1; TrackMouseEvent(&tme); } return 0; case WM_SHOWWINDOW: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = (wParam == TRUE ? GLWT_WINDOW_SHOW : GLWT_WINDOW_HIDE); event.dummy.dummy = 0; win->win_callback(win, &event, win->userdata); } return 0; case WM_SIZE: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = GLWT_WINDOW_RESIZE; event.resize.width = LOWORD(lParam); event.resize.height = HIWORD(lParam); win->win_callback(win, &event, win->userdata); } return 0; case WM_CLOSE: win->closed = 1; if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = GLWT_WINDOW_CLOSE; event.dummy.dummy = 0; win->win_callback(win, &event, win->userdata); } return 0; case WM_SYSCHAR: case WM_CHAR: if(win->win_callback) { GLWTWindowEvent event; event.window = win; event.type = GLWT_WINDOW_CHARACTER_INPUT; event.character.unicode = utf16_decode((unsigned int)wParam); win->win_callback(win, &event, win->userdata); } return 0; default: break; } }