aboutsummaryrefslogtreecommitdiffstats
path: root/pugl/pugl_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pugl/pugl_win.cpp')
-rw-r--r--pugl/pugl_win.cpp95
1 files changed, 60 insertions, 35 deletions
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);