summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-02-03 01:44:06 +0000
committerDavid Robillard <d@drobilla.net>2013-02-03 01:44:06 +0000
commitaa01d329754134899e6e729d6948a72e0ef881c4 (patch)
tree1f762e4118a065b7c02da6f9b8f58f09a2cb1492
parent5ecc055c068ccd13c4e4129a97a2aec4f505866e (diff)
Apply portability fixes from Ben Loftis.
-rw-r--r--AUTHORS2
-rw-r--r--pugl/pugl.h6
-rw-r--r--pugl/pugl_internal.h20
-rw-r--r--pugl/pugl_osx.m249
-rw-r--r--pugl/pugl_win.cpp95
-rw-r--r--pugl/pugl_x11.c17
-rw-r--r--wscript2
7 files changed, 252 insertions, 139 deletions
diff --git a/AUTHORS b/AUTHORS
index 7c304d5..202ec66 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,5 +1,5 @@
Author:
David Robillard <d@drobilla.net>
-Original GLX inspiration:
+Original GLX inspiration, portability fixes:
Ben Loftis
diff --git a/pugl/pugl.h b/pugl/pugl.h
index 2ee3016..9be936b 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -246,6 +246,12 @@ PUGL_API PuglHandle
puglGetHandle(PuglView* view);
/**
+ Return the timestamp (if any) of the currently-processing event.
+*/
+PUGL_API uint32_t
+puglGetEventTimestamp(PuglView* view);
+
+/**
Get the currently active modifiers (PuglMod flags).
This should only be called from an event handler.
diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h
index 61d287a..37db9e5 100644
--- a/pugl/pugl_internal.h
+++ b/pugl/pugl_internal.h
@@ -39,11 +39,13 @@ struct PuglViewImpl {
PuglInternals* impl;
- int width;
- int height;
- int mods;
- bool ignoreKeyRepeat;
- bool redisplay;
+ int width;
+ int height;
+ int mods;
+ bool mouse_in_view;
+ bool ignoreKeyRepeat;
+ bool redisplay;
+ uint32_t event_timestamp_ms;
};
void
@@ -58,13 +60,19 @@ puglGetHandle(PuglView* view)
return view->handle;
}
+uint32_t
+puglGetEventTimestamp(PuglView* view)
+{
+ return view->event_timestamp_ms;
+}
+
int
puglGetModifiers(PuglView* view)
{
return view->mods;
}
-static inline void
+void
puglDefaultReshape(PuglView* view, int width, int height)
{
glMatrixMode(GL_PROJECTION);
diff --git a/pugl/pugl_osx.m b/pugl/pugl_osx.m
index b3b6bae..5621edc 100644
--- a/pugl/pugl_osx.m
+++ b/pugl/pugl_osx.m
@@ -24,12 +24,64 @@
#include "pugl_internal.h"
+@interface PuglWindow : NSWindow
+{
+@public
+ PuglView* puglview;
+}
+
+- (id) initWithContentRect:(NSRect)contentRect
+ styleMask:(unsigned int)aStyle
+ backing:(NSBackingStoreType)bufferingType
+ defer:(BOOL)flag;
+- (void) setPuglview:(PuglView*)view;
+- (BOOL) windowShouldClose:(id)sender;
+- (void) becomeKeyWindow:(id)sender;
+- (BOOL) canBecomeKeyWindow:(id)sender;
+@end
+
+@implementation PuglWindow
+
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(unsigned int)aStyle
+ backing:(NSBackingStoreType)bufferingType
+ defer:(BOOL)flag
+{
+ NSWindow* result = [super initWithContentRect:contentRect
+ styleMask:(NSClosableWindowMask |
+ NSTitledWindowMask |
+ NSResizableWindowMask)
+ backing:NSBackingStoreBuffered defer:NO];
+
+ [result setAcceptsMouseMovedEvents:YES];
+ [result setLevel: CGShieldingWindowLevel() + 1];
+
+ return result;
+}
+
+- (void)setPuglview:(PuglView*)view
+{
+ puglview = view;
+ [self setContentSize:NSMakeSize(view->width, view->height) ];
+}
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ if (puglview->closeFunc)
+ puglview->closeFunc(puglview);
+ return YES;
+}
+
+@end
+
@interface PuglOpenGLView : NSOpenGLView
{
int colorBits;
int depthBits;
@public
- PuglView* view;
+ PuglView* puglview;
+
+ NSTrackingArea* trackingArea;
}
- (id) initWithFrame:(NSRect)frame
@@ -38,6 +90,7 @@
- (void) reshape;
- (void) drawRect:(NSRect)rect;
- (void) mouseMoved:(NSEvent*)event;
+- (void) mouseDragged:(NSEvent*)event;
- (void) mouseDown:(NSEvent*)event;
- (void) mouseUp:(NSEvent*)event;
- (void) rightMouseDown:(NSEvent*)event;
@@ -92,33 +145,37 @@
int width = bounds.size.width;
int height = bounds.size.height;
- if (view->reshapeFunc) {
- view->reshapeFunc(view, width, height);
- } else {
- puglDefaultReshape(view, width, height);
- }
+ if (puglview) {
+ /* NOTE: Apparently reshape gets called when the GC gets around to
+ deleting the view (?), so we must have reset puglview to NULL when
+ this comes around.
+ */
+ if (puglview->reshapeFunc) {
+ puglview->reshapeFunc(puglview, width, height);
+ } else {
+ puglDefaultReshape(puglview, width, height);
+ }
- view->width = width;
- view->height = height;
+ puglview->width = width;
+ puglview->height = height;
+ }
}
- (void) drawRect:(NSRect)rect
{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
-
- if (self->view->displayFunc) {
- self->view->displayFunc(self->view);
- }
-
+ puglDisplay(puglview);
glFlush();
glSwapAPPLE();
}
-static int
-getModifiers(unsigned modifierFlags)
+static unsigned
+getModifiers(PuglView* view, NSevent* ev)
{
- int mods = 0;
+ const unsigned modifierFlags = [ev modifierFlags]
+
+ view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
+
+ unsigned mods = 0;
mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0;
mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0;
mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0;
@@ -126,99 +183,135 @@ getModifiers(unsigned modifierFlags)
return mods;
}
+-(void)updateTrackingAreas
+{
+ if (trackingArea != nil) {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ }
+
+ const int opts = (NSTrackingMouseEnteredAndExited |
+ NSTrackingMouseMoved |
+ NSTrackingActiveAlways);
+ trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
+ options:opts
+ owner:self
+ userInfo:nil];
+ [self addTrackingArea:trackingArea];
+}
+
+- (void)mouseEntered:(NSEvent*)theEvent
+{
+ [self updateTrackingAreas];
+}
+
+- (void)mouseExited:(NSEvent*)theEvent
+{
+}
+
- (void) mouseMoved:(NSEvent*)event
{
- if (view->motionFunc) {
+ if (puglview->motionFunc) {
NSPoint loc = [event locationInWindow];
- view->mods = getModifiers([event modifierFlags]);
- view->motionFunc(view, loc.x, loc.y);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
+ }
+}
+
+- (void) mouseDragged:(NSEvent*)event
+{
+ if (puglview->motionFunc) {
+ NSPoint loc = [event locationInWindow];
+ puglview->mods = getModifiers(puglview, event);
+ puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
}
}
- (void) mouseDown:(NSEvent*)event
{
- if (view->mouseFunc) {
+ if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
- view->mods = getModifiers([event modifierFlags]);
- view->mouseFunc(view, 1, true, loc.x, loc.y);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, 1, true, loc.x, puglview->height - loc.y);
}
}
- (void) mouseUp:(NSEvent*)event
{
- if (view->mouseFunc) {
+ if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
- view->mods = getModifiers([event modifierFlags]);
- view->mouseFunc(view, 1, false, loc.x, loc.y);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, 1, false, loc.x, puglview->height - loc.y);
}
+ [self updateTrackingAreas];
}
- (void) rightMouseDown:(NSEvent*)event
{
- if (view->mouseFunc) {
+ if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
- view->mods = getModifiers([event modifierFlags]);
- view->mouseFunc(view, 3, true, loc.x, loc.y);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, 3, true, loc.x, puglview->height - loc.y);
}
}
- (void) rightMouseUp:(NSEvent*)event
{
- if (view->mouseFunc) {
+ if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
- view->mods = getModifiers([event modifierFlags]);
- view->mouseFunc(view, 3, false, loc.x, loc.y);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->mouseFunc(puglview, 3, false, loc.x, puglview->height - loc.y);
}
}
- (void) scrollWheel:(NSEvent*)event
{
- if (view->scrollFunc) {
- view->mods = getModifiers([event modifierFlags]);
- view->scrollFunc(view, [event deltaX], [event deltaY]);
+ if (puglview->scrollFunc) {
+ puglview->mods = getModifiers(puglview, event);
+ puglview->scrollFunc(puglview, [event deltaX], [event deltaY]);
}
+ [self updateTrackingAreas];
}
- (void) keyDown:(NSEvent*)event
{
- if (view->keyboardFunc && !(view->ignoreKeyRepeat && [event isARepeat])) {
+ if (puglview->keyboardFunc && !(puglview->ignoreKeyRepeat && [event isARepeat])) {
NSString* chars = [event characters];
- view->mods = getModifiers([event modifierFlags]);
- view->keyboardFunc(view, true, [chars characterAtIndex:0]);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->keyboardFunc(puglview, true, [chars characterAtIndex:0]);
}
}
- (void) keyUp:(NSEvent*)event
{
- if (view->keyboardFunc) {
+ if (puglview->keyboardFunc) {
NSString* chars = [event characters];
- view->mods = getModifiers([event modifierFlags]);
- view->keyboardFunc(view, false, [chars characterAtIndex:0]);
+ puglview->mods = getModifiers(puglview, event);
+ puglview->keyboardFunc(puglview, false, [chars characterAtIndex:0]);
}
}
- (void) flagsChanged:(NSEvent*)event
{
- if (view->specialFunc) {
- int mods = getModifiers([event modifierFlags]);
- if ((mods & PUGL_MOD_SHIFT) != (view->mods & PUGL_MOD_SHIFT)) {
- view->specialFunc(view, mods & PUGL_MOD_SHIFT, PUGL_KEY_SHIFT);
- } else if ((mods & PUGL_MOD_CTRL) != (view->mods & PUGL_MOD_CTRL)) {
- view->specialFunc(view, mods & PUGL_MOD_CTRL, PUGL_KEY_CTRL);
- } else if ((mods & PUGL_MOD_ALT) != (view->mods & PUGL_MOD_ALT)) {
- view->specialFunc(view, mods & PUGL_MOD_ALT, PUGL_KEY_ALT);
- } else if ((mods & PUGL_MOD_SUPER) != (view->mods & PUGL_MOD_SUPER)) {
- view->specialFunc(view, mods & PUGL_MOD_SUPER, PUGL_KEY_SUPER);
+ if (puglview->specialFunc) {
+ const unsigned mods = getModifiers(puglview, [event modifierFlags]);
+ if ((mods & PUGL_MOD_SHIFT) != (puglview->mods & PUGL_MOD_SHIFT)) {
+ puglview->specialFunc(puglview, mods & PUGL_MOD_SHIFT, PUGL_KEY_SHIFT);
+ } else if ((mods & PUGL_MOD_CTRL) != (puglview->mods & PUGL_MOD_CTRL)) {
+ puglview->specialFunc(puglview, mods & PUGL_MOD_CTRL, PUGL_KEY_CTRL);
+ } else if ((mods & PUGL_MOD_ALT) != (puglview->mods & PUGL_MOD_ALT)) {
+ puglview->specialFunc(puglview, mods & PUGL_MOD_ALT, PUGL_KEY_ALT);
+ } else if ((mods & PUGL_MOD_SUPER) != (puglview->mods & PUGL_MOD_SUPER)) {
+ puglview->specialFunc(puglview, mods & PUGL_MOD_SUPER, PUGL_KEY_SUPER);
}
- view->mods = mods;
+ puglview->mods = mods;
}
}
@end
struct PuglInternalsImpl {
- PuglOpenGLView* view;
- NSModalSession session;
+ PuglOpenGLView* glview;
id window;
};
@@ -241,33 +334,26 @@ puglCreate(PuglNativeWindow parent,
[NSAutoreleasePool new];
[NSApplication sharedApplication];
- [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
NSString* titleString = [[NSString alloc]
initWithBytes:title
length:strlen(title)
encoding:NSUTF8StringEncoding];
- id window = [[[NSWindow alloc]
- initWithContentRect:NSMakeRect(0, 0, 512, 512)
- styleMask:NSTitledWindowMask
- backing:NSBackingStoreBuffered
- defer:NO]
- autorelease];
+ id window = [[PuglWindow new]retain];
- [window cascadeTopLeftFromPoint:NSMakePoint(20, 20)];
+ [window setPuglview:view];
[window setTitle:titleString];
- [window setAcceptsMouseMovedEvents:YES];
- impl->view = [PuglOpenGLView new];
+ impl->glview = [PuglOpenGLView new];
impl->window = window;
- impl->view->view = view;
+ impl->glview->puglview = view;
- [window setContentView:impl->view];
+ [window setContentView:impl->glview];
[NSApp activateIgnoringOtherApps:YES];
- [window makeFirstResponder:impl->view];
+ [window makeFirstResponder:impl->glview];
- impl->session = [NSApp beginModalSessionForWindow:view->impl->window];
+ [window makeKeyAndOrderFront:window];
return view;
}
@@ -275,8 +361,10 @@ puglCreate(PuglNativeWindow parent,
void
puglDestroy(PuglView* view)
{
- [NSApp endModalSession:view->impl->session];
- [view->impl->view release];
+ view->impl->glview->puglview = NULL;
+ [view->impl->window close];
+ [view->impl->glview release];
+ [view->impl->window release];
free(view->impl);
free(view);
}
@@ -284,30 +372,15 @@ puglDestroy(PuglView* view)
void
puglDisplay(PuglView* view)
{
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glLoadIdentity();
-
if (view->displayFunc) {
view->displayFunc(view);
}
-
- glFlush();
- view->redisplay = false;
}
PuglStatus
puglProcessEvents(PuglView* view)
{
- NSInteger response = [NSApp runModalSession:view->impl->session];
- if (response != NSRunContinuesResponse) {
- if (view->closeFunc) {
- view->closeFunc(view);
- }
- }
-
- if (view->redisplay) {
- puglDisplay(view);
- }
+ [view->impl->glview setNeedsDisplay: YES];
return PUGL_SUCCESS;
}
@@ -321,5 +394,5 @@ puglPostRedisplay(PuglView* view)
PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
- return (PuglNativeWindow)view->impl->view;
+ return (PuglNativeWindow)view->impl->glview;
}
diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp
index 64d15a6..14e8070 100644
--- a/pugl/pugl_win.cpp
+++ b/pugl/pugl_win.cpp
@@ -22,6 +22,9 @@
#include <windowsx.h>
#include <GL/gl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
#include "pugl_internal.h"
#ifndef WM_MOUSEWHEEL
@@ -30,11 +33,17 @@
#ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
#endif
+#ifndef WHEEL_DELTA
+# define WHEEL_DELTA 120
+#endif
+
+const int LOCAL_CLOSE_MSG = WM_USER + 50;
struct PuglInternalsImpl {
- HWND hwnd;
- HDC hdc;
- HGLRC hglrc;
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+ WNDCLASS wc;
};
LRESULT CALLBACK
@@ -57,24 +66,36 @@ puglCreate(PuglNativeWindow parent,
view->width = width;
view->height = height;
- WNDCLASS wc;
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = wndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = 0;
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName = "Pugl";
- RegisterClass(&wc);
-
- impl->hwnd = CreateWindow(
- "Pugl", title,
- WS_VISIBLE | (parent ? WS_CHILD : (WS_POPUPWINDOW | WS_CAPTION)),
- 0, 0, width, height,
+ // FIXME: This is nasty, and pugl should not have static anything.
+ // Should class be a parameter? Does this make sense on other platforms?
+ static int wc_count = 0;
+ char classNameBuf[256];
+ snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d\n", title, wc_count++);
+
+ impl->wc.style = CS_OWNDC;
+ impl->wc.lpfnWndProc = wndProc;
+ impl->wc.cbClsExtra = 0;
+ impl->wc.cbWndExtra = 0;
+ impl->wc.hInstance = 0;
+ impl->wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ impl->wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ impl->wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ impl->wc.lpszMenuName = NULL;
+ impl->wc.lpszClassName = classNameBuf;
+ RegisterClass(&impl->wc);
+
+ // Adjust the overall window size to accomodate our requested client size
+ RECT wr = { 0, 0, width, height };
+ AdjustWindowRectEx(
+ &wr, WS_SIZEBOX | WS_POPUPWINDOW | WS_CAPTION, FALSE, WS_EX_TOPMOST);
+
+ impl->hwnd = CreateWindowEx(
+ WS_EX_TOPMOST,
+ classNameBuf, title,
+ WS_VISIBLE | (parent ? WS_CHILD : (WS_SIZEBOX | WS_POPUPWINDOW | WS_CAPTION)),
+ 0, 0, wr.right-wr.left, wr.bottom-wr.top,
(HWND)parent, NULL, NULL, NULL);
+
if (!impl->hwnd) {
free(impl);
free(view);
@@ -114,11 +135,12 @@ puglDestroy(PuglView* view)
wglDeleteContext(view->impl->hglrc);
ReleaseDC(view->impl->hwnd, view->impl->hdc);
DestroyWindow(view->impl->hwnd);
+ UnregisterClass(view->impl->wc.lpszClassName, NULL);
free(view->impl);
free(view);
}
-void
+static void
puglReshape(PuglView* view, int width, int height)
{
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
@@ -186,6 +208,13 @@ keySymToSpecial(int sym)
static void
processMouseEvent(PuglView* view, int button, bool press, LPARAM lParam)
{
+ view->event_timestamp_ms = GetMessageTime();
+ if (press) {
+ SetCapture(view->impl->hwnd);
+ } else {
+ ReleaseCapture();
+ }
+
if (view->mouseFunc) {
view->mouseFunc(view, button, press,
GET_X_LPARAM(lParam),
@@ -216,7 +245,11 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
case WM_CREATE:
case WM_SHOWWINDOW:
case WM_SIZE:
- puglReshape(view, view->width, view->height);
+ RECT rect;
+ GetClientRect(view->impl->hwnd, &rect);
+ puglReshape(view, rect.right, rect.bottom);
+ view->width = rect.right;
+ view->height = rect.bottom;
break;
case WM_PAINT:
BeginPaint(view->impl->hwnd, &ps);
@@ -225,8 +258,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_MOUSEMOVE:
if (view->motionFunc) {
- view->motionFunc(
- view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ view->motionFunc(view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
break;
case WM_LBUTTONDOWN:
@@ -260,6 +292,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_KEYDOWN:
+ view->event_timestamp_ms = (GetMessageTime());
if (view->ignoreKeyRepeat && (lParam & (1 << 30))) {
break;
} // else nobreak
@@ -273,6 +306,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_QUIT:
+ case LOCAL_CLOSE_MSG:
if (view->closeFunc) {
view->closeFunc(view);
}
@@ -288,13 +322,8 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
PuglStatus
puglProcessEvents(PuglView* view)
{
- MSG msg;
- while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) {
- handleMessage(view, msg.message, msg.wParam, msg.lParam);
- }
-
if (view->redisplay) {
- puglDisplay(view);
+ InvalidateRect(view->impl->hwnd, NULL, FALSE);
}
return PUGL_SUCCESS;
@@ -309,14 +338,10 @@ wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
return 0;
case WM_CLOSE:
- PostQuitMessage(0);
+ PostMessage(hwnd, LOCAL_CLOSE_MSG, wParam, lParam);
return 0;
case WM_DESTROY:
return 0;
- case WM_MOUSEWHEEL:
- case WM_MOUSEHWHEEL:
- PostMessage(hwnd, message, wParam, lParam);
- return 0;
default:
if (view) {
return handleMessage(view, message, wParam, lParam);
diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c
index 16b0cd7..fd61632 100644
--- a/pugl/pugl_x11.c
+++ b/pugl/pugl_x11.c
@@ -147,7 +147,7 @@ puglCreate(PuglNativeWindow parent,
if (glXIsDirect(impl->display, impl->ctx)) {
printf("DRI enabled\n");
} else {
- printf("no DRI available\n");
+ printf("No DRI available\n");
}
XFree(vi);
@@ -241,8 +241,10 @@ keySymToSpecial(KeySym sym)
}
static void
-setModifiers(PuglView* view, int xstate)
+setModifiers(PuglView* view, unsigned xstate, unsigned xtime)
{
+ view->event_timestamp_ms = xtime;
+
view->mods = 0;
view->mods |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0;
view->mods |= (xstate & ControlMask) ? PUGL_MOD_CTRL : 0;
@@ -273,16 +275,15 @@ puglProcessEvents(PuglView* view)
break;
}
puglDisplay(view);
- view->redisplay = false;
break;
case MotionNotify:
- setModifiers(view, event.xmotion.state);
+ setModifiers(view, event.xmotion.state, event.xmotion.time);
if (view->motionFunc) {
view->motionFunc(view, event.xmotion.x, event.xmotion.y);
}
break;
case ButtonPress:
- setModifiers(view, event.xbutton.state);
+ setModifiers(view, event.xbutton.state, event.xbutton.time);
if (event.xbutton.button >= 4 && event.xbutton.button <= 7) {
if (view->scrollFunc) {
float dx = 0, dy = 0;
@@ -298,7 +299,7 @@ puglProcessEvents(PuglView* view)
}
// nobreak
case ButtonRelease:
- setModifiers(view, event.xbutton.state);
+ setModifiers(view, event.xbutton.state, event.xbutton.time);
if (view->mouseFunc &&
(event.xbutton.button < 4 || event.xbutton.button > 7)) {
view->mouseFunc(view,
@@ -307,7 +308,7 @@ puglProcessEvents(PuglView* view)
}
break;
case KeyPress: {
- setModifiers(view, event.xkey.state);
+ setModifiers(view, event.xkey.state, event.xkey.time);
KeySym sym;
char str[5];
int n = XLookupString(&event.xkey, str, 4, &sym, NULL);
@@ -323,7 +324,7 @@ puglProcessEvents(PuglView* view)
}
} break;
case KeyRelease: {
- setModifiers(view, event.xkey.state);
+ setModifiers(view, event.xkey.state, event.xkey.time);
bool repeated = false;
if (view->ignoreKeyRepeat &&
XEventsQueued(view->impl->display, QueuedAfterReading)) {
diff --git a/wscript b/wscript
index 79c805e..b27f6f9 100644
--- a/wscript
+++ b/wscript
@@ -7,7 +7,7 @@ from waflib.extras import autowaf as autowaf
import waflib.Logs as Logs, waflib.Options as Options
# Version of this package (even if built as a child)
-PUGL_VERSION = '0.0.0'
+PUGL_VERSION = '0.1.0'
PUGL_MAJOR_VERSION = '0'
# Library version (UNIX style major, minor, micro)