diff options
Diffstat (limited to 'pugl')
-rw-r--r-- | pugl/pugl.h | 46 | ||||
-rw-r--r-- | pugl/pugl_internal.h | 16 | ||||
-rw-r--r-- | pugl/pugl_win.cpp | 4 | ||||
-rw-r--r-- | pugl/pugl_x11.c | 58 |
4 files changed, 119 insertions, 5 deletions
diff --git a/pugl/pugl.h b/pugl/pugl.h index 8bc3f72..a77a831 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -77,6 +77,37 @@ typedef enum { PUGL_SUCCESS = 0 } PuglStatus; +typedef enum { + PUGL_KEY_F1 = 1, + PUGL_KEY_F2, + PUGL_KEY_F3, + PUGL_KEY_F4, + PUGL_KEY_F5, + PUGL_KEY_F6, + PUGL_KEY_F7, + PUGL_KEY_F8, + PUGL_KEY_F9, + PUGL_KEY_F10, + PUGL_KEY_F11, + PUGL_KEY_F12, + PUGL_KEY_LEFT, + PUGL_KEY_UP, + PUGL_KEY_RIGHT, + PUGL_KEY_DOWN, + PUGL_KEY_PAGE_UP, + PUGL_KEY_PAGE_DOWN, + PUGL_KEY_HOME, + PUGL_KEY_END, + PUGL_KEY_INSERT +} PuglKey; + +typedef enum { + PUGL_MOD_SHIFT = 1, /**< Shift key */ + PUGL_MOD_CTRL = 1 << 1, /**< Control key */ + PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */ + PUGL_MOD_SUPER = 1 << 3, /**< Mod4/Command/Windows key */ +} PuglModifier; + /** Handle for opaque user data. */ @@ -90,6 +121,7 @@ typedef void (*PuglMouseFunc)(PuglView* view, int button, bool down, int x, int y); typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height); typedef void (*PuglScrollFunc)(PuglView* view, float dx, float dy); +typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key); /** Create a new GL window. @@ -125,6 +157,14 @@ PUGL_API PuglHandle puglGetHandle(PuglView* view); /** + Get the currently active modifiers (PuglModifier flags). + + This should only be called from an event handler. +*/ +int +puglGetModifiers(PuglView* view); + +/** Set the function to call when the window is closed. */ PUGL_API void @@ -161,6 +201,12 @@ PUGL_API void puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc); /** + Set the function to call on special events. +*/ +PUGL_API void +puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc); + +/** Set the function to call when the window size changes. */ PUGL_API void diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h index 0b04e5d..21e9eb4 100644 --- a/pugl/pugl_internal.h +++ b/pugl/pugl_internal.h @@ -36,11 +36,13 @@ struct PuglViewImpl { PuglMouseFunc mouseFunc; PuglReshapeFunc reshapeFunc; PuglScrollFunc scrollFunc; + PuglSpecialFunc specialFunc; PuglPlatformData* impl; int width; int height; + int mods; bool redisplay; }; @@ -56,6 +58,12 @@ puglGetHandle(PuglView* view) return view->handle; } +int +puglGetModifiers(PuglView* view) +{ + return view->mods; +} + void puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc) { @@ -85,7 +93,7 @@ puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc) { view->mouseFunc = mouseFunc; } - + void puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc) { @@ -97,3 +105,9 @@ puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc) { view->scrollFunc = scrollFunc; } + +void +puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc) +{ + view->specialFunc = specialFunc; +} diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp index f487352..a5c9dde 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.cpp @@ -157,8 +157,8 @@ processMouseEvent(PuglView* view, int button, bool press, LPARAM lParam) { if (view->mouseFunc) { view->mouseFunc(view, button, press, - GET_X_LPARAM(lParam), - GET_Y_LPARAM(lParam)); + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam)); } } diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 606f348..f7d6e32 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -207,6 +207,45 @@ puglDisplay(PuglView* view) view->redisplay = false; } +static PuglKey +keySymToSpecial(KeySym sym) +{ + switch (sym) { + case XK_F1: return PUGL_KEY_F1; + case XK_F2: return PUGL_KEY_F2; + case XK_F3: return PUGL_KEY_F3; + case XK_F4: return PUGL_KEY_F4; + case XK_F5: return PUGL_KEY_F5; + case XK_F6: return PUGL_KEY_F6; + case XK_F7: return PUGL_KEY_F7; + case XK_F8: return PUGL_KEY_F8; + case XK_F9: return PUGL_KEY_F9; + case XK_F10: return PUGL_KEY_F10; + case XK_F11: return PUGL_KEY_F11; + case XK_F12: return PUGL_KEY_F12; + case XK_Left: return PUGL_KEY_LEFT; + case XK_Up: return PUGL_KEY_UP; + case XK_Right: return PUGL_KEY_RIGHT; + case XK_Down: return PUGL_KEY_DOWN; + case XK_Page_Up: return PUGL_KEY_PAGE_UP; + case XK_Page_Down: return PUGL_KEY_PAGE_DOWN; + case XK_Home: return PUGL_KEY_HOME; + case XK_End: return PUGL_KEY_END; + case XK_Insert: return PUGL_KEY_INSERT; + } + return (PuglKey)0; +} + +static void +setModifiers(PuglView* view, int xstate) +{ + view->mods = 0; + view->mods |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0; + view->mods |= (xstate & ControlMask) ? PUGL_MOD_CTRL : 0; + view->mods |= (xstate & Mod1Mask) ? PUGL_MOD_ALT : 0; + view->mods |= (xstate & Mod4Mask) ? PUGL_MOD_SUPER : 0; +} + PuglStatus puglProcessEvents(PuglView* view) { @@ -235,11 +274,13 @@ puglProcessEvents(PuglView* view) view->redisplay = false; break; case MotionNotify: + setModifiers(view, event.xmotion.state); if (view->motionFunc) { view->motionFunc(view, event.xmotion.x, event.xmotion.y); } break; case ButtonPress: + setModifiers(view, event.xbutton.state); if (event.xbutton.button >= 4 && event.xbutton.button <= 7) { if (view->scrollFunc) { float dx = 0, dy = 0; @@ -255,6 +296,7 @@ puglProcessEvents(PuglView* view) } // nobreak case ButtonRelease: + setModifiers(view, event.xbutton.state); if (view->mouseFunc && (event.xbutton.button < 4 || event.xbutton.button > 7)) { view->mouseFunc(view, @@ -263,13 +305,20 @@ puglProcessEvents(PuglView* view) } break; case KeyPress: + setModifiers(view, event.xkey.state); if (view->keyboardFunc) { KeySym sym = XKeycodeToKeysym( view->impl->display, event.xkey.keycode, 0); - view->keyboardFunc(view, event.type == KeyPress, sym); + PuglKey special = keySymToSpecial(sym); + if (!special) { + view->keyboardFunc(view, true, sym); + } else if (view->specialFunc) { + view->specialFunc(view, true, special); + } } break; case KeyRelease: { + setModifiers(view, event.xkey.state); bool retriggered = false; if (XEventsQueued(view->impl->display, QueuedAfterReading)) { XEvent next; @@ -286,7 +335,12 @@ puglProcessEvents(PuglView* view) if (!retriggered && view->keyboardFunc) { KeySym sym = XKeycodeToKeysym( view->impl->display, event.xkey.keycode, 0); - view->keyboardFunc(view, false, sym); + PuglKey special = keySymToSpecial(sym); + if (!special) { + view->keyboardFunc(view, false, sym); + } else if (view->specialFunc) { + view->specialFunc(view, false, special); + } } } case ClientMessage: |