diff options
author | David Robillard <d@drobilla.net> | 2019-07-20 13:24:55 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-07-20 13:41:54 +0200 |
commit | e7d9aaf9bf756f7eb0e0f4d499def93d4389e8ae (patch) | |
tree | 2ba02a43159fedf1ee46a12ccc72c7af330fc4cc | |
parent | cf6da599e3ea7cf51f296dac722e3694c53b4ea3 (diff) |
Use C for Windows implementation
This avoids C++ binary compatibility and dependency hassles when
cross-compiling.
-rw-r--r-- | pugl/pugl_win.c (renamed from pugl/pugl_win.cpp) | 112 | ||||
-rw-r--r-- | wscript | 13 |
2 files changed, 65 insertions, 60 deletions
diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.c index 6e27a8d..b1fa41a 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.c @@ -15,7 +15,7 @@ */ /** - @file pugl_win.cpp Windows/WGL Pugl Implementation. + @file pugl_win.c Windows/WGL Pugl Implementation. */ #include "pugl/pugl_internal.h" @@ -79,23 +79,20 @@ struct PuglInternalsImpl { }; // Scoped class to manage the fake window used during window creation -struct PuglFakeWindow { - PuglFakeWindow(HWND wnd) : hwnd{wnd}, hdc{wnd ? GetDC(wnd) : 0} {} - PuglFakeWindow(const PuglFakeWindow&) = delete; - - ~PuglFakeWindow() { - if (hwnd) { - ReleaseDC(hwnd, hdc); - DestroyWindow(hwnd); - } - } - +typedef struct { HWND hwnd; HDC hdc; -}; +} PuglFakeWindow; static const TCHAR* DEFAULT_CLASSNAME = "Pugl"; +static PuglFakeWindow +puglMakeFakeWindow(HWND wnd) +{ + const PuglFakeWindow fakeWin = {wnd, wnd ? GetDC(wnd) : 0}; + return fakeWin; +} + LRESULT CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -153,10 +150,15 @@ puglGetPixelFormatDescriptor(const PuglHints* hints) return pfd; } -template <typename Proc> -Proc puglGetProc(const char* name) +static int +puglWinError(PuglFakeWindow* fakeWin, const int status) { - return reinterpret_cast<Proc>(wglGetProcAddress(name)); + if (fakeWin->hwnd) { + ReleaseDC(fakeWin->hwnd, fakeWin->hdc); + DestroyWindow(fakeWin->hwnd); + } + + return status; } int @@ -206,7 +208,7 @@ puglCreateWindow(PuglView* view, const char* title) AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST); // Create fake window for getting at GL context - PuglFakeWindow fakeWin( + PuglFakeWindow fakeWin = puglMakeFakeWindow( CreateWindowEx(WS_EX_TOPMOST, className, title, (view->parent ? WS_CHILD : winFlags), @@ -215,31 +217,32 @@ puglCreateWindow(PuglView* view, const char* title) (HWND)view->parent, NULL, NULL, NULL)); if (!fakeWin.hwnd) { - return 2; + return puglWinError(&fakeWin, 2); } // Choose pixel format for fake window - const auto fakePfd = puglGetPixelFormatDescriptor(&view->hints); - const int fakeFormatId = ChoosePixelFormat(fakeWin.hdc, &fakePfd); + const PIXELFORMATDESCRIPTOR fakePfd = puglGetPixelFormatDescriptor( + &view->hints); + const int fakeFormatId = ChoosePixelFormat(fakeWin.hdc, &fakePfd); if (!fakeFormatId) { - return 3; + return puglWinError(&fakeWin, 3); } else if (!SetPixelFormat(fakeWin.hdc, fakeFormatId, &fakePfd)) { - return 4; + return puglWinError(&fakeWin, 4); } HGLRC fakeRc = wglCreateContext(fakeWin.hdc); if (!fakeRc) { - return 5; + return puglWinError(&fakeWin, 5); } wglMakeCurrent(fakeWin.hdc, fakeRc); - auto wglChoosePixelFormat = puglGetProc<WglChoosePixelFormat>( - "wglChoosePixelFormatARB"); - auto wglCreateContextAttribs = puglGetProc<WglCreateContextAttribs>( - "wglCreateContextAttribsARB"); - auto wglSwapInterval = puglGetProc<WglSwapInterval>( - "wglSwapIntervalEXT"); + WglChoosePixelFormat wglChoosePixelFormat = (WglChoosePixelFormat)( + wglGetProcAddress("wglChoosePixelFormatARB")); + WglCreateContextAttribs wglCreateContextAttribs = (WglCreateContextAttribs)( + wglGetProcAddress("wglCreateContextAttribsARB")); + WglSwapInterval wglSwapInterval = (WglSwapInterval)( + wglGetProcAddress("wglSwapIntervalEXT")); PuglInternals* impl = view->impl; @@ -275,14 +278,14 @@ puglCreateWindow(PuglView* view, const char* title) int pixelFormatId; UINT numFormats; if (!wglChoosePixelFormat(impl->hdc, pixelAttrs, NULL, 1u, &pixelFormatId, &numFormats)) { - return 6; + return puglWinError(&fakeWin, 6); } // Set desired pixel format PIXELFORMATDESCRIPTOR pfd; DescribePixelFormat(impl->hdc, pixelFormatId, sizeof(pfd), &pfd); if (!SetPixelFormat(impl->hdc, pixelFormatId, &pfd)) { - return 7; + return puglWinError(&fakeWin, 7); } // Create final GL context @@ -296,15 +299,18 @@ puglCreateWindow(PuglView* view, const char* title) }; if (!(impl->hglrc = wglCreateContextAttribs(impl->hdc, 0, contextAttribs))) { - return 8; + return puglWinError(&fakeWin, 8); } // Switch to new context wglMakeCurrent(NULL, NULL); wglDeleteContext(fakeRc); if (!wglMakeCurrent(impl->hdc, impl->hglrc)) { - return 9; + return puglWinError(&fakeWin, 9); } + + ReleaseDC(fakeWin.hwnd, fakeWin.hdc); + DestroyWindow(fakeWin.hwnd); } else { // Modern extensions not available, just use the original "fake" window impl->hwnd = fakeWin.hwnd; @@ -320,7 +326,7 @@ puglCreateWindow(PuglView* view, const char* title) LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); - impl->timerFrequency = static_cast<double>(frequency.QuadPart); + impl->timerFrequency = (double)frequency.QuadPart; SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view); @@ -395,7 +401,7 @@ keySymToSpecial(WPARAM sym) } static uint32_t -getModifiers() +getModifiers(void) { uint32_t mods = 0; mods |= (GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0; @@ -422,23 +428,23 @@ initMouseEvent(PuglEvent* event, ReleaseCapture(); } - event->button.time = static_cast<uint32_t>(GetMessageTime()); + event->button.time = (uint32_t)GetMessageTime(); event->button.type = press ? PUGL_BUTTON_PRESS : PUGL_BUTTON_RELEASE; event->button.x = GET_X_LPARAM(lParam); event->button.y = GET_Y_LPARAM(lParam); event->button.x_root = pt.x; event->button.y_root = pt.y; event->button.state = getModifiers(); - event->button.button = static_cast<uint32_t>(button); + event->button.button = (uint32_t)button; } static void -initScrollEvent(PuglEvent* event, PuglView* view, LPARAM lParam, WPARAM) +initScrollEvent(PuglEvent* event, PuglView* view, LPARAM lParam) { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; ScreenToClient(view->impl->hwnd, &pt); - event->scroll.time = static_cast<uint32_t>(GetMessageTime()); + event->scroll.time = (uint32_t)GetMessageTime(); event->scroll.type = PUGL_SCROLL; event->scroll.x = pt.x; event->scroll.y = pt.y; @@ -483,15 +489,15 @@ initKeyEvent(PuglEvent* event, PuglView* view, bool press, LPARAM lParam) ScreenToClient(view->impl->hwnd, &rpos); event->key.type = press ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE; - event->key.time = static_cast<uint32_t>(GetMessageTime()); + event->key.time = (uint32_t)GetMessageTime(); event->key.state = getModifiers(); event->key.x_root = rpos.x; event->key.y_root = rpos.y; event->key.x = cpos.x; event->key.y = cpos.y; - event->key.keycode = static_cast<uint32_t>((lParam & 0xFF0000) >> 16); + event->key.keycode = (uint32_t)((lParam & 0xFF0000) >> 16); event->key.character = 0; - event->key.special = static_cast<PuglKey>(0); + event->key.special = (PuglKey)0; event->key.filter = 0; } @@ -499,7 +505,7 @@ static void wcharBufToEvent(wchar_t* buf, int n, PuglEvent* event) { if (n > 0) { - char* charp = reinterpret_cast<char*>(event->key.utf8); + char* charp = (char*)event->key.utf8; if (!WideCharToMultiByte(CP_UTF8, 0, buf, n, charp, 8, NULL, NULL)) { /* error: could not convert to utf-8, @@ -522,8 +528,10 @@ wcharBufToEvent(wchar_t* buf, int n, PuglEvent* event) } static void -translateMessageParamsToEvent(LPARAM, WPARAM wParam, PuglEvent* event) +translateMessageParamsToEvent(LPARAM lParam, WPARAM wParam, PuglEvent* event) { + (void)lParam; + /* TODO: This is a kludge. Would be nice to use ToUnicode here, but this breaks composed keys because it messes with the keyboard state. Not sure how to correctly handle this on Windows. */ @@ -542,7 +550,7 @@ translateMessageParamsToEvent(LPARAM, WPARAM wParam, PuglEvent* event) // So, since Google refuses to give me a better solution, and if no one // else has a better solution, I will make a hack... wchar_t buf[5] = { 0, 0, 0, 0, 0 }; - WPARAM c = MapVirtualKey(static_cast<unsigned>(wParam), MAPVK_VK_TO_CHAR); + WPARAM c = MapVirtualKey((unsigned)wParam, MAPVK_VK_TO_CHAR); buf[0] = c & 0xffff; // TODO: This does not take caps lock into account // TODO: Dead keys should affect key releases as well @@ -626,7 +634,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) ClientToScreen(view->impl->hwnd, &pt); event.motion.type = PUGL_MOTION_NOTIFY; - event.motion.time = static_cast<uint32_t>(GetMessageTime()); + event.motion.time = (uint32_t)GetMessageTime(); event.motion.x = GET_X_LPARAM(lParam); event.motion.y = GET_Y_LPARAM(lParam); event.motion.x_root = pt.x; @@ -653,11 +661,11 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) initMouseEvent(&event, view, 3, false, lParam); break; case WM_MOUSEWHEEL: - initScrollEvent(&event, view, lParam, wParam); + initScrollEvent(&event, view, lParam); event.scroll.dy = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; break; case WM_MOUSEHWHEEL: - initScrollEvent(&event, view, lParam, wParam); + initScrollEvent(&event, view, lParam); event.scroll.dx = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; break; case WM_KEYDOWN: @@ -702,14 +710,16 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) } void -puglGrabFocus(PuglView*) +puglGrabFocus(PuglView* view) { + (void)view; // TODO } PuglStatus -puglWaitForEvent(PuglView*) +puglWaitForEvent(PuglView* view) { + (void)view; WaitMessage(); return PUGL_SUCCESS; } @@ -765,7 +775,7 @@ puglGetTime(PuglView* view) { LARGE_INTEGER count; QueryPerformanceCounter(&count); - return double(count.QuadPart) / view->impl->timerFrequency; + return (double)count.QuadPart / view->impl->timerFrequency; } void @@ -21,7 +21,6 @@ out = 'build' # Build directory def options(ctx): ctx.load('compiler_c') - ctx.load('compiler_cxx') opts = ctx.configuration_options() opts.add_option('--target', default=None, dest='target', @@ -41,9 +40,8 @@ def configure(conf): conf.load('autowaf', cache=True) if conf.env.TARGET_PLATFORM == 'win32': - conf.load('compiler_cxx', cache=True) if conf.env.MSVC_COMPILER: - conf.env.append_unique('CXXFLAGS', ['/wd4191']) + conf.env.append_unique('CFLAGS', ['/wd4191']) elif conf.env.TARGET_PLATFORM == 'darwin': conf.env.append_unique('CFLAGS', ['-Wno-deprecated-declarations']) @@ -95,15 +93,12 @@ def build(bld): framework = [] libs = [] if bld.env.TARGET_PLATFORM == 'win32': - lang = 'cxx' - lib_source = ['pugl/pugl_win.cpp'] + lib_source = ['pugl/pugl_win.c'] libs = ['opengl32', 'gdi32', 'user32'] elif bld.env.TARGET_PLATFORM == 'darwin': - lang = 'c' # Objective C, actually lib_source = ['pugl/pugl_osx.m'] framework = ['Cocoa', 'OpenGL'] else: - lang = 'c' lib_source = ['pugl/pugl_x11.c'] libs = ['X11'] if bld.is_defined('HAVE_GL'): @@ -134,14 +129,14 @@ def build(bld): # Shared Library if bld.env['BUILD_SHARED']: - bld(features = '%s %sshlib' % (lang, lang), + bld(features = 'c cshlib', name = 'libpugl', cflags = libflags + ['-DPUGL_SHARED', '-DPUGL_INTERNAL'], **lib_common) # Static library if bld.env['BUILD_STATIC']: - bld(features = '%s %sstlib' % (lang, lang), + bld(features = 'c cstlib', name = 'libpugl_static', cflags = ['-DPUGL_INTERNAL'], **lib_common) |