From 4e6368d019e2543e6bf792f182486732d6f5a3f5 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 29 Apr 2012 02:53:47 +0000 Subject: Proper key press and release support on X11. Clearer mouse callback API. --- pugl/pugl.h | 2 +- pugl/pugl_win.cpp | 4 ++-- pugl/pugl_x11.c | 27 ++++++++++++++++++++++++--- pugl_test.c | 6 ++++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/pugl/pugl.h b/pugl/pugl.h index 853a754..6a6fbe7 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -52,7 +52,7 @@ typedef void (*PuglDisplayFunc)(PuglWindow* handle); typedef void (*PuglKeyboardFunc)(PuglWindow* handle, bool press, uint32_t key); typedef void (*PuglMotionFunc)(PuglWindow* handle, int x, int y); typedef void (*PuglMouseFunc)(PuglWindow* handle, - int button, int state, + int button, bool down, int x, int y); typedef void (*PuglReshapeFunc)(PuglWindow* handle, int width, int height); diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp index a27a2c5..50f42f0 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.cpp @@ -104,10 +104,10 @@ puglDisplay(PuglWindow* win) } static void -processMouseEvent(PuglWindow* win, int button, bool down, LPARAM lParam) +processMouseEvent(PuglWindow* win, int button, bool press, LPARAM lParam) { if (win->mouseFunc) { - win->mouseFunc(win, button, down, + win->mouseFunc(win, button, press, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); } diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 33f0b42..5844f2d 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -104,7 +104,8 @@ puglCreate(PuglNativeWindow parent, const char* title, int width, int height) attr.border_pixel = 0; attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask - | ButtonPressMask | PointerMotionMask | StructureNotifyMask; + | ButtonPressMask | ButtonReleaseMask + | PointerMotionMask | StructureNotifyMask; impl->win = XCreateWindow( impl->display, xParent, @@ -194,20 +195,40 @@ puglProcessEvents(PuglWindow* win) } break; case ButtonPress: + case ButtonRelease: if (win->mouseFunc) { win->mouseFunc(win, - event.xbutton.button, event.xbutton.state, + event.xbutton.button, event.type == ButtonPress, event.xbutton.x, event.xbutton.y); } break; case KeyPress: - case KeyRelease: if (win->keyboardFunc) { KeySym sym = XKeycodeToKeysym( win->impl->display, event.xkey.keycode, 0); win->keyboardFunc(win, event.type == KeyPress, sym); } break; + case KeyRelease: { + bool retriggered = false; + if (XEventsQueued(win->impl->display, QueuedAfterReading)) { + XEvent next; + XPeekEvent(win->impl->display, &next); + if (next.type == KeyPress && + next.xkey.time == event.xkey.time && + next.xkey.keycode == event.xkey.keycode) { + // Key repeat, ignore fake KeyPress event + XNextEvent(win->impl->display, &event); + retriggered = true; + } + } + + if (!retriggered && win->keyboardFunc) { + KeySym sym = XKeycodeToKeysym( + win->impl->display, event.xkey.keycode, 0); + win->keyboardFunc(win, false, sym); + } + } case ClientMessage: if (!strcmp(XGetAtomName(win->impl->display, event.xclient.message_type), diff --git a/pugl_test.c b/pugl_test.c index f6d9ac2..63bc7d6 100644 --- a/pugl_test.c +++ b/pugl_test.c @@ -59,6 +59,7 @@ onDisplay(PuglWindow* win) static void onKeyboard(PuglWindow* win, bool press, uint32_t key) { + fprintf(stderr, "Key %c %s\n", (char)key, press ? "down" : "up"); if (key == 'q' || key == 'Q' || key == KEY_ESCAPE) { quit = 1; } @@ -73,9 +74,10 @@ onMotion(PuglWindow* win, int x, int y) } static void -onMouse(PuglWindow* handle, int button, int state, int x, int y) +onMouse(PuglWindow* handle, int button, bool press, int x, int y) { - fprintf(stderr, "Mouse %d at %d,%d\n", button, x, y); + fprintf(stderr, "Mouse %d %s at %d,%d\n", + button, press ? "down" : "up", x, y); } static void -- cgit v1.2.1