From aa01d329754134899e6e729d6948a72e0ef881c4 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 3 Feb 2013 01:44:06 +0000 Subject: Apply portability fixes from Ben Loftis. --- pugl/pugl_win.cpp | 95 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 35 deletions(-) (limited to 'pugl/pugl_win.cpp') 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 #include +#include +#include + #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); -- cgit v1.2.1