aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2019-07-20 13:24:55 +0200
committerDavid Robillard <d@drobilla.net>2019-07-20 13:41:54 +0200
commite7d9aaf9bf756f7eb0e0f4d499def93d4389e8ae (patch)
tree2ba02a43159fedf1ee46a12ccc72c7af330fc4cc
parentcf6da599e3ea7cf51f296dac722e3694c53b4ea3 (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--wscript13
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
diff --git a/wscript b/wscript
index 31e59ac..09a8296 100644
--- a/wscript
+++ b/wscript
@@ -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)