aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/implementation.c456
-rw-r--r--src/mac.h18
-rw-r--r--src/mac.m1726
-rw-r--r--src/mac_cairo.m137
-rw-r--r--src/mac_gl.m232
-rw-r--r--src/mac_stub.m68
-rw-r--r--src/mac_vulkan.m168
-rw-r--r--src/stub.h28
-rw-r--r--src/types.h92
-rw-r--r--src/win.c1591
-rw-r--r--src/win.h168
-rw-r--r--src/win_cairo.c163
-rw-r--r--src/win_gl.c444
-rw-r--r--src/win_stub.c64
-rw-r--r--src/win_vulkan.c97
-rw-r--r--src/x11.c1983
-rw-r--r--src/x11.h61
-rw-r--r--src/x11_cairo.c171
-rw-r--r--src/x11_gl.c280
-rw-r--r--src/x11_stub.c40
-rw-r--r--src/x11_vulkan.c105
21 files changed, 4074 insertions, 4018 deletions
diff --git a/src/implementation.c b/src/implementation.c
index e842e13..a6d8393 100644
--- a/src/implementation.c
+++ b/src/implementation.c
@@ -26,248 +26,249 @@
const char*
puglStrerror(const PuglStatus status)
{
- // clang-format off
- switch (status) {
- case PUGL_SUCCESS: return "Success";
- case PUGL_FAILURE: return "Non-fatal failure";
- case PUGL_UNKNOWN_ERROR: return "Unknown system error";
- case PUGL_BAD_BACKEND: return "Invalid or missing backend";
- case PUGL_BAD_CONFIGURATION: return "Invalid view configuration";
- case PUGL_BAD_PARAMETER: return "Invalid parameter";
- case PUGL_BACKEND_FAILED: return "Backend initialisation failed";
- case PUGL_REGISTRATION_FAILED: return "Class registration failed";
- case PUGL_REALIZE_FAILED: return "View creation failed";
- case PUGL_SET_FORMAT_FAILED: return "Failed to set pixel format";
- case PUGL_CREATE_CONTEXT_FAILED: return "Failed to create drawing context";
- case PUGL_UNSUPPORTED_TYPE: return "Unsupported data type";
- }
- // clang-format on
-
- return "Unknown error";
+ // clang-format off
+ switch (status) {
+ case PUGL_SUCCESS: return "Success";
+ case PUGL_FAILURE: return "Non-fatal failure";
+ case PUGL_UNKNOWN_ERROR: return "Unknown system error";
+ case PUGL_BAD_BACKEND: return "Invalid or missing backend";
+ case PUGL_BAD_CONFIGURATION: return "Invalid view configuration";
+ case PUGL_BAD_PARAMETER: return "Invalid parameter";
+ case PUGL_BACKEND_FAILED: return "Backend initialisation failed";
+ case PUGL_REGISTRATION_FAILED: return "Class registration failed";
+ case PUGL_REALIZE_FAILED: return "View creation failed";
+ case PUGL_SET_FORMAT_FAILED: return "Failed to set pixel format";
+ case PUGL_CREATE_CONTEXT_FAILED: return "Failed to create drawing context";
+ case PUGL_UNSUPPORTED_TYPE: return "Unsupported data type";
+ }
+ // clang-format on
+
+ return "Unknown error";
}
void
puglSetString(char** dest, const char* string)
{
- if (*dest != string) {
- const size_t len = strlen(string);
+ if (*dest != string) {
+ const size_t len = strlen(string);
- *dest = (char*)realloc(*dest, len + 1);
- strncpy(*dest, string, len + 1);
- }
+ *dest = (char*)realloc(*dest, len + 1);
+ strncpy(*dest, string, len + 1);
+ }
}
void
puglSetBlob(PuglBlob* const dest, const void* const data, const size_t len)
{
- if (data) {
- dest->len = len;
- dest->data = realloc(dest->data, len + 1);
- memcpy(dest->data, data, len);
- ((char*)dest->data)[len] = 0;
- } else {
- dest->len = 0;
- dest->data = NULL;
- }
+ if (data) {
+ dest->len = len;
+ dest->data = realloc(dest->data, len + 1);
+ memcpy(dest->data, data, len);
+ ((char*)dest->data)[len] = 0;
+ } else {
+ dest->len = 0;
+ dest->data = NULL;
+ }
}
static void
puglSetDefaultHints(PuglHints hints)
{
- hints[PUGL_USE_COMPAT_PROFILE] = PUGL_TRUE;
- hints[PUGL_CONTEXT_VERSION_MAJOR] = 2;
- hints[PUGL_CONTEXT_VERSION_MINOR] = 0;
- hints[PUGL_RED_BITS] = 8;
- hints[PUGL_GREEN_BITS] = 8;
- hints[PUGL_BLUE_BITS] = 8;
- hints[PUGL_ALPHA_BITS] = 8;
- hints[PUGL_DEPTH_BITS] = 0;
- hints[PUGL_STENCIL_BITS] = 0;
- hints[PUGL_SAMPLES] = 0;
- hints[PUGL_DOUBLE_BUFFER] = PUGL_TRUE;
- hints[PUGL_SWAP_INTERVAL] = PUGL_DONT_CARE;
- hints[PUGL_RESIZABLE] = PUGL_FALSE;
- hints[PUGL_IGNORE_KEY_REPEAT] = PUGL_FALSE;
- hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE;
+ hints[PUGL_USE_COMPAT_PROFILE] = PUGL_TRUE;
+ hints[PUGL_CONTEXT_VERSION_MAJOR] = 2;
+ hints[PUGL_CONTEXT_VERSION_MINOR] = 0;
+ hints[PUGL_RED_BITS] = 8;
+ hints[PUGL_GREEN_BITS] = 8;
+ hints[PUGL_BLUE_BITS] = 8;
+ hints[PUGL_ALPHA_BITS] = 8;
+ hints[PUGL_DEPTH_BITS] = 0;
+ hints[PUGL_STENCIL_BITS] = 0;
+ hints[PUGL_SAMPLES] = 0;
+ hints[PUGL_DOUBLE_BUFFER] = PUGL_TRUE;
+ hints[PUGL_SWAP_INTERVAL] = PUGL_DONT_CARE;
+ hints[PUGL_RESIZABLE] = PUGL_FALSE;
+ hints[PUGL_IGNORE_KEY_REPEAT] = PUGL_FALSE;
+ hints[PUGL_REFRESH_RATE] = PUGL_DONT_CARE;
}
PuglWorld*
puglNewWorld(PuglWorldType type, PuglWorldFlags flags)
{
- PuglWorld* world = (PuglWorld*)calloc(1, sizeof(PuglWorld));
- if (!world || !(world->impl = puglInitWorldInternals(type, flags))) {
- free(world);
- return NULL;
- }
+ PuglWorld* world = (PuglWorld*)calloc(1, sizeof(PuglWorld));
+ if (!world || !(world->impl = puglInitWorldInternals(type, flags))) {
+ free(world);
+ return NULL;
+ }
- world->startTime = puglGetTime(world);
+ world->startTime = puglGetTime(world);
- puglSetString(&world->className, "Pugl");
+ puglSetString(&world->className, "Pugl");
- return world;
+ return world;
}
void
puglFreeWorld(PuglWorld* const world)
{
- puglFreeWorldInternals(world);
- free(world->className);
- free(world->views);
- free(world);
+ puglFreeWorldInternals(world);
+ free(world->className);
+ free(world->views);
+ free(world);
}
void
puglSetWorldHandle(PuglWorld* world, PuglWorldHandle handle)
{
- world->handle = handle;
+ world->handle = handle;
}
PuglWorldHandle
puglGetWorldHandle(PuglWorld* world)
{
- return world->handle;
+ return world->handle;
}
PuglStatus
puglSetClassName(PuglWorld* const world, const char* const name)
{
- puglSetString(&world->className, name);
- return PUGL_SUCCESS;
+ puglSetString(&world->className, name);
+ return PUGL_SUCCESS;
}
PuglView*
puglNewView(PuglWorld* const world)
{
- PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
- if (!view || !(view->impl = puglInitViewInternals())) {
- free(view);
- return NULL;
- }
+ PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
+ if (!view || !(view->impl = puglInitViewInternals())) {
+ free(view);
+ return NULL;
+ }
- view->world = world;
- view->minWidth = 1;
- view->minHeight = 1;
+ view->world = world;
+ view->minWidth = 1;
+ view->minHeight = 1;
- puglSetDefaultHints(view->hints);
+ puglSetDefaultHints(view->hints);
- // Add to world view list
- ++world->numViews;
- world->views = (PuglView**)realloc(world->views,
- world->numViews * sizeof(PuglView*));
+ // Add to world view list
+ ++world->numViews;
+ world->views =
+ (PuglView**)realloc(world->views, world->numViews * sizeof(PuglView*));
- world->views[world->numViews - 1] = view;
+ world->views[world->numViews - 1] = view;
- return view;
+ return view;
}
void
puglFreeView(PuglView* view)
{
- puglDispatchSimpleEvent(view, PUGL_DESTROY);
-
- // Remove from world view list
- PuglWorld* world = view->world;
- for (size_t i = 0; i < world->numViews; ++i) {
- if (world->views[i] == view) {
- if (i == world->numViews - 1) {
- world->views[i] = NULL;
- } else {
- memmove(world->views + i, world->views + i + 1,
- sizeof(PuglView*) * (world->numViews - i - 1));
- world->views[world->numViews - 1] = NULL;
- }
- --world->numViews;
- }
- }
-
- free(view->title);
- free(view->clipboard.data);
- puglFreeViewInternals(view);
- free(view);
+ puglDispatchSimpleEvent(view, PUGL_DESTROY);
+
+ // Remove from world view list
+ PuglWorld* world = view->world;
+ for (size_t i = 0; i < world->numViews; ++i) {
+ if (world->views[i] == view) {
+ if (i == world->numViews - 1) {
+ world->views[i] = NULL;
+ } else {
+ memmove(world->views + i,
+ world->views + i + 1,
+ sizeof(PuglView*) * (world->numViews - i - 1));
+ world->views[world->numViews - 1] = NULL;
+ }
+ --world->numViews;
+ }
+ }
+
+ free(view->title);
+ free(view->clipboard.data);
+ puglFreeViewInternals(view);
+ free(view);
}
PuglWorld*
puglGetWorld(PuglView* view)
{
- return view->world;
+ return view->world;
}
PuglStatus
puglSetViewHint(PuglView* view, PuglViewHint hint, int value)
{
- if (value == PUGL_DONT_CARE) {
- switch (hint) {
- case PUGL_USE_COMPAT_PROFILE:
- case PUGL_USE_DEBUG_CONTEXT:
- case PUGL_CONTEXT_VERSION_MAJOR:
- case PUGL_CONTEXT_VERSION_MINOR:
- case PUGL_SWAP_INTERVAL:
- return PUGL_BAD_PARAMETER;
- default:
- break;
- }
- }
+ if (value == PUGL_DONT_CARE) {
+ switch (hint) {
+ case PUGL_USE_COMPAT_PROFILE:
+ case PUGL_USE_DEBUG_CONTEXT:
+ case PUGL_CONTEXT_VERSION_MAJOR:
+ case PUGL_CONTEXT_VERSION_MINOR:
+ case PUGL_SWAP_INTERVAL:
+ return PUGL_BAD_PARAMETER;
+ default:
+ break;
+ }
+ }
- if (hint < PUGL_NUM_VIEW_HINTS) {
- view->hints[hint] = value;
- return PUGL_SUCCESS;
- }
+ if (hint < PUGL_NUM_VIEW_HINTS) {
+ view->hints[hint] = value;
+ return PUGL_SUCCESS;
+ }
- return PUGL_BAD_PARAMETER;
+ return PUGL_BAD_PARAMETER;
}
int
puglGetViewHint(const PuglView* view, PuglViewHint hint)
{
- if (hint < PUGL_NUM_VIEW_HINTS) {
- return view->hints[hint];
- }
+ if (hint < PUGL_NUM_VIEW_HINTS) {
+ return view->hints[hint];
+ }
- return PUGL_DONT_CARE;
+ return PUGL_DONT_CARE;
}
PuglStatus
puglSetParentWindow(PuglView* view, PuglNativeView parent)
{
- view->parent = parent;
- return PUGL_SUCCESS;
+ view->parent = parent;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetBackend(PuglView* view, const PuglBackend* backend)
{
- view->backend = backend;
- return PUGL_SUCCESS;
+ view->backend = backend;
+ return PUGL_SUCCESS;
}
void
puglSetHandle(PuglView* view, PuglHandle handle)
{
- view->handle = handle;
+ view->handle = handle;
}
PuglHandle
puglGetHandle(PuglView* view)
{
- return view->handle;
+ return view->handle;
}
bool
puglGetVisible(const PuglView* view)
{
- return view->visible;
+ return view->visible;
}
PuglRect
puglGetFrame(const PuglView* view)
{
- return view->frame;
+ return view->frame;
}
void*
puglGetContext(PuglView* view)
{
- return view->backend->getContext(view);
+ return view->backend->getContext(view);
}
#ifndef PUGL_DISABLE_DEPRECATED
@@ -275,25 +276,25 @@ puglGetContext(PuglView* view)
PuglStatus
puglPollEvents(PuglWorld* world, double timeout)
{
- return puglUpdate(world, timeout);
+ return puglUpdate(world, timeout);
}
PuglStatus
puglDispatchEvents(PuglWorld* world)
{
- return puglUpdate(world, 0.0);
+ return puglUpdate(world, 0.0);
}
PuglStatus
puglShowWindow(PuglView* view)
{
- return puglShow(view);
+ return puglShow(view);
}
PuglStatus
puglHideWindow(PuglView* view)
{
- return puglHide(view);
+ return puglHide(view);
}
#endif
@@ -301,112 +302,116 @@ puglHideWindow(PuglView* view)
PuglStatus
puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc)
{
- view->eventFunc = eventFunc;
- return PUGL_SUCCESS;
+ view->eventFunc = eventFunc;
+ return PUGL_SUCCESS;
}
/// Return the code point for buf, or the replacement character on error
uint32_t
puglDecodeUTF8(const uint8_t* buf)
{
-#define FAIL_IF(cond) do { if (cond) return 0xFFFD; } while (0)
-
- // http://en.wikipedia.org/wiki/UTF-8
-
- if (buf[0] < 0x80) {
- return buf[0];
- } else if (buf[0] < 0xC2) {
- return 0xFFFD;
- } else if (buf[0] < 0xE0) {
- FAIL_IF((buf[1] & 0xC0u) != 0x80);
- return ((uint32_t)buf[0] << 6u) + buf[1] - 0x3080u;
- } else if (buf[0] < 0xF0) {
- FAIL_IF((buf[1] & 0xC0u) != 0x80);
- FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0);
- FAIL_IF((buf[2] & 0xC0u) != 0x80);
- return ((uint32_t)buf[0] << 12u) + //
- ((uint32_t)buf[1] << 6u) + //
- ((uint32_t)buf[2] - 0xE2080u);
- } else if (buf[0] < 0xF5) {
- FAIL_IF((buf[1] & 0xC0u) != 0x80);
- FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90);
- FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90);
- FAIL_IF((buf[2] & 0xC0u) != 0x80u);
- FAIL_IF((buf[3] & 0xC0u) != 0x80u);
- return (((uint32_t)buf[0] << 18u) + //
- ((uint32_t)buf[1] << 12u) + //
- ((uint32_t)buf[2] << 6u) + //
- ((uint32_t)buf[3] - 0x3C82080u));
- }
- return 0xFFFD;
+#define FAIL_IF(cond) \
+ do { \
+ if (cond) \
+ return 0xFFFD; \
+ } while (0)
+
+ // http://en.wikipedia.org/wiki/UTF-8
+
+ if (buf[0] < 0x80) {
+ return buf[0];
+ } else if (buf[0] < 0xC2) {
+ return 0xFFFD;
+ } else if (buf[0] < 0xE0) {
+ FAIL_IF((buf[1] & 0xC0u) != 0x80);
+ return ((uint32_t)buf[0] << 6u) + buf[1] - 0x3080u;
+ } else if (buf[0] < 0xF0) {
+ FAIL_IF((buf[1] & 0xC0u) != 0x80);
+ FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0);
+ FAIL_IF((buf[2] & 0xC0u) != 0x80);
+ return ((uint32_t)buf[0] << 12u) + //
+ ((uint32_t)buf[1] << 6u) + //
+ ((uint32_t)buf[2] - 0xE2080u);
+ } else if (buf[0] < 0xF5) {
+ FAIL_IF((buf[1] & 0xC0u) != 0x80);
+ FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90);
+ FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90);
+ FAIL_IF((buf[2] & 0xC0u) != 0x80u);
+ FAIL_IF((buf[3] & 0xC0u) != 0x80u);
+ return (((uint32_t)buf[0] << 18u) + //
+ ((uint32_t)buf[1] << 12u) + //
+ ((uint32_t)buf[2] << 6u) + //
+ ((uint32_t)buf[3] - 0x3C82080u));
+ }
+ return 0xFFFD;
}
static inline bool
puglMustConfigure(PuglView* view, const PuglEventConfigure* configure)
{
- return memcmp(configure, &view->lastConfigure, sizeof(PuglEventConfigure));
+ return memcmp(configure, &view->lastConfigure, sizeof(PuglEventConfigure));
}
void
puglDispatchSimpleEvent(PuglView* view, const PuglEventType type)
{
- assert(type == PUGL_CREATE || type == PUGL_DESTROY || type == PUGL_MAP ||
- type == PUGL_UNMAP || type == PUGL_UPDATE || type == PUGL_CLOSE ||
- type == PUGL_LOOP_ENTER || type == PUGL_LOOP_LEAVE);
+ assert(type == PUGL_CREATE || type == PUGL_DESTROY || type == PUGL_MAP ||
+ type == PUGL_UNMAP || type == PUGL_UPDATE || type == PUGL_CLOSE ||
+ type == PUGL_LOOP_ENTER || type == PUGL_LOOP_LEAVE);
- const PuglEvent event = {{type, 0}};
- puglDispatchEvent(view, &event);
+ const PuglEvent event = {{type, 0}};
+ puglDispatchEvent(view, &event);
}
void
puglDispatchEventInContext(PuglView* view, const PuglEvent* event)
{
- if (event->type == PUGL_CONFIGURE) {
- view->frame.x = event->configure.x;
- view->frame.y = event->configure.y;
- view->frame.width = event->configure.width;
- view->frame.height = event->configure.height;
-
- if (puglMustConfigure(view, &event->configure)) {
- view->eventFunc(view, event);
- view->lastConfigure = event->configure;
- }
- } else if (event->type == PUGL_EXPOSE) {
- if (event->expose.width > 0 && event->expose.height > 0) {
- view->eventFunc(view, event);
- }
- } else {
- view->eventFunc(view, event);
- }
+ if (event->type == PUGL_CONFIGURE) {
+ view->frame.x = event->configure.x;
+ view->frame.y = event->configure.y;
+ view->frame.width = event->configure.width;
+ view->frame.height = event->configure.height;
+
+ if (puglMustConfigure(view, &event->configure)) {
+ view->eventFunc(view, event);
+ view->lastConfigure = event->configure;
+ }
+ } else if (event->type == PUGL_EXPOSE) {
+ if (event->expose.width > 0 && event->expose.height > 0) {
+ view->eventFunc(view, event);
+ }
+ } else {
+ view->eventFunc(view, event);
+ }
}
void
puglDispatchEvent(PuglView* view, const PuglEvent* event)
{
- switch (event->type) {
- case PUGL_NOTHING:
- break;
- case PUGL_CREATE:
- case PUGL_DESTROY:
- view->backend->enter(view, NULL);
- view->eventFunc(view, event);
- view->backend->leave(view, NULL);
- break;
- case PUGL_CONFIGURE:
- if (puglMustConfigure(view, &event->configure)) {
- view->backend->enter(view, NULL);
- puglDispatchEventInContext(view, event);
- view->backend->leave(view, NULL);
- }
- break;
- case PUGL_EXPOSE:
- view->backend->enter(view, &event->expose);
- puglDispatchEventInContext(view, event);
- view->backend->leave(view, &event->expose);
- break;
- default:
- view->eventFunc(view, event);
- }
+ switch (event->type) {
+ case PUGL_NOTHING:
+ break;
+ case PUGL_CREATE:
+ case PUGL_DESTROY:
+ view->backend->enter(view, NULL);
+ view->eventFunc(view, event);
+ view->backend->leave(view, NULL);
+ break;
+ case PUGL_CONFIGURE:
+ if (puglMustConfigure(view, &event->configure)) {
+ view->backend->enter(view, NULL);
+ puglDispatchEventInContext(view, event);
+ view->backend->leave(view, NULL);
+ }
+ break;
+ case PUGL_EXPOSE:
+ view->backend->enter(view, &event->expose);
+ puglDispatchEventInContext(view, event);
+ view->backend->leave(view, &event->expose);
+ break;
+ default:
+ view->eventFunc(view, event);
+ }
}
const void*
@@ -414,15 +419,15 @@ puglGetInternalClipboard(const PuglView* const view,
const char** const type,
size_t* const len)
{
- if (len) {
- *len = view->clipboard.len;
- }
+ if (len) {
+ *len = view->clipboard.len;
+ }
- if (type) {
- *type = "text/plain";
- }
+ if (type) {
+ *type = "text/plain";
+ }
- return view->clipboard.data;
+ return view->clipboard.data;
}
PuglStatus
@@ -431,11 +436,10 @@ puglSetInternalClipboard(PuglView* const view,
const void* const data,
const size_t len)
{
- if (type && strcmp(type, "text/plain")) {
- return PUGL_UNSUPPORTED_TYPE;
- }
+ if (type && strcmp(type, "text/plain")) {
+ return PUGL_UNSUPPORTED_TYPE;
+ }
- puglSetBlob(&view->clipboard, data, len);
- return PUGL_SUCCESS;
+ puglSetBlob(&view->clipboard, data, len);
+ return PUGL_SUCCESS;
}
-
diff --git a/src/mac.h b/src/mac.h
index d17c74f..35e6e0d 100644
--- a/src/mac.h
+++ b/src/mac.h
@@ -38,18 +38,18 @@
@end
struct PuglWorldInternalsImpl {
- NSApplication* app;
- NSAutoreleasePool* autoreleasePool;
+ NSApplication* app;
+ NSAutoreleasePool* autoreleasePool;
};
struct PuglInternalsImpl {
- NSApplication* app;
- PuglWrapperView* wrapperView;
- NSView* drawView;
- NSCursor* cursor;
- PuglWindow* window;
- uint32_t mods;
- bool mouseTracked;
+ NSApplication* app;
+ PuglWrapperView* wrapperView;
+ NSView* drawView;
+ NSCursor* cursor;
+ PuglWindow* window;
+ uint32_t mods;
+ bool mouseTracked;
};
#endif // PUGL_DETAIL_MAC_H
diff --git a/src/mac.m b/src/mac.m
index adac2a5..090dd0f 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -40,85 +40,85 @@ typedef NSUInteger NSWindowStyleMask;
static NSRect
rectToScreen(NSScreen* screen, NSRect rect)
{
- const double screenHeight = [screen frame].size.height;
+ const double screenHeight = [screen frame].size.height;
- rect.origin.y = screenHeight - rect.origin.y - rect.size.height;
- return rect;
+ rect.origin.y = screenHeight - rect.origin.y - rect.size.height;
+ return rect;
}
static NSScreen*
viewScreen(PuglView* view)
{
- return view->impl->window ? [view->impl->window screen] : [NSScreen mainScreen];
+ return view->impl->window ? [view->impl->window screen]
+ : [NSScreen mainScreen];
}
static NSRect
nsRectToPoints(PuglView* view, const NSRect rect)
{
- const double scaleFactor = [viewScreen(view) backingScaleFactor];
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
- return NSMakeRect(rect.origin.x / scaleFactor,
- rect.origin.y / scaleFactor,
- rect.size.width / scaleFactor,
- rect.size.height / scaleFactor);
+ return NSMakeRect(rect.origin.x / scaleFactor,
+ rect.origin.y / scaleFactor,
+ rect.size.width / scaleFactor,
+ rect.size.height / scaleFactor);
}
static NSRect
nsRectFromPoints(PuglView* view, const NSRect rect)
{
- const double scaleFactor = [viewScreen(view) backingScaleFactor];
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
- return NSMakeRect(rect.origin.x * scaleFactor,
- rect.origin.y * scaleFactor,
- rect.size.width * scaleFactor,
- rect.size.height * scaleFactor);
+ return NSMakeRect(rect.origin.x * scaleFactor,
+ rect.origin.y * scaleFactor,
+ rect.size.width * scaleFactor,
+ rect.size.height * scaleFactor);
}
static NSPoint
nsPointFromPoints(PuglView* view, const NSPoint point)
{
- const double scaleFactor = [viewScreen(view) backingScaleFactor];
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
- return NSMakePoint(point.x * scaleFactor, point.y * scaleFactor);
+ return NSMakePoint(point.x * scaleFactor, point.y * scaleFactor);
}
static NSRect
rectToNsRect(const PuglRect rect)
{
- return NSMakeRect(rect.x, rect.y, rect.width, rect.height);
+ return NSMakeRect(rect.x, rect.y, rect.width, rect.height);
}
static NSSize
sizePoints(PuglView* view, const double width, const double height)
{
- const double scaleFactor = [viewScreen(view) backingScaleFactor];
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
- return NSMakeSize(width / scaleFactor, height / scaleFactor);
+ return NSMakeSize(width / scaleFactor, height / scaleFactor);
}
static void
updateViewRect(PuglView* view)
{
- NSWindow* const window = view->impl->window;
- if (window) {
- const NSRect screenFramePt = [[NSScreen mainScreen] frame];
- const NSRect screenFramePx = nsRectFromPoints(view, screenFramePt);
- const NSRect framePt = [window frame];
- const NSRect contentPt = [window contentRectForFrameRect:framePt];
- const NSRect contentPx = nsRectFromPoints(view, contentPt);
- const double screenHeight = screenFramePx.size.height;
+ NSWindow* const window = view->impl->window;
+ if (window) {
+ const NSRect screenFramePt = [[NSScreen mainScreen] frame];
+ const NSRect screenFramePx = nsRectFromPoints(view, screenFramePt);
+ const NSRect framePt = [window frame];
+ const NSRect contentPt = [window contentRectForFrameRect:framePt];
+ const NSRect contentPx = nsRectFromPoints(view, contentPt);
+ const double screenHeight = screenFramePx.size.height;
- view->frame.x = contentPx.origin.x;
- view->frame.y = screenHeight - contentPx.origin.y - contentPx.size.height;
- view->frame.width = contentPx.size.width;
- view->frame.height = contentPx.size.height;
- }
+ view->frame.x = contentPx.origin.x;
+ view->frame.y = screenHeight - contentPx.origin.y - contentPx.size.height;
+ view->frame.width = contentPx.size.width;
+ view->frame.height = contentPx.size.height;
+ }
}
-@implementation PuglWindow
-{
+@implementation PuglWindow {
@public
- PuglView* puglview;
+ PuglView* puglview;
}
- (id)initWithContentRect:(NSRect)contentRect
@@ -126,617 +126,638 @@ updateViewRect(PuglView* view)
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag
{
- (void)flag;
+ (void)flag;
- NSWindow* result = [super initWithContentRect:contentRect
- styleMask:aStyle
- backing:bufferingType
- defer:NO];
+ NSWindow* result = [super initWithContentRect:contentRect
+ styleMask:aStyle
+ backing:bufferingType
+ defer:NO];
- [result setAcceptsMouseMovedEvents:YES];
- return (PuglWindow*)result;
+ [result setAcceptsMouseMovedEvents:YES];
+ return (PuglWindow*)result;
}
- (void)setPuglview:(PuglView*)view
{
- puglview = view;
+ puglview = view;
- [self
- setContentSize:sizePoints(view, view->frame.width, view->frame.height)];
+ [self setContentSize:sizePoints(view, view->frame.width, view->frame.height)];
}
- (BOOL)canBecomeKeyWindow
{
- return YES;
+ return YES;
}
- (BOOL)canBecomeMainWindow
{
- return YES;
+ return YES;
}
- (void)setIsVisible:(BOOL)flag
{
- if (flag && !puglview->visible) {
- const PuglEventConfigure ev = {
- PUGL_CONFIGURE,
- 0,
- puglview->frame.x,
- puglview->frame.y,
- puglview->frame.width,
- puglview->frame.height,
- };
+ if (flag && !puglview->visible) {
+ const PuglEventConfigure ev = {
+ PUGL_CONFIGURE,
+ 0,
+ puglview->frame.x,
+ puglview->frame.y,
+ puglview->frame.width,
+ puglview->frame.height,
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
- puglDispatchSimpleEvent(puglview, PUGL_MAP);
- } else if (!flag && puglview->visible) {
- puglDispatchSimpleEvent(puglview, PUGL_UNMAP);
- }
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchSimpleEvent(puglview, PUGL_MAP);
+ } else if (!flag && puglview->visible) {
+ puglDispatchSimpleEvent(puglview, PUGL_UNMAP);
+ }
- puglview->visible = flag;
+ puglview->visible = flag;
- [super setIsVisible:flag];
+ [super setIsVisible:flag];
}
@end
-@implementation PuglWrapperView
-{
+@implementation PuglWrapperView {
@public
- PuglView* puglview;
- NSTrackingArea* trackingArea;
- NSMutableAttributedString* markedText;
- NSMutableDictionary* userTimers;
- bool reshaped;
+ PuglView* puglview;
+ NSTrackingArea* trackingArea;
+ NSMutableAttributedString* markedText;
+ NSMutableDictionary* userTimers;
+ bool reshaped;
}
- (void)dispatchExpose:(NSRect)rect
{
- const double scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
+ const double scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
- if (reshaped) {
- updateViewRect(puglview);
+ if (reshaped) {
+ updateViewRect(puglview);
- const PuglEventConfigure ev = {
- PUGL_CONFIGURE,
- 0,
- puglview->frame.x,
- puglview->frame.y,
- puglview->frame.width,
- puglview->frame.height,
- };
+ const PuglEventConfigure ev = {
+ PUGL_CONFIGURE,
+ 0,
+ puglview->frame.x,
+ puglview->frame.y,
+ puglview->frame.width,
+ puglview->frame.height,
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
- reshaped = false;
- }
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ reshaped = false;
+ }
- if (![[puglview->impl->drawView window] isVisible]) {
- return;
- }
+ if (![[puglview->impl->drawView window] isVisible]) {
+ return;
+ }
- const PuglEventExpose ev = {
- PUGL_EXPOSE,
- 0,
- rect.origin.x * scaleFactor,
- rect.origin.y * scaleFactor,
- rect.size.width * scaleFactor,
- rect.size.height * scaleFactor,
- };
+ const PuglEventExpose ev = {
+ PUGL_EXPOSE,
+ 0,
+ rect.origin.x * scaleFactor,
+ rect.origin.y * scaleFactor,
+ rect.size.width * scaleFactor,
+ rect.size.height * scaleFactor,
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (NSSize)intrinsicContentSize
{
- if (puglview->defaultWidth || puglview->defaultHeight) {
- return sizePoints(puglview,
- puglview->defaultWidth,
- puglview->defaultHeight);
- }
+ if (puglview->defaultWidth || puglview->defaultHeight) {
+ return sizePoints(
+ puglview, puglview->defaultWidth, puglview->defaultHeight);
+ }
- return NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
+ return NSMakeSize(NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric);
}
- (BOOL)isFlipped
{
- return YES;
+ return YES;
}
- (BOOL)acceptsFirstResponder
{
- return YES;
+ return YES;
}
- (void)setReshaped
{
- reshaped = true;
+ reshaped = true;
}
static uint32_t
getModifiers(const NSEvent* const ev)
{
- const NSEventModifierFlags modifierFlags = [ev modifierFlags];
+ const NSEventModifierFlags modifierFlags = [ev modifierFlags];
- return (((modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0) |
- ((modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0) |
- ((modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0) |
- ((modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0));
+ return (((modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0) |
+ ((modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0) |
+ ((modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0) |
+ ((modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0));
}
static PuglKey
keySymToSpecial(const NSEvent* const ev)
{
- NSString* chars = [ev charactersIgnoringModifiers];
- if ([chars length] == 1) {
- switch ([chars characterAtIndex:0]) {
- case NSF1FunctionKey: return PUGL_KEY_F1;
- case NSF2FunctionKey: return PUGL_KEY_F2;
- case NSF3FunctionKey: return PUGL_KEY_F3;
- case NSF4FunctionKey: return PUGL_KEY_F4;
- case NSF5FunctionKey: return PUGL_KEY_F5;
- case NSF6FunctionKey: return PUGL_KEY_F6;
- case NSF7FunctionKey: return PUGL_KEY_F7;
- case NSF8FunctionKey: return PUGL_KEY_F8;
- case NSF9FunctionKey: return PUGL_KEY_F9;
- case NSF10FunctionKey: return PUGL_KEY_F10;
- case NSF11FunctionKey: return PUGL_KEY_F11;
- case NSF12FunctionKey: return PUGL_KEY_F12;
- case NSDeleteCharacter: return PUGL_KEY_BACKSPACE;
- case NSDeleteFunctionKey: return PUGL_KEY_DELETE;
- case NSLeftArrowFunctionKey: return PUGL_KEY_LEFT;
- case NSUpArrowFunctionKey: return PUGL_KEY_UP;
- case NSRightArrowFunctionKey: return PUGL_KEY_RIGHT;
- case NSDownArrowFunctionKey: return PUGL_KEY_DOWN;
- case NSPageUpFunctionKey: return PUGL_KEY_PAGE_UP;
- case NSPageDownFunctionKey: return PUGL_KEY_PAGE_DOWN;
- case NSHomeFunctionKey: return PUGL_KEY_HOME;
- case NSEndFunctionKey: return PUGL_KEY_END;
- case NSInsertFunctionKey: return PUGL_KEY_INSERT;
- case NSMenuFunctionKey: return PUGL_KEY_MENU;
- case NSScrollLockFunctionKey: return PUGL_KEY_SCROLL_LOCK;
- case NSClearLineFunctionKey: return PUGL_KEY_NUM_LOCK;
- case NSPrintScreenFunctionKey: return PUGL_KEY_PRINT_SCREEN;
- case NSPauseFunctionKey: return PUGL_KEY_PAUSE;
- }
- // SHIFT, CTRL, ALT, and SUPER are handled in [flagsChanged]
- }
- return (PuglKey)0;
+ NSString* chars = [ev charactersIgnoringModifiers];
+ if ([chars length] == 1) {
+ switch ([chars characterAtIndex:0]) {
+ case NSF1FunctionKey:
+ return PUGL_KEY_F1;
+ case NSF2FunctionKey:
+ return PUGL_KEY_F2;
+ case NSF3FunctionKey:
+ return PUGL_KEY_F3;
+ case NSF4FunctionKey:
+ return PUGL_KEY_F4;
+ case NSF5FunctionKey:
+ return PUGL_KEY_F5;
+ case NSF6FunctionKey:
+ return PUGL_KEY_F6;
+ case NSF7FunctionKey:
+ return PUGL_KEY_F7;
+ case NSF8FunctionKey:
+ return PUGL_KEY_F8;
+ case NSF9FunctionKey:
+ return PUGL_KEY_F9;
+ case NSF10FunctionKey:
+ return PUGL_KEY_F10;
+ case NSF11FunctionKey:
+ return PUGL_KEY_F11;
+ case NSF12FunctionKey:
+ return PUGL_KEY_F12;
+ case NSDeleteCharacter:
+ return PUGL_KEY_BACKSPACE;
+ case NSDeleteFunctionKey:
+ return PUGL_KEY_DELETE;
+ case NSLeftArrowFunctionKey:
+ return PUGL_KEY_LEFT;
+ case NSUpArrowFunctionKey:
+ return PUGL_KEY_UP;
+ case NSRightArrowFunctionKey:
+ return PUGL_KEY_RIGHT;
+ case NSDownArrowFunctionKey:
+ return PUGL_KEY_DOWN;
+ case NSPageUpFunctionKey:
+ return PUGL_KEY_PAGE_UP;
+ case NSPageDownFunctionKey:
+ return PUGL_KEY_PAGE_DOWN;
+ case NSHomeFunctionKey:
+ return PUGL_KEY_HOME;
+ case NSEndFunctionKey:
+ return PUGL_KEY_END;
+ case NSInsertFunctionKey:
+ return PUGL_KEY_INSERT;
+ case NSMenuFunctionKey:
+ return PUGL_KEY_MENU;
+ case NSScrollLockFunctionKey:
+ return PUGL_KEY_SCROLL_LOCK;
+ case NSClearLineFunctionKey:
+ return PUGL_KEY_NUM_LOCK;
+ case NSPrintScreenFunctionKey:
+ return PUGL_KEY_PRINT_SCREEN;
+ case NSPauseFunctionKey:
+ return PUGL_KEY_PAUSE;
+ }
+ // SHIFT, CTRL, ALT, and SUPER are handled in [flagsChanged]
+ }
+ return (PuglKey)0;
}
- (void)updateTrackingAreas
{
- if (trackingArea != nil) {
- [self removeTrackingArea:trackingArea];
- [trackingArea release];
- }
+ 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];
- [super updateTrackingAreas];
+ const int opts = (NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved |
+ NSTrackingActiveAlways);
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:opts
+ owner:self
+ userInfo:nil];
+ [self addTrackingArea:trackingArea];
+ [super updateTrackingAreas];
}
- (NSPoint)eventLocation:(NSEvent*)event
{
- return nsPointFromPoints(puglview,
- [self convertPoint:[event locationInWindow]
- fromView:nil]);
+ return nsPointFromPoints(
+ puglview, [self convertPoint:[event locationInWindow] fromView:nil]);
}
static void
handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
{
- const NSPoint wloc = [view eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventCrossing ev = {
- type,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- PUGL_CROSSING_NORMAL,
- };
+ const NSPoint wloc = [view eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglEventCrossing ev = {
+ type,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ PUGL_CROSSING_NORMAL,
+ };
- puglDispatchEvent(view->puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(view->puglview, (const PuglEvent*)&ev);
}
- (void)mouseEntered:(NSEvent*)event
{
- handleCrossing(self, event, PUGL_POINTER_IN);
- [puglview->impl->cursor set];
- puglview->impl->mouseTracked = true;
+ handleCrossing(self, event, PUGL_POINTER_IN);
+ [puglview->impl->cursor set];
+ puglview->impl->mouseTracked = true;
}
- (void)mouseExited:(NSEvent*)event
{
- [[NSCursor arrowCursor] set];
- handleCrossing(self, event, PUGL_POINTER_OUT);
- puglview->impl->mouseTracked = false;
+ [[NSCursor arrowCursor] set];
+ handleCrossing(self, event, PUGL_POINTER_OUT);
+ puglview->impl->mouseTracked = false;
}
- (void)cursorUpdate:(NSEvent*)event
{
- (void)event;
- [puglview->impl->cursor set];
+ (void)event;
+ [puglview->impl->cursor set];
}
- (void)mouseMoved:(NSEvent*)event
{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventMotion ev = {
- PUGL_MOTION,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- };
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglEventMotion ev = {
+ PUGL_MOTION,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (void)mouseDragged:(NSEvent*)event
{
- [self mouseMoved: event];
+ [self mouseMoved:event];
}
- (void)rightMouseDragged:(NSEvent*)event
{
- [self mouseMoved: event];
+ [self mouseMoved:event];
}
- (void)otherMouseDragged:(NSEvent*)event
{
- [self mouseMoved: event];
+ [self mouseMoved:event];
}
- (void)mouseDown:(NSEvent*)event
{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventButton ev = {
- PUGL_BUTTON_PRESS,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- (uint32_t)[event buttonNumber] + 1,
- };
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglEventButton ev = {
+ PUGL_BUTTON_PRESS,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ (uint32_t)[event buttonNumber] + 1,
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (void)mouseUp:(NSEvent*)event
{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglEventButton ev = {
- PUGL_BUTTON_RELEASE,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- (uint32_t)[event buttonNumber] + 1,
- };
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglEventButton ev = {
+ PUGL_BUTTON_RELEASE,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ (uint32_t)[event buttonNumber] + 1,
+ };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (void)rightMouseDown:(NSEvent*)event
{
- [self mouseDown: event];
+ [self mouseDown:event];
}
- (void)rightMouseUp:(NSEvent*)event
{
- [self mouseUp: event];
+ [self mouseUp:event];
}
- (void)otherMouseDown:(NSEvent*)event
{
- [self mouseDown: event];
+ [self mouseDown:event];
}
- (void)otherMouseUp:(NSEvent*)event
{
- [self mouseUp: event];
+ [self mouseUp:event];
}
- (void)scrollWheel:(NSEvent*)event
{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const double dx = [event scrollingDeltaX];
- const double dy = [event scrollingDeltaY];
- const PuglScrollDirection dir =
- ((dx == 0.0 && dy > 0.0)
- ? PUGL_SCROLL_UP
- : ((dx == 0.0 && dy < 0.0)
- ? PUGL_SCROLL_DOWN
- : ((dy == 0.0 && dx > 0.0)
- ? PUGL_SCROLL_RIGHT
- : ((dy == 0.0 && dx < 0.0) ? PUGL_SCROLL_LEFT
- : PUGL_SCROLL_SMOOTH))));
-
- const PuglEventScroll ev = {
- PUGL_SCROLL,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- [event hasPreciseScrollingDeltas] ? PUGL_SCROLL_SMOOTH : dir,
- dx,
- dy,
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const double dx = [event scrollingDeltaX];
+ const double dy = [event scrollingDeltaY];
+ const PuglScrollDirection dir =
+ ((dx == 0.0 && dy > 0.0)
+ ? PUGL_SCROLL_UP
+ : ((dx == 0.0 && dy < 0.0)
+ ? PUGL_SCROLL_DOWN
+ : ((dy == 0.0 && dx > 0.0)
+ ? PUGL_SCROLL_RIGHT
+ : ((dy == 0.0 && dx < 0.0) ? PUGL_SCROLL_LEFT
+ : PUGL_SCROLL_SMOOTH))));
+
+ const PuglEventScroll ev = {
+ PUGL_SCROLL,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ [event hasPreciseScrollingDeltas] ? PUGL_SCROLL_SMOOTH : dir,
+ dx,
+ dy,
+ };
+
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (void)keyDown:(NSEvent*)event
{
- if (puglview->hints[PUGL_IGNORE_KEY_REPEAT] && [event isARepeat]) {
- return;
- }
-
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglKey spec = keySymToSpecial(event);
- const NSString* chars = [event charactersIgnoringModifiers];
- const char* str = [[chars lowercaseString] UTF8String];
- const uint32_t code = (spec ? spec : puglDecodeUTF8((const uint8_t*)str));
-
- const PuglEventKey ev = {
- PUGL_KEY_PRESS,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- [event keyCode],
- (code != 0xFFFD) ? code : 0,
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
-
- if (!spec) {
- [self interpretKeyEvents:@[event]];
- }
+ if (puglview->hints[PUGL_IGNORE_KEY_REPEAT] && [event isARepeat]) {
+ return;
+ }
+
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglKey spec = keySymToSpecial(event);
+ const NSString* chars = [event charactersIgnoringModifiers];
+ const char* str = [[chars lowercaseString] UTF8String];
+ const uint32_t code = (spec ? spec : puglDecodeUTF8((const uint8_t*)str));
+
+ const PuglEventKey ev = {
+ PUGL_KEY_PRESS,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ [event keyCode],
+ (code != 0xFFFD) ? code : 0,
+ };
+
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+
+ if (!spec) {
+ [self interpretKeyEvents:@[event]];
+ }
}
- (void)keyUp:(NSEvent*)event
{
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- const PuglKey spec = keySymToSpecial(event);
- const NSString* chars = [event charactersIgnoringModifiers];
- const char* str = [[chars lowercaseString] UTF8String];
- const uint32_t code = (spec ? spec : puglDecodeUTF8((const uint8_t*)str));
-
- const PuglEventKey ev = {
- PUGL_KEY_RELEASE,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- [event keyCode],
- (code != 0xFFFD) ? code : 0,
- };
-
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ const PuglKey spec = keySymToSpecial(event);
+ const NSString* chars = [event charactersIgnoringModifiers];
+ const char* str = [[chars lowercaseString] UTF8String];
+ const uint32_t code = (spec ? spec : puglDecodeUTF8((const uint8_t*)str));
+
+ const PuglEventKey ev = {
+ PUGL_KEY_RELEASE,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ [event keyCode],
+ (code != 0xFFFD) ? code : 0,
+ };
+
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (BOOL)hasMarkedText
{
- return [markedText length] > 0;
+ return [markedText length] > 0;
}
- (NSRange)markedRange
{
- return (([markedText length] > 0)
- ? NSMakeRange(0, [markedText length] - 1)
- : NSMakeRange(NSNotFound, 0));
+ return (([markedText length] > 0) ? NSMakeRange(0, [markedText length] - 1)
+ : NSMakeRange(NSNotFound, 0));
}
- (NSRange)selectedRange
{
- return NSMakeRange(NSNotFound, 0);
+ return NSMakeRange(NSNotFound, 0);
}
- (void)setMarkedText:(id)string
selectedRange:(NSRange)selected
replacementRange:(NSRange)replacement
{
- (void)selected;
- (void)replacement;
- [markedText release];
- markedText = (
- [(NSObject*)string isKindOfClass:[NSAttributedString class]]
- ? [[NSMutableAttributedString alloc] initWithAttributedString:string]
- : [[NSMutableAttributedString alloc] initWithString:string]);
+ (void)selected;
+ (void)replacement;
+ [markedText release];
+ markedText =
+ ([(NSObject*)string isKindOfClass:[NSAttributedString class]]
+ ? [[NSMutableAttributedString alloc] initWithAttributedString:string]
+ : [[NSMutableAttributedString alloc] initWithString:string]);
}
- (void)unmarkText
{
- [[markedText mutableString] setString:@""];
+ [[markedText mutableString] setString:@""];
}
- (NSArray*)validAttributesForMarkedText
{
- return @[];
+ return @[];
}
- (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range
actualRange:
- (NSRangePointer)actual
+ (NSRangePointer)actual
{
- (void)range;
- (void)actual;
- return nil;
+ (void)range;
+ (void)actual;
+ return nil;
}
- (NSUInteger)characterIndexForPoint:(NSPoint)point
{
- (void)point;
- return 0;
+ (void)point;
+ return 0;
}
- (NSRect)firstRectForCharacterRange:(NSRange)range
actualRange:(NSRangePointer)actual
{
- (void)range;
- (void)actual;
+ (void)range;
+ (void)actual;
- const NSRect frame = [self bounds];
- return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);
+ const NSRect frame = [self bounds];
+ return NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0);
}
- (void)doCommandBySelector:(SEL)selector
{
- (void)selector;
+ (void)selector;
}
- (void)insertText:(id)string replacementRange:(NSRange)replacement
{
- (void)replacement;
-
- NSEvent* const event = [NSApp currentEvent];
- NSString* const characters =
- ([(NSObject*)string isKindOfClass:[NSAttributedString class]]
- ? [(NSAttributedString*)string string]
- : (NSString*)string);
-
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- for (size_t i = 0; i < [characters length]; ++i) {
- const uint32_t code = [characters characterAtIndex:i];
- char utf8[8] = {0};
- NSUInteger len = 0;
-
- [characters getBytes:utf8
- maxLength:sizeof(utf8)
- usedLength:&len
- encoding:NSUTF8StringEncoding
- options:0
- range:NSMakeRange(i, i + 1)
- remainingRange:nil];
-
- PuglEventText ev = {
- PUGL_TEXT,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- getModifiers(event),
- [event keyCode],
- code,
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- };
-
- memcpy(ev.string, utf8, len);
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
- }
+ (void)replacement;
+
+ NSEvent* const event = [NSApp currentEvent];
+ NSString* const characters =
+ ([(NSObject*)string isKindOfClass:[NSAttributedString class]]
+ ? [(NSAttributedString*)string string]
+ : (NSString*)string);
+
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ for (size_t i = 0; i < [characters length]; ++i) {
+ const uint32_t code = [characters characterAtIndex:i];
+ char utf8[8] = {0};
+ NSUInteger len = 0;
+
+ [characters getBytes:utf8
+ maxLength:sizeof(utf8)
+ usedLength:&len
+ encoding:NSUTF8StringEncoding
+ options:0
+ range:NSMakeRange(i, i + 1)
+ remainingRange:nil];
+
+ PuglEventText ev = {
+ PUGL_TEXT,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ getModifiers(event),
+ [event keyCode],
+ code,
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ };
+
+ memcpy(ev.string, utf8, len);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ }
}
- (void)flagsChanged:(NSEvent*)event
{
- const uint32_t mods = getModifiers(event);
- PuglEventType type = PUGL_NOTHING;
- PuglKey special = (PuglKey)0;
-
- if ((mods & PUGL_MOD_SHIFT) != (puglview->impl->mods & PUGL_MOD_SHIFT)) {
- type = mods & PUGL_MOD_SHIFT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- special = PUGL_KEY_SHIFT;
- } else if ((mods & PUGL_MOD_CTRL) != (puglview->impl->mods & PUGL_MOD_CTRL)) {
- type = mods & PUGL_MOD_CTRL ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- special = PUGL_KEY_CTRL;
- } else if ((mods & PUGL_MOD_ALT) != (puglview->impl->mods & PUGL_MOD_ALT)) {
- type = mods & PUGL_MOD_ALT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- special = PUGL_KEY_ALT;
- } else if ((mods & PUGL_MOD_SUPER) != (puglview->impl->mods & PUGL_MOD_SUPER)) {
- type = mods & PUGL_MOD_SUPER ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- special = PUGL_KEY_SUPER;
- }
-
- if (special != 0) {
- const NSPoint wloc = [self eventLocation:event];
- const NSPoint rloc = [NSEvent mouseLocation];
- PuglEventKey ev = {
- type,
- 0,
- [event timestamp],
- wloc.x,
- wloc.y,
- rloc.x,
- [[NSScreen mainScreen] frame].size.height - rloc.y,
- mods,
- [event keyCode],
- special
- };
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
- }
-
- puglview->impl->mods = mods;
+ const uint32_t mods = getModifiers(event);
+ PuglEventType type = PUGL_NOTHING;
+ PuglKey special = (PuglKey)0;
+
+ if ((mods & PUGL_MOD_SHIFT) != (puglview->impl->mods & PUGL_MOD_SHIFT)) {
+ type = mods & PUGL_MOD_SHIFT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
+ special = PUGL_KEY_SHIFT;
+ } else if ((mods & PUGL_MOD_CTRL) != (puglview->impl->mods & PUGL_MOD_CTRL)) {
+ type = mods & PUGL_MOD_CTRL ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
+ special = PUGL_KEY_CTRL;
+ } else if ((mods & PUGL_MOD_ALT) != (puglview->impl->mods & PUGL_MOD_ALT)) {
+ type = mods & PUGL_MOD_ALT ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
+ special = PUGL_KEY_ALT;
+ } else if ((mods & PUGL_MOD_SUPER) !=
+ (puglview->impl->mods & PUGL_MOD_SUPER)) {
+ type = mods & PUGL_MOD_SUPER ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
+ special = PUGL_KEY_SUPER;
+ }
+
+ if (special != 0) {
+ const NSPoint wloc = [self eventLocation:event];
+ const NSPoint rloc = [NSEvent mouseLocation];
+ PuglEventKey ev = {type,
+ 0,
+ [event timestamp],
+ wloc.x,
+ wloc.y,
+ rloc.x,
+ [[NSScreen mainScreen] frame].size.height - rloc.y,
+ mods,
+ [event keyCode],
+ special};
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ }
+
+ puglview->impl->mods = mods;
}
- (BOOL)preservesContentInLiveResize
{
- return NO;
+ return NO;
}
- (void)viewWillStartLiveResize
{
- puglDispatchSimpleEvent(puglview, PUGL_LOOP_ENTER);
+ puglDispatchSimpleEvent(puglview, PUGL_LOOP_ENTER);
}
- (void)viewWillDraw
{
- puglDispatchSimpleEvent(puglview, PUGL_UPDATE);
- [super viewWillDraw];
+ puglDispatchSimpleEvent(puglview, PUGL_UPDATE);
+ [super viewWillDraw];
}
- (void)resizeTick
{
- puglPostRedisplay(puglview);
+ puglPostRedisplay(puglview);
}
- (void)timerTick:(NSTimer*)userTimer
{
- const NSNumber* userInfo = userTimer.userInfo;
- const PuglEventTimer ev = {PUGL_TIMER, 0, userInfo.unsignedLongValue};
+ const NSNumber* userInfo = userTimer.userInfo;
+ const PuglEventTimer ev = {PUGL_TIMER, 0, userInfo.unsignedLongValue};
- puglDispatchEvent(puglview, (const PuglEvent*)&ev);
+ puglDispatchEvent(puglview, (const PuglEvent*)&ev);
}
- (void)viewDidEndLiveResize
{
- puglDispatchSimpleEvent(puglview, PUGL_LOOP_LEAVE);
+ puglDispatchSimpleEvent(puglview, PUGL_LOOP_LEAVE);
}
@end
@@ -747,51 +768,50 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
@end
-@implementation PuglWindowDelegate
-{
- PuglWindow* window;
+@implementation PuglWindowDelegate {
+ PuglWindow* window;
}
- (instancetype)initWithPuglWindow:(PuglWindow*)puglWindow
{
- if ((self = [super init])) {
- window = puglWindow;
- }
+ if ((self = [super init])) {
+ window = puglWindow;
+ }
- return self;
+ return self;
}
- (BOOL)windowShouldClose:(id)sender
{
- (void)sender;
+ (void)sender;
- puglDispatchSimpleEvent(window->puglview, PUGL_CLOSE);
- return YES;
+ puglDispatchSimpleEvent(window->puglview, PUGL_CLOSE);
+ return YES;
}
- (void)windowDidMove:(NSNotification*)notification
{
- (void)notification;
+ (void)notification;
- updateViewRect(window->puglview);
+ updateViewRect(window->puglview);
}
- (void)windowDidBecomeKey:(NSNotification*)notification
{
- (void)notification;
+ (void)notification;
- PuglEvent ev = {{PUGL_FOCUS_IN, 0}};
- ev.focus.mode = PUGL_CROSSING_NORMAL;
- puglDispatchEvent(window->puglview, &ev);
+ PuglEvent ev = {{PUGL_FOCUS_IN, 0}};
+ ev.focus.mode = PUGL_CROSSING_NORMAL;
+ puglDispatchEvent(window->puglview, &ev);
}
- (void)windowDidResignKey:(NSNotification*)notification
{
- (void)notification;
+ (void)notification;
- PuglEvent ev = {{PUGL_FOCUS_OUT, 0}};
- ev.focus.mode = PUGL_CROSSING_NORMAL;
- puglDispatchEvent(window->puglview, &ev);
+ PuglEvent ev = {{PUGL_FOCUS_OUT, 0}};
+ ev.focus.mode = PUGL_CROSSING_NORMAL;
+ puglDispatchEvent(window->puglview, &ev);
}
@end
@@ -799,532 +819,526 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
PuglWorldInternals*
puglInitWorldInternals(PuglWorldType type, PuglWorldFlags PUGL_UNUSED(flags))
{
- PuglWorldInternals* impl = (PuglWorldInternals*)calloc(
- 1, sizeof(PuglWorldInternals));
+ PuglWorldInternals* impl =
+ (PuglWorldInternals*)calloc(1, sizeof(PuglWorldInternals));
- impl->app = [NSApplication sharedApplication];
+ impl->app = [NSApplication sharedApplication];
- if (type == PUGL_PROGRAM) {
- impl->autoreleasePool = [NSAutoreleasePool new];
- }
+ if (type == PUGL_PROGRAM) {
+ impl->autoreleasePool = [NSAutoreleasePool new];
+ }
- return impl;
+ return impl;
}
void
puglFreeWorldInternals(PuglWorld* world)
{
- if (world->impl->autoreleasePool) {
- [world->impl->autoreleasePool drain];
- }
+ if (world->impl->autoreleasePool) {
+ [world->impl->autoreleasePool drain];
+ }
- free(world->impl);
+ free(world->impl);
}
void*
puglGetNativeWorld(PuglWorld* PUGL_UNUSED(world))
{
- return NULL;
+ return NULL;
}
PuglInternals*
puglInitViewInternals(void)
{
- PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
+ PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
- impl->cursor = [NSCursor arrowCursor];
+ impl->cursor = [NSCursor arrowCursor];
- return impl;
+ return impl;
}
static NSLayoutConstraint*
puglConstraint(id item, NSLayoutAttribute attribute, float constant)
{
- return [NSLayoutConstraint
- constraintWithItem: item
- attribute: attribute
- relatedBy: NSLayoutRelationGreaterThanOrEqual
- toItem: nil
- attribute: NSLayoutAttributeNotAnAttribute
- multiplier: 1.0
- constant: (CGFloat)constant];
+ return
+ [NSLayoutConstraint constraintWithItem:item
+ attribute:attribute
+ relatedBy:NSLayoutRelationGreaterThanOrEqual
+ toItem:nil
+ attribute:NSLayoutAttributeNotAnAttribute
+ multiplier:1.0
+ constant:(CGFloat)constant];
}
PuglStatus
puglRealize(PuglView* view)
{
- PuglInternals* impl = view->impl;
- if (impl->wrapperView) {
- return PUGL_FAILURE;
- }
-
- const NSScreen* const screen = [NSScreen mainScreen];
- const double scaleFactor = [screen backingScaleFactor];
-
- // Getting depth from the display mode seems tedious, just set usual values
- if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_RED_BITS] = 8;
- }
- if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_BLUE_BITS] = 8;
- }
- if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_GREEN_BITS] = 8;
- }
- if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_ALPHA_BITS] = 8;
- }
-
- CGDirectDisplayID displayId = CGMainDisplayID();
- CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
-
- // Try to get refresh rate from mode (usually fails)
- view->hints[PUGL_REFRESH_RATE] = (int)CGDisplayModeGetRefreshRate(mode);
-
- CGDisplayModeRelease(mode);
- if (view->hints[PUGL_REFRESH_RATE] == 0) {
- // Get refresh rate from a display link
- // TODO: Keep and actually use the display link for something?
- CVDisplayLinkRef link;
- CVDisplayLinkCreateWithCGDisplay(displayId, &link);
-
- const CVTime p = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
- const double r = p.timeScale / (double)p.timeValue;
- view->hints[PUGL_REFRESH_RATE] = (int)lrint(r);
-
- CVDisplayLinkRelease(link);
- }
-
- if (view->frame.width == 0.0 && view->frame.height == 0.0) {
- if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
- return PUGL_BAD_CONFIGURATION;
- }
-
- const double screenWidthPx = [screen frame].size.width * scaleFactor;
- const double screenHeightPx = [screen frame].size.height * scaleFactor;
-
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
- view->frame.x = screenWidthPx / 2.0 - view->frame.width / 2.0;
- view->frame.y = screenHeightPx / 2.0 - view->frame.height / 2.0;
- }
-
- const NSRect framePx = rectToNsRect(view->frame);
- const NSRect framePt = NSMakeRect(framePx.origin.x / scaleFactor,
- framePx.origin.y / scaleFactor,
- framePx.size.width / scaleFactor,
- framePx.size.height / scaleFactor);
-
- // Create wrapper view to handle input
- impl->wrapperView = [PuglWrapperView alloc];
- impl->wrapperView->puglview = view;
- impl->wrapperView->userTimers = [[NSMutableDictionary alloc] init];
- impl->wrapperView->markedText = [[NSMutableAttributedString alloc] init];
- [impl->wrapperView setAutoresizesSubviews:YES];
- [impl->wrapperView initWithFrame:framePt];
- [impl->wrapperView addConstraint:
- puglConstraint(impl->wrapperView, NSLayoutAttributeWidth, view->minWidth)];
- [impl->wrapperView addConstraint:
- puglConstraint(impl->wrapperView, NSLayoutAttributeHeight, view->minHeight)];
-
- // Create draw view to be rendered to
- PuglStatus st = PUGL_SUCCESS;
- if ((st = view->backend->configure(view)) ||
- (st = view->backend->create(view))) {
- return st;
- }
-
- // Add draw view to wrapper view
- [impl->wrapperView addSubview:impl->drawView];
- [impl->wrapperView setHidden:NO];
- [impl->drawView setHidden:NO];
-
- if (view->parent) {
- NSView* pview = (NSView*)view->parent;
- [pview addSubview:impl->wrapperView];
- [impl->drawView setHidden:NO];
- [[impl->drawView window] makeFirstResponder:impl->wrapperView];
- } else {
- unsigned style = (NSClosableWindowMask |
- NSTitledWindowMask |
- NSMiniaturizableWindowMask );
- if (view->hints[PUGL_RESIZABLE]) {
- style |= NSResizableWindowMask;
- }
-
- PuglWindow* window = [[[PuglWindow alloc]
- initWithContentRect:rectToScreen([NSScreen mainScreen], framePt)
- styleMask:style
- backing:NSBackingStoreBuffered
- defer:NO
- ] retain];
- [window setPuglview:view];
-
- if (view->title) {
- NSString* titleString = [[NSString alloc]
- initWithBytes:view->title
- length:strlen(view->title)
- encoding:NSUTF8StringEncoding];
-
- [window setTitle:titleString];
- }
-
- if (view->minWidth || view->minHeight) {
- [window setContentMinSize:sizePoints(view,
- view->minWidth,
- view->minHeight)];
- }
- impl->window = window;
-
- ((NSWindow*)window).delegate = [[PuglWindowDelegate alloc]
- initWithPuglWindow:window];
-
- if (view->minAspectX && view->minAspectY) {
- [window setContentAspectRatio:sizePoints(view,
- view->minAspectX,
- view->minAspectY)];
- }
-
- puglSetFrame(view, view->frame);
-
- [window setContentView:impl->wrapperView];
- [view->world->impl->app activateIgnoringOtherApps:YES];
- [window makeFirstResponder:impl->wrapperView];
- [window makeKeyAndOrderFront:window];
- [impl->window setIsVisible:NO];
- }
-
- [impl->wrapperView updateTrackingAreas];
-
- puglDispatchSimpleEvent(view, PUGL_CREATE);
-
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ if (impl->wrapperView) {
+ return PUGL_FAILURE;
+ }
+
+ const NSScreen* const screen = [NSScreen mainScreen];
+ const double scaleFactor = [screen backingScaleFactor];
+
+ // Getting depth from the display mode seems tedious, just set usual values
+ if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_RED_BITS] = 8;
+ }
+ if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_BLUE_BITS] = 8;
+ }
+ if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_GREEN_BITS] = 8;
+ }
+ if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_ALPHA_BITS] = 8;
+ }
+
+ CGDirectDisplayID displayId = CGMainDisplayID();
+ CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
+
+ // Try to get refresh rate from mode (usually fails)
+ view->hints[PUGL_REFRESH_RATE] = (int)CGDisplayModeGetRefreshRate(mode);
+
+ CGDisplayModeRelease(mode);
+ if (view->hints[PUGL_REFRESH_RATE] == 0) {
+ // Get refresh rate from a display link
+ // TODO: Keep and actually use the display link for something?
+ CVDisplayLinkRef link;
+ CVDisplayLinkCreateWithCGDisplay(displayId, &link);
+
+ const CVTime p = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
+ const double r = p.timeScale / (double)p.timeValue;
+ view->hints[PUGL_REFRESH_RATE] = (int)lrint(r);
+
+ CVDisplayLinkRelease(link);
+ }
+
+ if (view->frame.width == 0.0 && view->frame.height == 0.0) {
+ if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
+ return PUGL_BAD_CONFIGURATION;
+ }
+
+ const double screenWidthPx = [screen frame].size.width * scaleFactor;
+ const double screenHeightPx = [screen frame].size.height * scaleFactor;
+
+ view->frame.width = view->defaultWidth;
+ view->frame.height = view->defaultHeight;
+ view->frame.x = screenWidthPx / 2.0 - view->frame.width / 2.0;
+ view->frame.y = screenHeightPx / 2.0 - view->frame.height / 2.0;
+ }
+
+ const NSRect framePx = rectToNsRect(view->frame);
+ const NSRect framePt = NSMakeRect(framePx.origin.x / scaleFactor,
+ framePx.origin.y / scaleFactor,
+ framePx.size.width / scaleFactor,
+ framePx.size.height / scaleFactor);
+
+ // Create wrapper view to handle input
+ impl->wrapperView = [PuglWrapperView alloc];
+ impl->wrapperView->puglview = view;
+ impl->wrapperView->userTimers = [[NSMutableDictionary alloc] init];
+ impl->wrapperView->markedText = [[NSMutableAttributedString alloc] init];
+ [impl->wrapperView setAutoresizesSubviews:YES];
+ [impl->wrapperView initWithFrame:framePt];
+ [impl->wrapperView addConstraint:puglConstraint(impl->wrapperView,
+ NSLayoutAttributeWidth,
+ view->minWidth)];
+ [impl->wrapperView addConstraint:puglConstraint(impl->wrapperView,
+ NSLayoutAttributeHeight,
+ view->minHeight)];
+
+ // Create draw view to be rendered to
+ PuglStatus st = PUGL_SUCCESS;
+ if ((st = view->backend->configure(view)) ||
+ (st = view->backend->create(view))) {
+ return st;
+ }
+
+ // Add draw view to wrapper view
+ [impl->wrapperView addSubview:impl->drawView];
+ [impl->wrapperView setHidden:NO];
+ [impl->drawView setHidden:NO];
+
+ if (view->parent) {
+ NSView* pview = (NSView*)view->parent;
+ [pview addSubview:impl->wrapperView];
+ [impl->drawView setHidden:NO];
+ [[impl->drawView window] makeFirstResponder:impl->wrapperView];
+ } else {
+ unsigned style =
+ (NSClosableWindowMask | NSTitledWindowMask | NSMiniaturizableWindowMask);
+ if (view->hints[PUGL_RESIZABLE]) {
+ style |= NSResizableWindowMask;
+ }
+
+ PuglWindow* window = [[[PuglWindow alloc]
+ initWithContentRect:rectToScreen([NSScreen mainScreen], framePt)
+ styleMask:style
+ backing:NSBackingStoreBuffered
+ defer:NO] retain];
+ [window setPuglview:view];
+
+ if (view->title) {
+ NSString* titleString =
+ [[NSString alloc] initWithBytes:view->title
+ length:strlen(view->title)
+ encoding:NSUTF8StringEncoding];
+
+ [window setTitle:titleString];
+ }
+
+ if (view->minWidth || view->minHeight) {
+ [window
+ setContentMinSize:sizePoints(view, view->minWidth, view->minHeight)];
+ }
+ impl->window = window;
+
+ ((NSWindow*)window).delegate =
+ [[PuglWindowDelegate alloc] initWithPuglWindow:window];
+
+ if (view->minAspectX && view->minAspectY) {
+ [window setContentAspectRatio:sizePoints(view,
+ view->minAspectX,
+ view->minAspectY)];
+ }
+
+ puglSetFrame(view, view->frame);
+
+ [window setContentView:impl->wrapperView];
+ [view->world->impl->app activateIgnoringOtherApps:YES];
+ [window makeFirstResponder:impl->wrapperView];
+ [window makeKeyAndOrderFront:window];
+ [impl->window setIsVisible:NO];
+ }
+
+ [impl->wrapperView updateTrackingAreas];
+
+ puglDispatchSimpleEvent(view, PUGL_CREATE);
+
+ return PUGL_SUCCESS;
}
PuglStatus
puglShow(PuglView* view)
{
- if (!view->impl->wrapperView) {
- const PuglStatus st = puglRealize(view);
- if (st) {
- return st;
- }
- }
+ if (!view->impl->wrapperView) {
+ const PuglStatus st = puglRealize(view);
+ if (st) {
+ return st;
+ }
+ }
- if (![view->impl->window isVisible]) {
- [view->impl->window setIsVisible:YES];
- [view->impl->drawView setNeedsDisplay: YES];
- updateViewRect(view);
- }
+ if (![view->impl->window isVisible]) {
+ [view->impl->window setIsVisible:YES];
+ [view->impl->drawView setNeedsDisplay:YES];
+ updateViewRect(view);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglHide(PuglView* view)
{
- [view->impl->window setIsVisible:NO];
- return PUGL_SUCCESS;
+ [view->impl->window setIsVisible:NO];
+ return PUGL_SUCCESS;
}
void
puglFreeViewInternals(PuglView* view)
{
- if (view) {
- if (view->backend) {
- view->backend->destroy(view);
- }
-
- if (view->impl) {
- [view->impl->wrapperView removeFromSuperview];
- view->impl->wrapperView->puglview = NULL;
- if (view->impl->window) {
- [view->impl->window close];
- }
- [view->impl->wrapperView release];
- if (view->impl->window) {
- [view->impl->window release];
- }
- free(view->impl);
- }
- }
+ if (view) {
+ if (view->backend) {
+ view->backend->destroy(view);
+ }
+
+ if (view->impl) {
+ [view->impl->wrapperView removeFromSuperview];
+ view->impl->wrapperView->puglview = NULL;
+ if (view->impl->window) {
+ [view->impl->window close];
+ }
+ [view->impl->wrapperView release];
+ if (view->impl->window) {
+ [view->impl->window release];
+ }
+ free(view->impl);
+ }
+ }
}
PuglStatus
puglGrabFocus(PuglView* view)
{
- NSWindow* window = [view->impl->wrapperView window];
+ NSWindow* window = [view->impl->wrapperView window];
- [window makeKeyWindow];
- [window makeFirstResponder:view->impl->wrapperView];
- return PUGL_SUCCESS;
+ [window makeKeyWindow];
+ [window makeFirstResponder:view->impl->wrapperView];
+ return PUGL_SUCCESS;
}
bool
puglHasFocus(const PuglView* view)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
- return ([[impl->wrapperView window] isKeyWindow] &&
- [[impl->wrapperView window] firstResponder] == impl->wrapperView);
+ return ([[impl->wrapperView window] isKeyWindow] &&
+ [[impl->wrapperView window] firstResponder] == impl->wrapperView);
}
PuglStatus
puglRequestAttention(PuglView* view)
{
- if (![view->impl->window isKeyWindow]) {
- [view->world->impl->app requestUserAttention:NSInformationalRequest];
- }
+ if (![view->impl->window isKeyWindow]) {
+ [view->world->impl->app requestUserAttention:NSInformationalRequest];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglStartTimer(PuglView* view, uintptr_t id, double timeout)
{
- puglStopTimer(view, id);
+ puglStopTimer(view, id);
- NSNumber* idNumber = [NSNumber numberWithUnsignedLong:id];
+ NSNumber* idNumber = [NSNumber numberWithUnsignedLong:id];
- NSTimer* timer = [NSTimer timerWithTimeInterval:timeout
- target:view->impl->wrapperView
- selector:@selector(timerTick:)
- userInfo:idNumber
- repeats:YES];
+ NSTimer* timer = [NSTimer timerWithTimeInterval:timeout
+ target:view->impl->wrapperView
+ selector:@selector(timerTick:)
+ userInfo:idNumber
+ repeats:YES];
- [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
+ [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
- view->impl->wrapperView->userTimers[idNumber] = timer;
+ view->impl->wrapperView->userTimers[idNumber] = timer;
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglStopTimer(PuglView* view, uintptr_t id)
{
- NSNumber* idNumber = [NSNumber numberWithUnsignedLong:id];
- NSTimer* timer = view->impl->wrapperView->userTimers[idNumber];
+ NSNumber* idNumber = [NSNumber numberWithUnsignedLong:id];
+ NSTimer* timer = view->impl->wrapperView->userTimers[idNumber];
- if (timer) {
- [view->impl->wrapperView->userTimers removeObjectForKey:timer];
- [timer invalidate];
- return PUGL_SUCCESS;
- }
+ if (timer) {
+ [view->impl->wrapperView->userTimers removeObjectForKey:timer];
+ [timer invalidate];
+ return PUGL_SUCCESS;
+ }
- return PUGL_UNKNOWN_ERROR;
+ return PUGL_UNKNOWN_ERROR;
}
PuglStatus
puglSendEvent(PuglView* view, const PuglEvent* event)
{
- if (event->type == PUGL_CLIENT) {
- PuglWrapperView* wrapper = view->impl->wrapperView;
- const NSWindow* window = [wrapper window];
- const NSRect rect = [wrapper frame];
- const NSPoint center = {NSMidX(rect), NSMidY(rect)};
-
- NSEvent* nsevent = [NSEvent
- otherEventWithType:NSApplicationDefined
- location:center
- modifierFlags:0
- timestamp:[[NSProcessInfo processInfo] systemUptime]
- windowNumber:window.windowNumber
- context:nil
- subtype:PUGL_CLIENT
- data1:(NSInteger)event->client.data1
- data2:(NSInteger)event->client.data2];
-
- [view->world->impl->app postEvent:nsevent atStart:false];
- return PUGL_SUCCESS;
- }
+ if (event->type == PUGL_CLIENT) {
+ PuglWrapperView* wrapper = view->impl->wrapperView;
+ const NSWindow* window = [wrapper window];
+ const NSRect rect = [wrapper frame];
+ const NSPoint center = {NSMidX(rect), NSMidY(rect)};
+
+ NSEvent* nsevent =
+ [NSEvent otherEventWithType:NSApplicationDefined
+ location:center
+ modifierFlags:0
+ timestamp:[[NSProcessInfo processInfo] systemUptime]
+ windowNumber:window.windowNumber
+ context:nil
+ subtype:PUGL_CLIENT
+ data1:(NSInteger)event->client.data1
+ data2:(NSInteger)event->client.data2];
- return PUGL_UNSUPPORTED_TYPE;
+ [view->world->impl->app postEvent:nsevent atStart:false];
+ return PUGL_SUCCESS;
+ }
+
+ return PUGL_UNSUPPORTED_TYPE;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglWaitForEvent(PuglView* view)
{
- return puglPollEvents(view->world, -1.0);
+ return puglPollEvents(view->world, -1.0);
}
#endif
static void
dispatchClientEvent(PuglWorld* world, NSEvent* ev)
{
- NSWindow* win = [ev window];
- NSPoint loc = [ev locationInWindow];
- for (size_t i = 0; i < world->numViews; ++i) {
- PuglView* view = world->views[i];
- PuglWrapperView* wrapper = view->impl->wrapperView;
- if ([wrapper window] == win && NSPointInRect(loc, [wrapper frame])) {
- const PuglEventClient event = {PUGL_CLIENT,
- 0,
- (uintptr_t)[ev data1],
- (uintptr_t)[ev data2]};
+ NSWindow* win = [ev window];
+ NSPoint loc = [ev locationInWindow];
+ for (size_t i = 0; i < world->numViews; ++i) {
+ PuglView* view = world->views[i];
+ PuglWrapperView* wrapper = view->impl->wrapperView;
+ if ([wrapper window] == win && NSPointInRect(loc, [wrapper frame])) {
+ const PuglEventClient event = {
+ PUGL_CLIENT, 0, (uintptr_t)[ev data1], (uintptr_t)[ev data2]};
- puglDispatchEvent(view, (const PuglEvent*)&event);
- }
- }
+ puglDispatchEvent(view, (const PuglEvent*)&event);
+ }
+ }
}
PuglStatus
puglUpdate(PuglWorld* world, const double timeout)
{
- NSDate* date = ((timeout < 0)
- ? [NSDate distantFuture]
- : [NSDate dateWithTimeIntervalSinceNow:timeout]);
-
- for (NSEvent* ev = NULL;
- (ev = [world->impl->app nextEventMatchingMask:NSAnyEventMask
- untilDate:date
- inMode:NSDefaultRunLoopMode
- dequeue:YES]);) {
-
- if ([ev type] == NSApplicationDefined && [ev subtype] == PUGL_CLIENT) {
- dispatchClientEvent(world, ev);
- }
+ NSDate* date =
+ ((timeout < 0) ? [NSDate distantFuture]
+ : [NSDate dateWithTimeIntervalSinceNow:timeout]);
+
+ for (NSEvent* ev = NULL;
+ (ev = [world->impl->app nextEventMatchingMask:NSAnyEventMask
+ untilDate:date
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES]);) {
+ if ([ev type] == NSApplicationDefined && [ev subtype] == PUGL_CLIENT) {
+ dispatchClientEvent(world, ev);
+ }
- [world->impl->app sendEvent: ev];
+ [world->impl->app sendEvent:ev];
- if (timeout < 0) {
- // Now that we've waited and got an event, set the date to now to
- // avoid looping forever
- date = [NSDate date];
- }
- }
+ if (timeout < 0) {
+ // Now that we've waited and got an event, set the date to now to
+ // avoid looping forever
+ date = [NSDate date];
+ }
+ }
- for (size_t i = 0; i < world->numViews; ++i) {
- PuglView* const view = world->views[i];
+ for (size_t i = 0; i < world->numViews; ++i) {
+ PuglView* const view = world->views[i];
- if ([[view->impl->drawView window] isVisible]) {
- puglDispatchSimpleEvent(view, PUGL_UPDATE);
- }
+ if ([[view->impl->drawView window] isVisible]) {
+ puglDispatchSimpleEvent(view, PUGL_UPDATE);
+ }
- [view->impl->drawView displayIfNeeded];
- }
+ [view->impl->drawView displayIfNeeded];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglProcessEvents(PuglView* view)
{
- return puglDispatchEvents(view->world);
+ return puglDispatchEvents(view->world);
}
#endif
double
puglGetTime(const PuglWorld* world)
{
- return (mach_absolute_time() / 1e9) - world->startTime;
+ return (mach_absolute_time() / 1e9) - world->startTime;
}
PuglStatus
puglPostRedisplay(PuglView* view)
{
- [view->impl->drawView setNeedsDisplay: YES];
- return PUGL_SUCCESS;
+ [view->impl->drawView setNeedsDisplay:YES];
+ return PUGL_SUCCESS;
}
PuglStatus
puglPostRedisplayRect(PuglView* view, const PuglRect rect)
{
- const NSRect rectPx = rectToNsRect(rect);
+ const NSRect rectPx = rectToNsRect(rect);
- [view->impl->drawView setNeedsDisplayInRect:nsRectToPoints(view, rectPx)];
+ [view->impl->drawView setNeedsDisplayInRect:nsRectToPoints(view, rectPx)];
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglNativeView
puglGetNativeWindow(PuglView* view)
{
- return (PuglNativeView)view->impl->wrapperView;
+ return (PuglNativeView)view->impl->wrapperView;
}
PuglStatus
puglSetWindowTitle(PuglView* view, const char* title)
{
- puglSetString(&view->title, title);
+ puglSetString(&view->title, title);
- if (view->impl->window) {
- NSString* titleString = [[NSString alloc]
- initWithBytes:title
- length:strlen(title)
- encoding:NSUTF8StringEncoding];
+ if (view->impl->window) {
+ NSString* titleString =
+ [[NSString alloc] initWithBytes:title
+ length:strlen(title)
+ encoding:NSUTF8StringEncoding];
- [view->impl->window setTitle:titleString];
- }
+ [view->impl->window setTitle:titleString];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
- // Update view frame to exactly the requested frame in Pugl coordinates
- view->frame = frame;
+ // Update view frame to exactly the requested frame in Pugl coordinates
+ view->frame = frame;
- const NSRect framePx = rectToNsRect(frame);
- const NSRect framePt = nsRectToPoints(view, framePx);
- if (impl->window) {
- // Resize window to fit new content rect
- const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
- const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
+ const NSRect framePx = rectToNsRect(frame);
+ const NSRect framePt = nsRectToPoints(view, framePx);
+ if (impl->window) {
+ // Resize window to fit new content rect
+ const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
+ const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
- [impl->window setFrame:winFrame display:NO];
- }
+ [impl->window setFrame:winFrame display:NO];
+ }
- // Resize views
- const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
- const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+ // Resize views
+ const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
- [impl->wrapperView setFrame:(impl->window ? sizePt : framePt)];
- [impl->drawView setFrame:sizePt];
+ [impl->wrapperView setFrame:(impl->window ? sizePt : framePt)];
+ [impl->drawView setFrame:sizePt];
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetDefaultSize(PuglView* const view, const int width, const int height)
{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return PUGL_SUCCESS;
+ view->defaultWidth = width;
+ view->defaultHeight = height;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetMinSize(PuglView* const view, const int width, const int height)
{
- view->minWidth = width;
- view->minHeight = height;
+ view->minWidth = width;
+ view->minHeight = height;
- if (view->impl->window && (view->minWidth || view->minHeight)) {
- [view->impl->window setContentMinSize:sizePoints(view,
- view->minWidth,
- view->minHeight)];
- }
+ if (view->impl->window && (view->minWidth || view->minHeight)) {
+ [view->impl->window
+ setContentMinSize:sizePoints(view, view->minWidth, view->minHeight)];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetMaxSize(PuglView* const view, const int width, const int height)
{
- view->maxWidth = width;
- view->maxHeight = height;
+ view->maxWidth = width;
+ view->maxHeight = height;
- if (view->impl->window && (view->maxWidth || view->maxHeight)) {
- [view->impl->window setContentMaxSize:sizePoints(view,
- view->maxWidth,
- view->maxHeight)];
- }
+ if (view->impl->window && (view->maxWidth || view->maxHeight)) {
+ [view->impl->window
+ setContentMaxSize:sizePoints(view, view->maxWidth, view->maxHeight)];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
@@ -1334,35 +1348,34 @@ puglSetAspectRatio(PuglView* const view,
const int maxX,
const int maxY)
{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
+ view->minAspectX = minX;
+ view->minAspectY = minY;
+ view->maxAspectX = maxX;
+ view->maxAspectY = maxY;
- if (view->impl->window && view->minAspectX && view->minAspectY) {
- [view->impl->window setContentAspectRatio:sizePoints(view,
- view->minAspectX,
- view->minAspectY)];
- }
+ if (view->impl->window && view->minAspectX && view->minAspectY) {
+ [view->impl->window setContentAspectRatio:sizePoints(view,
+ view->minAspectX,
+ view->minAspectY)];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetTransientFor(PuglView* view, PuglNativeView parent)
{
- view->transientParent = parent;
+ view->transientParent = parent;
- if (view->impl->window) {
- NSWindow* parentWindow = [(NSView*)parent window];
- if (parentWindow) {
- [parentWindow addChildWindow:view->impl->window
- ordered:NSWindowAbove];
- return PUGL_SUCCESS;
- }
- }
+ if (view->impl->window) {
+ NSWindow* parentWindow = [(NSView*)parent window];
+ if (parentWindow) {
+ [parentWindow addChildWindow:view->impl->window ordered:NSWindowAbove];
+ return PUGL_SUCCESS;
+ }
+ }
- return PUGL_FAILURE;
+ return PUGL_FAILURE;
}
const void*
@@ -1370,57 +1383,57 @@ puglGetClipboard(PuglView* const view,
const char** const type,
size_t* const len)
{
- NSPasteboard* const pasteboard = [NSPasteboard generalPasteboard];
+ NSPasteboard* const pasteboard = [NSPasteboard generalPasteboard];
- if ([[pasteboard types] containsObject:NSStringPboardType]) {
- const NSString* str = [pasteboard stringForType:NSStringPboardType];
- const char* utf8 = [str UTF8String];
+ if ([[pasteboard types] containsObject:NSStringPboardType]) {
+ const NSString* str = [pasteboard stringForType:NSStringPboardType];
+ const char* utf8 = [str UTF8String];
- puglSetBlob(&view->clipboard, utf8, strlen(utf8) + 1);
- }
+ puglSetBlob(&view->clipboard, utf8, strlen(utf8) + 1);
+ }
- return puglGetInternalClipboard(view, type, len);
+ return puglGetInternalClipboard(view, type, len);
}
static NSCursor*
puglGetNsCursor(const PuglCursor cursor)
{
- switch (cursor) {
- case PUGL_CURSOR_ARROW:
- return [NSCursor arrowCursor];
- case PUGL_CURSOR_CARET:
- return [NSCursor IBeamCursor];
- case PUGL_CURSOR_CROSSHAIR:
- return [NSCursor crosshairCursor];
- case PUGL_CURSOR_HAND:
- return [NSCursor pointingHandCursor];
- case PUGL_CURSOR_NO:
- return [NSCursor operationNotAllowedCursor];
- case PUGL_CURSOR_LEFT_RIGHT:
- return [NSCursor resizeLeftRightCursor];
- case PUGL_CURSOR_UP_DOWN:
- return [NSCursor resizeUpDownCursor];
- }
-
- return NULL;
+ switch (cursor) {
+ case PUGL_CURSOR_ARROW:
+ return [NSCursor arrowCursor];
+ case PUGL_CURSOR_CARET:
+ return [NSCursor IBeamCursor];
+ case PUGL_CURSOR_CROSSHAIR:
+ return [NSCursor crosshairCursor];
+ case PUGL_CURSOR_HAND:
+ return [NSCursor pointingHandCursor];
+ case PUGL_CURSOR_NO:
+ return [NSCursor operationNotAllowedCursor];
+ case PUGL_CURSOR_LEFT_RIGHT:
+ return [NSCursor resizeLeftRightCursor];
+ case PUGL_CURSOR_UP_DOWN:
+ return [NSCursor resizeUpDownCursor];
+ }
+
+ return NULL;
}
PuglStatus
puglSetCursor(PuglView* view, PuglCursor cursor)
{
- PuglInternals* const impl = view->impl;
- NSCursor* const cur = puglGetNsCursor(cursor);
- if (!cur) {
- return PUGL_FAILURE;
- }
+ PuglInternals* const impl = view->impl;
+ NSCursor* const cur = puglGetNsCursor(cursor);
+ if (!cur) {
+ return PUGL_FAILURE;
+ }
- impl->cursor = cur;
+ impl->cursor = cur;
- if (impl->mouseTracked) {
- [cur set];
- }
+ if (impl->mouseTracked) {
+ [cur set];
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
@@ -1429,24 +1442,23 @@ puglSetClipboard(PuglView* const view,
const void* const data,
const size_t len)
{
- NSPasteboard* const pasteboard = [NSPasteboard generalPasteboard];
- const char* const str = (const char*)data;
+ NSPasteboard* const pasteboard = [NSPasteboard generalPasteboard];
+ const char* const str = (const char*)data;
- PuglStatus st = puglSetInternalClipboard(view, type, data, len);
- if (st) {
- return st;
- }
+ PuglStatus st = puglSetInternalClipboard(view, type, data, len);
+ if (st) {
+ return st;
+ }
- NSString* nsString = [NSString stringWithUTF8String:str];
- if (nsString) {
- [pasteboard
- declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil]
- owner:nil];
+ NSString* nsString = [NSString stringWithUTF8String:str];
+ if (nsString) {
+ [pasteboard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil]
+ owner:nil];
- [pasteboard setString:nsString forType:NSStringPboardType];
+ [pasteboard setString:nsString forType:NSStringPboardType];
- return PUGL_SUCCESS;
- }
+ return PUGL_SUCCESS;
+ }
- return PUGL_UNKNOWN_ERROR;
+ return PUGL_UNKNOWN_ERROR;
}
diff --git a/src/mac_cairo.m b/src/mac_cairo.m
index 9a46037..1c564a0 100644
--- a/src/mac_cairo.m
+++ b/src/mac_cairo.m
@@ -29,33 +29,32 @@
@interface PuglCairoView : NSView
@end
-@implementation PuglCairoView
-{
+@implementation PuglCairoView {
@public
- PuglView* puglview;
- cairo_surface_t* surface;
- cairo_t* cr;
+ PuglView* puglview;
+ cairo_surface_t* surface;
+ cairo_t* cr;
}
- (id)initWithFrame:(NSRect)frame
{
- self = [super initWithFrame:frame];
+ self = [super initWithFrame:frame];
- return self;
+ return self;
}
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [super resizeWithOldSuperviewSize:oldSize];
- [wrapper setReshaped];
+ [super resizeWithOldSuperviewSize:oldSize];
+ [wrapper setReshaped];
}
- (void)drawRect:(NSRect)rect
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [wrapper dispatchExpose:rect];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ [wrapper dispatchExpose:rect];
}
@end
@@ -63,99 +62,99 @@
static PuglStatus
puglMacCairoCreate(PuglView* view)
{
- PuglInternals* impl = view->impl;
- PuglCairoView* drawView = [PuglCairoView alloc];
-
- drawView->puglview = view;
- [drawView initWithFrame:[impl->wrapperView bounds]];
- if (view->hints[PUGL_RESIZABLE]) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ PuglCairoView* drawView = [PuglCairoView alloc];
+
+ drawView->puglview = view;
+ [drawView initWithFrame:[impl->wrapperView bounds]];
+ if (view->hints[PUGL_RESIZABLE]) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacCairoDestroy(PuglView* view)
{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
- [drawView removeFromSuperview];
- [drawView release];
+ [drawView removeFromSuperview];
+ [drawView release];
- view->impl->drawView = nil;
- return PUGL_SUCCESS;
+ view->impl->drawView = nil;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacCairoEnter(PuglView* view, const PuglEventExpose* expose)
{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
- if (!expose) {
- return PUGL_SUCCESS;
- }
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+ if (!expose) {
+ return PUGL_SUCCESS;
+ }
- assert(!drawView->surface);
- assert(!drawView->cr);
+ assert(!drawView->surface);
+ assert(!drawView->cr);
- const double scale = 1.0 / [[NSScreen mainScreen] backingScaleFactor];
- CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
- const CGSize sizePx = {view->frame.width, view->frame.height};
- const CGSize sizePt = CGContextConvertSizeToUserSpace(context, sizePx);
+ const double scale = 1.0 / [[NSScreen mainScreen] backingScaleFactor];
+ CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
+ const CGSize sizePx = {view->frame.width, view->frame.height};
+ const CGSize sizePt = CGContextConvertSizeToUserSpace(context, sizePx);
- // Convert coordinates to standard Cairo space
- CGContextTranslateCTM(context, 0.0, -sizePt.height);
- CGContextScaleCTM(context, scale, -scale);
+ // Convert coordinates to standard Cairo space
+ CGContextTranslateCTM(context, 0.0, -sizePt.height);
+ CGContextScaleCTM(context, scale, -scale);
- drawView->surface = cairo_quartz_surface_create_for_cg_context(
- context, (unsigned)sizePx.width, (unsigned)sizePx.height);
+ drawView->surface = cairo_quartz_surface_create_for_cg_context(
+ context, (unsigned)sizePx.width, (unsigned)sizePx.height);
- drawView->cr = cairo_create(drawView->surface);
+ drawView->cr = cairo_create(drawView->surface);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacCairoLeave(PuglView* view, const PuglEventExpose* expose)
{
- PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
- if (!expose) {
- return PUGL_SUCCESS;
- }
+ PuglCairoView* const drawView = (PuglCairoView*)view->impl->drawView;
+ if (!expose) {
+ return PUGL_SUCCESS;
+ }
- assert(drawView->surface);
- assert(drawView->cr);
+ assert(drawView->surface);
+ assert(drawView->cr);
- CGContextRef context = cairo_quartz_surface_get_cg_context(drawView->surface);
+ CGContextRef context = cairo_quartz_surface_get_cg_context(drawView->surface);
- cairo_destroy(drawView->cr);
- cairo_surface_destroy(drawView->surface);
- drawView->cr = NULL;
- drawView->surface = NULL;
+ cairo_destroy(drawView->cr);
+ cairo_surface_destroy(drawView->surface);
+ drawView->cr = NULL;
+ drawView->surface = NULL;
- CGContextFlush(context);
+ CGContextFlush(context);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static void*
puglMacCairoGetContext(PuglView* view)
{
- return ((PuglCairoView*)view->impl->drawView)->cr;
+ return ((PuglCairoView*)view->impl->drawView)->cr;
}
const PuglBackend*
puglCairoBackend(void)
{
- static const PuglBackend backend = {puglStubConfigure,
- puglMacCairoCreate,
- puglMacCairoDestroy,
- puglMacCairoEnter,
- puglMacCairoLeave,
- puglMacCairoGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglStubConfigure,
+ puglMacCairoCreate,
+ puglMacCairoDestroy,
+ puglMacCairoEnter,
+ puglMacCairoLeave,
+ puglMacCairoGetContext};
+
+ return &backend;
}
diff --git a/src/mac_gl.m b/src/mac_gl.m
index b29221f..dd06cc0 100644
--- a/src/mac_gl.m
+++ b/src/mac_gl.m
@@ -21,95 +21,95 @@
#include "pugl/gl.h"
#ifndef __MAC_10_10
-# define NSOpenGLProfileVersion4_1Core NSOpenGLProfileVersion3_2Core
+# define NSOpenGLProfileVersion4_1Core NSOpenGLProfileVersion3_2Core
#endif
@interface PuglOpenGLView : NSOpenGLView
@end
-@implementation PuglOpenGLView
-{
+@implementation PuglOpenGLView {
@public
- PuglView* puglview;
+ PuglView* puglview;
}
- (id)initWithFrame:(NSRect)frame
{
- const bool compat = puglview->hints[PUGL_USE_COMPAT_PROFILE];
- const unsigned samples = (unsigned)puglview->hints[PUGL_SAMPLES];
- const int major = puglview->hints[PUGL_CONTEXT_VERSION_MAJOR];
- const unsigned profile = ((compat || major < 3)
- ? NSOpenGLProfileVersionLegacy
- : (major >= 4
- ? NSOpenGLProfileVersion4_1Core
- : NSOpenGLProfileVersion3_2Core));
-
- // Set attributes to default if they are unset
- // (There is no GLX_DONT_CARE equivalent on MacOS)
- if (puglview->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
- puglview->hints[PUGL_DEPTH_BITS] = 0;
- }
- if (puglview->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
- puglview->hints[PUGL_STENCIL_BITS] = 0;
- }
- if (puglview->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
- puglview->hints[PUGL_SAMPLES] = 1;
- }
- if (puglview->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
- puglview->hints[PUGL_DOUBLE_BUFFER] = 1;
- }
- if (puglview->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
- puglview->hints[PUGL_SWAP_INTERVAL] = 1;
- }
-
- const unsigned colorSize = (unsigned)(puglview->hints[PUGL_RED_BITS] +
- puglview->hints[PUGL_BLUE_BITS] +
- puglview->hints[PUGL_GREEN_BITS] +
- puglview->hints[PUGL_ALPHA_BITS]);
-
- NSOpenGLPixelFormatAttribute pixelAttribs[17] = {
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFAAccelerated,
- NSOpenGLPFAOpenGLProfile, profile,
- NSOpenGLPFAColorSize, colorSize,
- NSOpenGLPFADepthSize, (unsigned)puglview->hints[PUGL_DEPTH_BITS],
- NSOpenGLPFAStencilSize, (unsigned)puglview->hints[PUGL_STENCIL_BITS],
- NSOpenGLPFAMultisample, samples ? 1 : 0,
- NSOpenGLPFASampleBuffers, samples ? 1 : 0,
- NSOpenGLPFASamples, samples,
- 0};
-
- NSOpenGLPixelFormat* pixelFormat = [
- [NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttribs];
-
- if (pixelFormat) {
- self = [super initWithFrame:frame pixelFormat:pixelFormat];
- [pixelFormat release];
- } else {
- self = [super initWithFrame:frame];
- }
-
- [self setWantsBestResolutionOpenGLSurface:YES];
-
- if (self) {
- [[self openGLContext] makeCurrentContext];
- [self reshape];
- }
- return self;
+ const bool compat = puglview->hints[PUGL_USE_COMPAT_PROFILE];
+ const unsigned samples = (unsigned)puglview->hints[PUGL_SAMPLES];
+ const int major = puglview->hints[PUGL_CONTEXT_VERSION_MAJOR];
+ const unsigned profile =
+ ((compat || major < 3) ? NSOpenGLProfileVersionLegacy
+ : (major >= 4 ? NSOpenGLProfileVersion4_1Core
+ : NSOpenGLProfileVersion3_2Core));
+
+ // Set attributes to default if they are unset
+ // (There is no GLX_DONT_CARE equivalent on MacOS)
+ if (puglview->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_DEPTH_BITS] = 0;
+ }
+ if (puglview->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_STENCIL_BITS] = 0;
+ }
+ if (puglview->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_SAMPLES] = 1;
+ }
+ if (puglview->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_DOUBLE_BUFFER] = 1;
+ }
+ if (puglview->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
+ puglview->hints[PUGL_SWAP_INTERVAL] = 1;
+ }
+
+ const unsigned colorSize = (unsigned)(puglview->hints[PUGL_RED_BITS] +
+ puglview->hints[PUGL_BLUE_BITS] +
+ puglview->hints[PUGL_GREEN_BITS] +
+ puglview->hints[PUGL_ALPHA_BITS]);
+
+ // clang-format off
+ NSOpenGLPixelFormatAttribute pixelAttribs[17] = {
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFAOpenGLProfile, profile,
+ NSOpenGLPFAColorSize, colorSize,
+ NSOpenGLPFADepthSize, (unsigned)puglview->hints[PUGL_DEPTH_BITS],
+ NSOpenGLPFAStencilSize, (unsigned)puglview->hints[PUGL_STENCIL_BITS],
+ NSOpenGLPFAMultisample, samples ? 1 : 0,
+ NSOpenGLPFASampleBuffers, samples ? 1 : 0,
+ NSOpenGLPFASamples, samples,
+ 0};
+ // clang-format on
+
+ NSOpenGLPixelFormat* pixelFormat =
+ [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelAttribs];
+
+ if (pixelFormat) {
+ self = [super initWithFrame:frame pixelFormat:pixelFormat];
+ [pixelFormat release];
+ } else {
+ self = [super initWithFrame:frame];
+ }
+
+ [self setWantsBestResolutionOpenGLSurface:YES];
+
+ if (self) {
+ [[self openGLContext] makeCurrentContext];
+ [self reshape];
+ }
+ return self;
}
- (void)reshape
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [super reshape];
- [wrapper setReshaped];
+ [super reshape];
+ [wrapper setReshaped];
}
- (void)drawRect:(NSRect)rect
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [wrapper dispatchExpose:rect];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ [wrapper dispatchExpose:rect];
}
@end
@@ -117,94 +117,94 @@
static PuglStatus
puglMacGlCreate(PuglView* view)
{
- PuglInternals* impl = view->impl;
- PuglOpenGLView* drawView = [PuglOpenGLView alloc];
-
- drawView->puglview = view;
- [drawView initWithFrame:[impl->wrapperView bounds]];
- if (view->hints[PUGL_RESIZABLE]) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ PuglOpenGLView* drawView = [PuglOpenGLView alloc];
+
+ drawView->puglview = view;
+ [drawView initWithFrame:[impl->wrapperView bounds]];
+ if (view->hints[PUGL_RESIZABLE]) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacGlDestroy(PuglView* view)
{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
- [drawView removeFromSuperview];
- [drawView release];
+ [drawView removeFromSuperview];
+ [drawView release];
- view->impl->drawView = nil;
- return PUGL_SUCCESS;
+ view->impl->drawView = nil;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacGlEnter(PuglView* view, const PuglEventExpose* PUGL_UNUSED(expose))
{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
- [[drawView openGLContext] makeCurrentContext];
- return PUGL_SUCCESS;
+ [[drawView openGLContext] makeCurrentContext];
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacGlLeave(PuglView* view, const PuglEventExpose* expose)
{
- PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
+ PuglOpenGLView* const drawView = (PuglOpenGLView*)view->impl->drawView;
- if (expose) {
- [[drawView openGLContext] flushBuffer];
- }
+ if (expose) {
+ [[drawView openGLContext] flushBuffer];
+ }
- [NSOpenGLContext clearCurrentContext];
+ [NSOpenGLContext clearCurrentContext];
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglGlFunc
-puglGetProcAddress(const char *name)
+puglGetProcAddress(const char* name)
{
- CFBundleRef framework =
- CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ CFBundleRef framework =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- CFStringRef symbol = CFStringCreateWithCString(
- kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ CFStringRef symbol = CFStringCreateWithCString(
+ kCFAllocatorDefault, name, kCFStringEncodingASCII);
- PuglGlFunc func = (PuglGlFunc)CFBundleGetFunctionPointerForName(
- framework, symbol);
+ PuglGlFunc func =
+ (PuglGlFunc)CFBundleGetFunctionPointerForName(framework, symbol);
- CFRelease(symbol);
+ CFRelease(symbol);
- return func;
+ return func;
}
PuglStatus
puglEnterContext(PuglView* view)
{
- return view->backend->enter(view, NULL);
+ return view->backend->enter(view, NULL);
}
PuglStatus
puglLeaveContext(PuglView* view)
{
- return view->backend->leave(view, NULL);
+ return view->backend->leave(view, NULL);
}
const PuglBackend*
puglGlBackend(void)
{
- static const PuglBackend backend = {puglStubConfigure,
- puglMacGlCreate,
- puglMacGlDestroy,
- puglMacGlEnter,
- puglMacGlLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglStubConfigure,
+ puglMacGlCreate,
+ puglMacGlDestroy,
+ puglMacGlEnter,
+ puglMacGlLeave,
+ puglStubGetContext};
+
+ return &backend;
}
diff --git a/src/mac_stub.m b/src/mac_stub.m
index 404d295..ac7bfcc 100644
--- a/src/mac_stub.m
+++ b/src/mac_stub.m
@@ -25,25 +25,24 @@
@interface PuglStubView : NSView
@end
-@implementation PuglStubView
-{
+@implementation PuglStubView {
@public
- PuglView* puglview;
+ PuglView* puglview;
}
- (void)resizeWithOldSuperviewSize:(NSSize)oldSize
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [super resizeWithOldSuperviewSize:oldSize];
- [wrapper setReshaped];
+ [super resizeWithOldSuperviewSize:oldSize];
+ [wrapper setReshaped];
}
- (void)drawRect:(NSRect)rect
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [wrapper dispatchExpose:rect];
+ [wrapper dispatchExpose:rect];
}
@end
@@ -51,42 +50,43 @@
static PuglStatus
puglMacStubCreate(PuglView* view)
{
- PuglInternals* impl = view->impl;
- PuglStubView* drawView = [PuglStubView alloc];
-
- drawView->puglview = view;
- [drawView initWithFrame:NSMakeRect(0, 0, view->frame.width, view->frame.height)];
- if (view->hints[PUGL_RESIZABLE]) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ PuglStubView* drawView = [PuglStubView alloc];
+
+ drawView->puglview = view;
+ [drawView
+ initWithFrame:NSMakeRect(0, 0, view->frame.width, view->frame.height)];
+ if (view->hints[PUGL_RESIZABLE]) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacStubDestroy(PuglView* view)
{
- PuglStubView* const drawView = (PuglStubView*)view->impl->drawView;
+ PuglStubView* const drawView = (PuglStubView*)view->impl->drawView;
- [drawView removeFromSuperview];
- [drawView release];
+ [drawView removeFromSuperview];
+ [drawView release];
- view->impl->drawView = nil;
- return PUGL_SUCCESS;
+ view->impl->drawView = nil;
+ return PUGL_SUCCESS;
}
const PuglBackend*
puglStubBackend(void)
{
- static const PuglBackend backend = {puglStubConfigure,
- puglMacStubCreate,
- puglMacStubDestroy,
- puglStubEnter,
- puglStubLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglStubConfigure,
+ puglMacStubCreate,
+ puglMacStubDestroy,
+ puglStubEnter,
+ puglStubLeave,
+ puglStubGetContext};
+
+ return &backend;
}
diff --git a/src/mac_vulkan.m b/src/mac_vulkan.m
index c56346c..6899483 100644
--- a/src/mac_vulkan.m
+++ b/src/mac_vulkan.m
@@ -40,47 +40,45 @@
@end
-@implementation PuglVulkanView
-{
+@implementation PuglVulkanView {
@public
- PuglView* puglview;
+ PuglView* puglview;
}
- (id)initWithFrame:(NSRect)frame
{
- self = [super initWithFrame:frame];
+ self = [super initWithFrame:frame];
- if (self) {
- self.wantsLayer = YES;
- self.layerContentsRedrawPolicy =
- NSViewLayerContentsRedrawOnSetNeedsDisplay;
- }
+ if (self) {
+ self.wantsLayer = YES;
+ self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
+ }
- return self;
+ return self;
}
- (CALayer*)makeBackingLayer
{
- CAMetalLayer* layer = [CAMetalLayer layer];
- [layer setDelegate:self];
- return layer;
+ CAMetalLayer* layer = [CAMetalLayer layer];
+ [layer setDelegate:self];
+ return layer;
}
- (void)setFrameSize:(NSSize)newSize
{
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [super setFrameSize:newSize];
- [wrapper setReshaped];
+ [super setFrameSize:newSize];
+ [wrapper setReshaped];
- self.layer.frame = self.bounds;
+ self.layer.frame = self.bounds;
}
- (void)displayLayer:(CALayer*)layer
{
- (void)layer;
- PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
- [wrapper dispatchExpose:[self bounds]];
+ (void)layer;
+ PuglWrapperView* wrapper = (PuglWrapperView*)[self superview];
+ [wrapper dispatchExpose:[self bounds]];
}
@end
@@ -88,105 +86,105 @@
static PuglStatus
puglMacVulkanCreate(PuglView* view)
{
- PuglInternals* impl = view->impl;
- PuglVulkanView* drawView = [PuglVulkanView alloc];
- const NSRect rect = NSMakeRect(0, 0, view->frame.width, view->frame.height);
-
- drawView->puglview = view;
- [drawView initWithFrame:rect];
- if (view->hints[PUGL_RESIZABLE]) {
- [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
- } else {
- [drawView setAutoresizingMask:NSViewNotSizable];
- }
-
- impl->drawView = drawView;
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ PuglVulkanView* drawView = [PuglVulkanView alloc];
+ const NSRect rect = NSMakeRect(0, 0, view->frame.width, view->frame.height);
+
+ drawView->puglview = view;
+ [drawView initWithFrame:rect];
+ if (view->hints[PUGL_RESIZABLE]) {
+ [drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ } else {
+ [drawView setAutoresizingMask:NSViewNotSizable];
+ }
+
+ impl->drawView = drawView;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglMacVulkanDestroy(PuglView* view)
{
- PuglVulkanView* const drawView = (PuglVulkanView*)view->impl->drawView;
+ PuglVulkanView* const drawView = (PuglVulkanView*)view->impl->drawView;
- [drawView removeFromSuperview];
- [drawView release];
+ [drawView removeFromSuperview];
+ [drawView release];
- view->impl->drawView = nil;
- return PUGL_SUCCESS;
+ view->impl->drawView = nil;
+ return PUGL_SUCCESS;
}
struct PuglVulkanLoaderImpl {
- void* libvulkan;
- PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
- PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+ void* libvulkan;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
};
PuglVulkanLoader*
puglNewVulkanLoader(PuglWorld* PUGL_UNUSED(world))
{
- PuglVulkanLoader* loader = (PuglVulkanLoader*)
- calloc(1, sizeof(PuglVulkanLoader));
- if (!loader) {
- return NULL;
- }
+ PuglVulkanLoader* loader =
+ (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader));
+ if (!loader) {
+ return NULL;
+ }
- if (!(loader->libvulkan = dlopen("libvulkan.dylib", RTLD_LAZY))) {
- free(loader);
- return NULL;
- }
+ if (!(loader->libvulkan = dlopen("libvulkan.dylib", RTLD_LAZY))) {
+ free(loader);
+ return NULL;
+ }
- loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
- dlsym(loader->libvulkan, "vkGetInstanceProcAddr");
+ loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(
+ loader->libvulkan, "vkGetInstanceProcAddr");
- loader->vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)
- dlsym(loader->libvulkan, "vkGetDeviceProcAddr");
+ loader->vkGetDeviceProcAddr =
+ (PFN_vkGetDeviceProcAddr)dlsym(loader->libvulkan, "vkGetDeviceProcAddr");
- return loader;
+ return loader;
}
void
puglFreeVulkanLoader(PuglVulkanLoader* loader)
{
- if (loader) {
- dlclose(loader->libvulkan);
- free(loader);
- }
+ if (loader) {
+ dlclose(loader->libvulkan);
+ free(loader);
+ }
}
PFN_vkGetInstanceProcAddr
puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetInstanceProcAddr;
+ return loader->vkGetInstanceProcAddr;
}
PFN_vkGetDeviceProcAddr
puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetDeviceProcAddr;
+ return loader->vkGetDeviceProcAddr;
}
const PuglBackend*
puglVulkanBackend(void)
{
- static const PuglBackend backend = {puglStubConfigure,
- puglMacVulkanCreate,
- puglMacVulkanDestroy,
- puglStubEnter,
- puglStubLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglStubConfigure,
+ puglMacVulkanCreate,
+ puglMacVulkanDestroy,
+ puglStubEnter,
+ puglStubLeave,
+ puglStubGetContext};
+
+ return &backend;
}
const char* const*
puglGetInstanceExtensions(uint32_t* const count)
{
- static const char* const extensions[] = {"VK_KHR_surface",
- "VK_MVK_macos_surface"};
+ static const char* const extensions[] = {"VK_KHR_surface",
+ "VK_MVK_macos_surface"};
- *count = 2;
- return extensions;
+ *count = 2;
+ return extensions;
}
VkResult
@@ -196,18 +194,18 @@ puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
const VkAllocationCallbacks* const allocator,
VkSurfaceKHR* const surface)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
- PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
- (PFN_vkCreateMacOSSurfaceMVK)
- vkGetInstanceProcAddr(instance, "vkCreateMacOSSurfaceMVK");
+ PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK =
+ (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr(
+ instance, "vkCreateMacOSSurfaceMVK");
- const VkMacOSSurfaceCreateInfoMVK info = {
- VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
- NULL,
- 0,
- impl->drawView,
- };
+ const VkMacOSSurfaceCreateInfoMVK info = {
+ VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
+ NULL,
+ 0,
+ impl->drawView,
+ };
- return vkCreateMacOSSurfaceMVK(instance, &info, allocator, surface);
+ return vkCreateMacOSSurfaceMVK(instance, &info, allocator, surface);
}
diff --git a/src/stub.h b/src/stub.h
index 36d7364..e61085c 100644
--- a/src/stub.h
+++ b/src/stub.h
@@ -24,45 +24,45 @@ PUGL_BEGIN_DECLS
static inline PuglStatus
puglStubConfigure(PuglView* view)
{
- (void)view;
- return PUGL_SUCCESS;
+ (void)view;
+ return PUGL_SUCCESS;
}
static inline PuglStatus
puglStubCreate(PuglView* view)
{
- (void)view;
- return PUGL_SUCCESS;
+ (void)view;
+ return PUGL_SUCCESS;
}
static inline PuglStatus
puglStubDestroy(PuglView* view)
{
- (void)view;
- return PUGL_SUCCESS;
+ (void)view;
+ return PUGL_SUCCESS;
}
static inline PuglStatus
puglStubEnter(PuglView* view, const PuglEventExpose* expose)
{
- (void)view;
- (void)expose;
- return PUGL_SUCCESS;
+ (void)view;
+ (void)expose;
+ return PUGL_SUCCESS;
}
static inline PuglStatus
puglStubLeave(PuglView* view, const PuglEventExpose* expose)
{
- (void)view;
- (void)expose;
- return PUGL_SUCCESS;
+ (void)view;
+ (void)expose;
+ return PUGL_SUCCESS;
}
static inline void*
puglStubGetContext(PuglView* view)
{
- (void)view;
- return NULL;
+ (void)view;
+ return NULL;
}
PUGL_END_DECLS
diff --git a/src/types.h b/src/types.h
index 4e63d43..a618e8c 100644
--- a/src/types.h
+++ b/src/types.h
@@ -25,11 +25,11 @@
// Unused parameter macro to suppresses warnings and make it impossible to use
#if defined(__cplusplus)
-# define PUGL_UNUSED(name)
+# define PUGL_UNUSED(name)
#elif defined(__GNUC__) || defined(__clang__)
-# define PUGL_UNUSED(name) name##_unused __attribute__((__unused__))
+# define PUGL_UNUSED(name) name##_unused __attribute__((__unused__))
#else
-# define PUGL_UNUSED(name) name
+# define PUGL_UNUSED(name) name
#endif
/// Platform-specific world internals
@@ -43,45 +43,45 @@ typedef int PuglHints[PUGL_NUM_VIEW_HINTS];
/// Blob of arbitrary data
typedef struct {
- void* data; ///< Dynamically allocated data
- size_t len; ///< Length of data in bytes
+ void* data; ///< Dynamically allocated data
+ size_t len; ///< Length of data in bytes
} PuglBlob;
/// Cross-platform view definition
struct PuglViewImpl {
- PuglWorld* world;
- const PuglBackend* backend;
- PuglInternals* impl;
- PuglHandle handle;
- PuglEventFunc eventFunc;
- char* title;
- PuglBlob clipboard;
- PuglNativeView parent;
- uintptr_t transientParent;
- PuglRect frame;
- PuglEventConfigure lastConfigure;
- PuglHints hints;
- int defaultWidth;
- int defaultHeight;
- int minWidth;
- int minHeight;
- int maxWidth;
- int maxHeight;
- int minAspectX;
- int minAspectY;
- int maxAspectX;
- int maxAspectY;
- bool visible;
+ PuglWorld* world;
+ const PuglBackend* backend;
+ PuglInternals* impl;
+ PuglHandle handle;
+ PuglEventFunc eventFunc;
+ char* title;
+ PuglBlob clipboard;
+ PuglNativeView parent;
+ uintptr_t transientParent;
+ PuglRect frame;
+ PuglEventConfigure lastConfigure;
+ PuglHints hints;
+ int defaultWidth;
+ int defaultHeight;
+ int minWidth;
+ int minHeight;
+ int maxWidth;
+ int maxHeight;
+ int minAspectX;
+ int minAspectY;
+ int maxAspectX;
+ int maxAspectY;
+ bool visible;
};
/// Cross-platform world definition
struct PuglWorldImpl {
- PuglWorldInternals* impl;
- PuglWorldHandle handle;
- char* className;
- double startTime;
- size_t numViews;
- PuglView** views;
+ PuglWorldInternals* impl;
+ PuglWorldHandle handle;
+ char* className;
+ double startTime;
+ size_t numViews;
+ PuglView** views;
};
/// Opaque surface used by graphics backend
@@ -89,23 +89,23 @@ typedef void PuglSurface;
/// Graphics backend interface
struct PuglBackendImpl {
- /// Get visual information from display and setup view as necessary
- PuglStatus (*configure)(PuglView*);
+ /// Get visual information from display and setup view as necessary
+ PuglStatus (*configure)(PuglView*);
- /// Create surface and drawing context
- PuglStatus (*create)(PuglView*);
+ /// Create surface and drawing context
+ PuglStatus (*create)(PuglView*);
- /// Destroy surface and drawing context
- PuglStatus (*destroy)(PuglView*);
+ /// Destroy surface and drawing context
+ PuglStatus (*destroy)(PuglView*);
- /// Enter drawing context, for drawing if expose is non-null
- PuglStatus (*enter)(PuglView*, const PuglEventExpose*);
+ /// Enter drawing context, for drawing if expose is non-null
+ PuglStatus (*enter)(PuglView*, const PuglEventExpose*);
- /// Leave drawing context, after drawing if expose is non-null
- PuglStatus (*leave)(PuglView*, const PuglEventExpose*);
+ /// Leave drawing context, after drawing if expose is non-null
+ PuglStatus (*leave)(PuglView*, const PuglEventExpose*);
- /// Return the puglGetContext() handle for the application, if any
- void* (*getContext)(PuglView*);
+ /// Return the puglGetContext() handle for the application, if any
+ void* (*getContext)(PuglView*);
};
#endif // PUGL_DETAIL_TYPES_H
diff --git a/src/win.c b/src/win.c
index 44033fc..664912b 100644
--- a/src/win.c
+++ b/src/win.c
@@ -32,24 +32,24 @@
#include <wctype.h>
#ifndef WM_MOUSEWHEEL
-# define WM_MOUSEWHEEL 0x020A
+# define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WM_MOUSEHWHEEL
-# define WM_MOUSEHWHEEL 0x020E
+# define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WHEEL_DELTA
-# define WHEEL_DELTA 120
+# define WHEEL_DELTA 120
#endif
#ifndef GWLP_USERDATA
-# define GWLP_USERDATA (-21)
+# define GWLP_USERDATA (-21)
#endif
-#define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50)
-#define PUGL_LOCAL_MARK_MSG (WM_USER + 51)
+#define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50)
+#define PUGL_LOCAL_MARK_MSG (WM_USER + 51)
#define PUGL_LOCAL_CLIENT_MSG (WM_USER + 52)
-#define PUGL_USER_TIMER_MIN 9470
+#define PUGL_USER_TIMER_MIN 9470
-typedef BOOL (WINAPI *PFN_SetProcessDPIAware)(void);
+typedef BOOL(WINAPI* PFN_SetProcessDPIAware)(void);
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
@@ -57,268 +57,267 @@ wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static wchar_t*
puglUtf8ToWideChar(const char* const utf8)
{
- const int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
- if (len > 0) {
- wchar_t* result = (wchar_t*)calloc((size_t)len, sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, utf8, -1, result, len);
- return result;
- }
-
- return NULL;
+ const int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
+ if (len > 0) {
+ wchar_t* result = (wchar_t*)calloc((size_t)len, sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, utf8, -1, result, len);
+ return result;
+ }
+
+ return NULL;
}
static char*
puglWideCharToUtf8(const wchar_t* const wstr, size_t* len)
{
- int n = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
- if (n > 0) {
- char* result = (char*)calloc((size_t)n, sizeof(char));
- WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, n, NULL, NULL);
- *len = (size_t)n;
- return result;
- }
-
- return NULL;
+ int n = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
+ if (n > 0) {
+ char* result = (char*)calloc((size_t)n, sizeof(char));
+ WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, n, NULL, NULL);
+ *len = (size_t)n;
+ return result;
+ }
+
+ return NULL;
}
static bool
puglRegisterWindowClass(const char* name)
{
- WNDCLASSEX wc = { 0 };
- if (GetClassInfoEx(GetModuleHandle(NULL), name, &wc)) {
- return true; // Already registered
- }
-
- wc.cbSize = sizeof(wc);
- wc.style = CS_OWNDC;
- wc.lpfnWndProc = wndProc;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszClassName = name;
-
- return RegisterClassEx(&wc);
+ WNDCLASSEX wc = {0};
+ if (GetClassInfoEx(GetModuleHandle(NULL), name, &wc)) {
+ return true; // Already registered
+ }
+
+ wc.cbSize = sizeof(wc);
+ wc.style = CS_OWNDC;
+ wc.lpfnWndProc = wndProc;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
+ wc.lpszClassName = name;
+
+ return RegisterClassEx(&wc);
}
PuglWorldInternals*
-puglInitWorldInternals(PuglWorldType PUGL_UNUSED(type),
+puglInitWorldInternals(PuglWorldType PUGL_UNUSED(type),
PuglWorldFlags PUGL_UNUSED(flags))
{
- PuglWorldInternals* impl = (PuglWorldInternals*)calloc(
- 1, sizeof(PuglWorldInternals));
- if (!impl) {
- return NULL;
- }
-
- HMODULE user32 = LoadLibrary("user32.dll");
- if (user32) {
- PFN_SetProcessDPIAware SetProcessDPIAware =
- (PFN_SetProcessDPIAware)GetProcAddress(
- user32, "SetProcessDPIAware");
- if (SetProcessDPIAware) {
- SetProcessDPIAware();
- }
-
- FreeLibrary(user32);
- }
-
- LARGE_INTEGER frequency;
- QueryPerformanceFrequency(&frequency);
- impl->timerFrequency = (double)frequency.QuadPart;
-
- return impl;
+ PuglWorldInternals* impl =
+ (PuglWorldInternals*)calloc(1, sizeof(PuglWorldInternals));
+ if (!impl) {
+ return NULL;
+ }
+
+ HMODULE user32 = LoadLibrary("user32.dll");
+ if (user32) {
+ PFN_SetProcessDPIAware SetProcessDPIAware =
+ (PFN_SetProcessDPIAware)GetProcAddress(user32, "SetProcessDPIAware");
+ if (SetProcessDPIAware) {
+ SetProcessDPIAware();
+ }
+
+ FreeLibrary(user32);
+ }
+
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+ impl->timerFrequency = (double)frequency.QuadPart;
+
+ return impl;
}
void*
puglGetNativeWorld(PuglWorld* PUGL_UNUSED(world))
{
- return GetModuleHandle(NULL);
+ return GetModuleHandle(NULL);
}
PuglInternals*
puglInitViewInternals(void)
{
- return (PuglInternals*)calloc(1, sizeof(PuglInternals));
+ return (PuglInternals*)calloc(1, sizeof(PuglInternals));
}
static PuglStatus
puglPollWinEvents(PuglWorld* world, const double timeout)
{
- (void)world;
-
- if (timeout < 0) {
- WaitMessage();
- } else {
- MsgWaitForMultipleObjects(
- 0, NULL, FALSE, (DWORD)(timeout * 1e3), QS_ALLEVENTS);
- }
- return PUGL_SUCCESS;
+ (void)world;
+
+ if (timeout < 0) {
+ WaitMessage();
+ } else {
+ MsgWaitForMultipleObjects(
+ 0, NULL, FALSE, (DWORD)(timeout * 1e3), QS_ALLEVENTS);
+ }
+ return PUGL_SUCCESS;
}
PuglStatus
puglRealize(PuglView* view)
{
- PuglInternals* impl = view->impl;
- if (impl->hwnd) {
- return PUGL_FAILURE;
- }
-
- // Getting depth from the display mode seems tedious, just set usual values
- if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_RED_BITS] = 8;
- }
- if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_BLUE_BITS] = 8;
- }
- if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_GREEN_BITS] = 8;
- }
- if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_ALPHA_BITS] = 8;
- }
-
- // Get refresh rate for resize draw timer
- DEVMODEA devMode = {0};
- EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devMode);
- view->hints[PUGL_REFRESH_RATE] = (int)devMode.dmDisplayFrequency;
-
- // Register window class if necessary
- if (!puglRegisterWindowClass(view->world->className)) {
- return PUGL_REGISTRATION_FAILED;
- }
-
- if (!view->backend || !view->backend->configure) {
- return PUGL_BAD_BACKEND;
- }
-
- PuglStatus st = PUGL_SUCCESS;
- if ((st = view->backend->configure(view)) ||
- (st = view->backend->create(view))) {
- return st;
- }
-
- if (view->title) {
- puglSetWindowTitle(view, view->title);
- }
-
- view->impl->cursor = LoadCursor(NULL, IDC_ARROW);
-
- puglSetFrame(view, view->frame);
- SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
-
- puglDispatchSimpleEvent(view, PUGL_CREATE);
-
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+ if (impl->hwnd) {
+ return PUGL_FAILURE;
+ }
+
+ // Getting depth from the display mode seems tedious, just set usual values
+ if (view->hints[PUGL_RED_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_RED_BITS] = 8;
+ }
+ if (view->hints[PUGL_BLUE_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_BLUE_BITS] = 8;
+ }
+ if (view->hints[PUGL_GREEN_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_GREEN_BITS] = 8;
+ }
+ if (view->hints[PUGL_ALPHA_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_ALPHA_BITS] = 8;
+ }
+
+ // Get refresh rate for resize draw timer
+ DEVMODEA devMode = {0};
+ EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devMode);
+ view->hints[PUGL_REFRESH_RATE] = (int)devMode.dmDisplayFrequency;
+
+ // Register window class if necessary
+ if (!puglRegisterWindowClass(view->world->className)) {
+ return PUGL_REGISTRATION_FAILED;
+ }
+
+ if (!view->backend || !view->backend->configure) {
+ return PUGL_BAD_BACKEND;
+ }
+
+ PuglStatus st = PUGL_SUCCESS;
+ if ((st = view->backend->configure(view)) ||
+ (st = view->backend->create(view))) {
+ return st;
+ }
+
+ if (view->title) {
+ puglSetWindowTitle(view, view->title);
+ }
+
+ view->impl->cursor = LoadCursor(NULL, IDC_ARROW);
+
+ puglSetFrame(view, view->frame);
+ SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
+
+ puglDispatchSimpleEvent(view, PUGL_CREATE);
+
+ return PUGL_SUCCESS;
}
PuglStatus
puglShow(PuglView* view)
{
- PuglInternals* impl = view->impl;
-
- if (!impl->hwnd) {
- const PuglStatus st = puglRealize(view);
- if (st) {
- return st;
- }
- }
-
- ShowWindow(impl->hwnd, SW_SHOWNORMAL);
- SetFocus(impl->hwnd);
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+
+ if (!impl->hwnd) {
+ const PuglStatus st = puglRealize(view);
+ if (st) {
+ return st;
+ }
+ }
+
+ ShowWindow(impl->hwnd, SW_SHOWNORMAL);
+ SetFocus(impl->hwnd);
+ return PUGL_SUCCESS;
}
PuglStatus
puglHide(PuglView* view)
{
- PuglInternals* impl = view->impl;
+ PuglInternals* impl = view->impl;
- ShowWindow(impl->hwnd, SW_HIDE);
- return PUGL_SUCCESS;
+ ShowWindow(impl->hwnd, SW_HIDE);
+ return PUGL_SUCCESS;
}
void
puglFreeViewInternals(PuglView* view)
{
- if (view) {
- if (view->backend) {
- view->backend->destroy(view);
- }
-
- ReleaseDC(view->impl->hwnd, view->impl->hdc);
- DestroyWindow(view->impl->hwnd);
- free(view->impl);
- }
+ if (view) {
+ if (view->backend) {
+ view->backend->destroy(view);
+ }
+
+ ReleaseDC(view->impl->hwnd, view->impl->hdc);
+ DestroyWindow(view->impl->hwnd);
+ free(view->impl);
+ }
}
void
puglFreeWorldInternals(PuglWorld* world)
{
- UnregisterClass(world->className, NULL);
- free(world->impl);
+ UnregisterClass(world->className, NULL);
+ free(world->impl);
}
static PuglKey
keySymToSpecial(WPARAM sym)
{
- // clang-format off
- switch (sym) {
- case VK_F1: return PUGL_KEY_F1;
- case VK_F2: return PUGL_KEY_F2;
- case VK_F3: return PUGL_KEY_F3;
- case VK_F4: return PUGL_KEY_F4;
- case VK_F5: return PUGL_KEY_F5;
- case VK_F6: return PUGL_KEY_F6;
- case VK_F7: return PUGL_KEY_F7;
- case VK_F8: return PUGL_KEY_F8;
- case VK_F9: return PUGL_KEY_F9;
- case VK_F10: return PUGL_KEY_F10;
- case VK_F11: return PUGL_KEY_F11;
- case VK_F12: return PUGL_KEY_F12;
- case VK_BACK: return PUGL_KEY_BACKSPACE;
- case VK_DELETE: return PUGL_KEY_DELETE;
- case VK_LEFT: return PUGL_KEY_LEFT;
- case VK_UP: return PUGL_KEY_UP;
- case VK_RIGHT: return PUGL_KEY_RIGHT;
- case VK_DOWN: return PUGL_KEY_DOWN;
- case VK_PRIOR: return PUGL_KEY_PAGE_UP;
- case VK_NEXT: return PUGL_KEY_PAGE_DOWN;
- case VK_HOME: return PUGL_KEY_HOME;
- case VK_END: return PUGL_KEY_END;
- case VK_INSERT: return PUGL_KEY_INSERT;
- case VK_SHIFT:
- case VK_LSHIFT: return PUGL_KEY_SHIFT_L;
- case VK_RSHIFT: return PUGL_KEY_SHIFT_R;
- case VK_CONTROL:
- case VK_LCONTROL: return PUGL_KEY_CTRL_L;
- case VK_RCONTROL: return PUGL_KEY_CTRL_R;
- case VK_MENU:
- case VK_LMENU: return PUGL_KEY_ALT_L;
- case VK_RMENU: return PUGL_KEY_ALT_R;
- case VK_LWIN: return PUGL_KEY_SUPER_L;
- case VK_RWIN: return PUGL_KEY_SUPER_R;
- case VK_CAPITAL: return PUGL_KEY_CAPS_LOCK;
- case VK_SCROLL: return PUGL_KEY_SCROLL_LOCK;
- case VK_NUMLOCK: return PUGL_KEY_NUM_LOCK;
- case VK_SNAPSHOT: return PUGL_KEY_PRINT_SCREEN;
- case VK_PAUSE: return PUGL_KEY_PAUSE;
- }
- // clang-format on
-
- return (PuglKey)0;
+ // clang-format off
+ switch (sym) {
+ case VK_F1: return PUGL_KEY_F1;
+ case VK_F2: return PUGL_KEY_F2;
+ case VK_F3: return PUGL_KEY_F3;
+ case VK_F4: return PUGL_KEY_F4;
+ case VK_F5: return PUGL_KEY_F5;
+ case VK_F6: return PUGL_KEY_F6;
+ case VK_F7: return PUGL_KEY_F7;
+ case VK_F8: return PUGL_KEY_F8;
+ case VK_F9: return PUGL_KEY_F9;
+ case VK_F10: return PUGL_KEY_F10;
+ case VK_F11: return PUGL_KEY_F11;
+ case VK_F12: return PUGL_KEY_F12;
+ case VK_BACK: return PUGL_KEY_BACKSPACE;
+ case VK_DELETE: return PUGL_KEY_DELETE;
+ case VK_LEFT: return PUGL_KEY_LEFT;
+ case VK_UP: return PUGL_KEY_UP;
+ case VK_RIGHT: return PUGL_KEY_RIGHT;
+ case VK_DOWN: return PUGL_KEY_DOWN;
+ case VK_PRIOR: return PUGL_KEY_PAGE_UP;
+ case VK_NEXT: return PUGL_KEY_PAGE_DOWN;
+ case VK_HOME: return PUGL_KEY_HOME;
+ case VK_END: return PUGL_KEY_END;
+ case VK_INSERT: return PUGL_KEY_INSERT;
+ case VK_SHIFT:
+ case VK_LSHIFT: return PUGL_KEY_SHIFT_L;
+ case VK_RSHIFT: return PUGL_KEY_SHIFT_R;
+ case VK_CONTROL:
+ case VK_LCONTROL: return PUGL_KEY_CTRL_L;
+ case VK_RCONTROL: return PUGL_KEY_CTRL_R;
+ case VK_MENU:
+ case VK_LMENU: return PUGL_KEY_ALT_L;
+ case VK_RMENU: return PUGL_KEY_ALT_R;
+ case VK_LWIN: return PUGL_KEY_SUPER_L;
+ case VK_RWIN: return PUGL_KEY_SUPER_R;
+ case VK_CAPITAL: return PUGL_KEY_CAPS_LOCK;
+ case VK_SCROLL: return PUGL_KEY_SCROLL_LOCK;
+ case VK_NUMLOCK: return PUGL_KEY_NUM_LOCK;
+ case VK_SNAPSHOT: return PUGL_KEY_PRINT_SCREEN;
+ case VK_PAUSE: return PUGL_KEY_PAUSE;
+ }
+ // clang-format on
+
+ return (PuglKey)0;
}
static uint32_t
getModifiers(void)
{
- // clang-format off
- return (((GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0u) |
- ((GetKeyState(VK_CONTROL) < 0) ? PUGL_MOD_CTRL : 0u) |
- ((GetKeyState(VK_MENU) < 0) ? PUGL_MOD_ALT : 0u) |
- ((GetKeyState(VK_LWIN) < 0) ? PUGL_MOD_SUPER : 0u) |
- ((GetKeyState(VK_RWIN) < 0) ? PUGL_MOD_SUPER : 0u));
- // clang-format on
+ // clang-format off
+ return (((GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0u) |
+ ((GetKeyState(VK_CONTROL) < 0) ? PUGL_MOD_CTRL : 0u) |
+ ((GetKeyState(VK_MENU) < 0) ? PUGL_MOD_ALT : 0u) |
+ ((GetKeyState(VK_LWIN) < 0) ? PUGL_MOD_SUPER : 0u) |
+ ((GetKeyState(VK_RWIN) < 0) ? PUGL_MOD_SUPER : 0u));
+ // clang-format on
}
static void
@@ -328,59 +327,59 @@ initMouseEvent(PuglEvent* event,
bool press,
LPARAM lParam)
{
- POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
- ClientToScreen(view->impl->hwnd, &pt);
-
- if (press) {
- SetCapture(view->impl->hwnd);
- } else {
- ReleaseCapture();
- }
-
- event->button.time = GetMessageTime() / 1e3;
- 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.xRoot = pt.x;
- event->button.yRoot = pt.y;
- event->button.state = getModifiers();
- event->button.button = (uint32_t)button;
+ POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ ClientToScreen(view->impl->hwnd, &pt);
+
+ if (press) {
+ SetCapture(view->impl->hwnd);
+ } else {
+ ReleaseCapture();
+ }
+
+ event->button.time = GetMessageTime() / 1e3;
+ 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.xRoot = pt.x;
+ event->button.yRoot = pt.y;
+ event->button.state = getModifiers();
+ event->button.button = (uint32_t)button;
}
static void
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 = GetMessageTime() / 1e3;
- event->scroll.type = PUGL_SCROLL;
- event->scroll.x = pt.x;
- event->scroll.y = pt.y;
- event->scroll.xRoot = GET_X_LPARAM(lParam);
- event->scroll.yRoot = GET_Y_LPARAM(lParam);
- event->scroll.state = getModifiers();
- event->scroll.dx = 0;
- event->scroll.dy = 0;
+ POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
+ ScreenToClient(view->impl->hwnd, &pt);
+
+ event->scroll.time = GetMessageTime() / 1e3;
+ event->scroll.type = PUGL_SCROLL;
+ event->scroll.x = pt.x;
+ event->scroll.y = pt.y;
+ event->scroll.xRoot = GET_X_LPARAM(lParam);
+ event->scroll.yRoot = GET_Y_LPARAM(lParam);
+ event->scroll.state = getModifiers();
+ event->scroll.dx = 0;
+ event->scroll.dy = 0;
}
/// Return the code point for buf, or the replacement character on error
static uint32_t
puglDecodeUTF16(const wchar_t* buf, const int len)
{
- const uint32_t c0 = buf[0];
- const uint32_t c1 = buf[0];
- if (c0 >= 0xD800 && c0 < 0xDC00) {
- if (len < 2) {
- return 0xFFFD; // Surrogate, but length is only 1
- } else if (c1 >= 0xDC00 && c1 <= 0xDFFF) {
- return ((c0 & 0x03FF) << 10) + (c1 & 0x03FF) + 0x10000;
- }
-
- return 0xFFFD; // Unpaired surrogates
- }
-
- return c0;
+ const uint32_t c0 = buf[0];
+ const uint32_t c1 = buf[0];
+ if (c0 >= 0xD800 && c0 < 0xDC00) {
+ if (len < 2) {
+ return 0xFFFD; // Surrogate, but length is only 1
+ } else if (c1 >= 0xDC00 && c1 <= 0xDFFF) {
+ return ((c0 & 0x03FF) << 10) + (c1 & 0x03FF) + 0x10000;
+ }
+
+ return 0xFFFD; // Unpaired surrogates
+ }
+
+ return c0;
}
static void
@@ -390,120 +389,120 @@ initKeyEvent(PuglEventKey* event,
WPARAM wParam,
LPARAM lParam)
{
- POINT rpos = { 0, 0 };
- GetCursorPos(&rpos);
-
- POINT cpos = { rpos.x, rpos.y };
- ScreenToClient(view->impl->hwnd, &rpos);
-
- const unsigned scode = (uint32_t)((lParam & 0xFF0000) >> 16);
- const unsigned vkey = ((wParam == VK_SHIFT)
- ? MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX)
- : (unsigned)wParam);
-
- const unsigned vcode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC);
- const unsigned kchar = MapVirtualKey(vkey, MAPVK_VK_TO_CHAR);
- const bool dead = kchar >> (sizeof(UINT) * 8 - 1) & 1;
- const bool ext = lParam & 0x01000000;
-
- event->type = press ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
- event->time = GetMessageTime() / 1e3;
- event->state = getModifiers();
- event->xRoot = rpos.x;
- event->yRoot = rpos.y;
- event->x = cpos.x;
- event->y = cpos.y;
- event->keycode = (uint32_t)((lParam & 0xFF0000) >> 16);
- event->key = 0;
-
- const PuglKey special = keySymToSpecial(vkey);
- if (special) {
- if (ext && (special == PUGL_KEY_CTRL || special == PUGL_KEY_ALT)) {
- event->key = (uint32_t)special + 1u; // Right hand key
- } else {
- event->key = (uint32_t)special;
- }
- } else if (!dead) {
- // Translate unshifted key
- BYTE keyboardState[256] = {0};
- wchar_t buf[5] = {0};
-
- event->key = puglDecodeUTF16(
- buf, ToUnicode(vkey, vcode, keyboardState, buf, 4, 1 << 2));
- }
+ POINT rpos = {0, 0};
+ GetCursorPos(&rpos);
+
+ POINT cpos = {rpos.x, rpos.y};
+ ScreenToClient(view->impl->hwnd, &rpos);
+
+ const unsigned scode = (uint32_t)((lParam & 0xFF0000) >> 16);
+ const unsigned vkey =
+ ((wParam == VK_SHIFT) ? MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX)
+ : (unsigned)wParam);
+
+ const unsigned vcode = MapVirtualKey(vkey, MAPVK_VK_TO_VSC);
+ const unsigned kchar = MapVirtualKey(vkey, MAPVK_VK_TO_CHAR);
+ const bool dead = kchar >> (sizeof(UINT) * 8 - 1) & 1;
+ const bool ext = lParam & 0x01000000;
+
+ event->type = press ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE;
+ event->time = GetMessageTime() / 1e3;
+ event->state = getModifiers();
+ event->xRoot = rpos.x;
+ event->yRoot = rpos.y;
+ event->x = cpos.x;
+ event->y = cpos.y;
+ event->keycode = (uint32_t)((lParam & 0xFF0000) >> 16);
+ event->key = 0;
+
+ const PuglKey special = keySymToSpecial(vkey);
+ if (special) {
+ if (ext && (special == PUGL_KEY_CTRL || special == PUGL_KEY_ALT)) {
+ event->key = (uint32_t)special + 1u; // Right hand key
+ } else {
+ event->key = (uint32_t)special;
+ }
+ } else if (!dead) {
+ // Translate unshifted key
+ BYTE keyboardState[256] = {0};
+ wchar_t buf[5] = {0};
+
+ event->key = puglDecodeUTF16(
+ buf, ToUnicode(vkey, vcode, keyboardState, buf, 4, 1 << 2));
+ }
}
static void
initCharEvent(PuglEvent* event, PuglView* view, WPARAM wParam, LPARAM lParam)
{
- const wchar_t utf16[2] = {wParam & 0xFFFF,
- (wchar_t)((wParam >> 16) & 0xFFFF)};
+ const wchar_t utf16[2] = {wParam & 0xFFFF,
+ (wchar_t)((wParam >> 16) & 0xFFFF)};
- initKeyEvent(&event->key, view, true, wParam, lParam);
- event->type = PUGL_TEXT;
- event->text.character = puglDecodeUTF16(utf16, 2);
+ initKeyEvent(&event->key, view, true, wParam, lParam);
+ event->type = PUGL_TEXT;
+ event->text.character = puglDecodeUTF16(utf16, 2);
- if (!WideCharToMultiByte(
- CP_UTF8, 0, utf16, 2, event->text.string, 8, NULL, NULL)) {
- memset(event->text.string, 0, 8);
- }
+ if (!WideCharToMultiByte(
+ CP_UTF8, 0, utf16, 2, event->text.string, 8, NULL, NULL)) {
+ memset(event->text.string, 0, 8);
+ }
}
static bool
ignoreKeyEvent(PuglView* view, LPARAM lParam)
{
- return view->hints[PUGL_IGNORE_KEY_REPEAT] && (lParam & (1 << 30));
+ return view->hints[PUGL_IGNORE_KEY_REPEAT] && (lParam & (1 << 30));
}
static RECT
handleConfigure(PuglView* view, PuglEvent* event)
{
- RECT rect;
- GetClientRect(view->impl->hwnd, &rect);
- MapWindowPoints(view->impl->hwnd,
- view->parent ? (HWND)view->parent : HWND_DESKTOP,
- (LPPOINT)&rect,
- 2);
-
- const LONG width = rect.right - rect.left;
- const LONG height = rect.bottom - rect.top;
-
- view->frame.x = rect.left;
- view->frame.y = rect.top;
-
- event->configure.type = PUGL_CONFIGURE;
- event->configure.x = view->frame.x;
- event->configure.y = view->frame.y;
- event->configure.width = width;
- event->configure.height = height;
-
- if (view->frame.width != width || view->frame.height != height) {
- view->frame.width = width;
- view->frame.height = height;
- }
-
- return rect;
+ RECT rect;
+ GetClientRect(view->impl->hwnd, &rect);
+ MapWindowPoints(view->impl->hwnd,
+ view->parent ? (HWND)view->parent : HWND_DESKTOP,
+ (LPPOINT)&rect,
+ 2);
+
+ const LONG width = rect.right - rect.left;
+ const LONG height = rect.bottom - rect.top;
+
+ view->frame.x = rect.left;
+ view->frame.y = rect.top;
+
+ event->configure.type = PUGL_CONFIGURE;
+ event->configure.x = view->frame.x;
+ event->configure.y = view->frame.y;
+ event->configure.width = width;
+ event->configure.height = height;
+
+ if (view->frame.width != width || view->frame.height != height) {
+ view->frame.width = width;
+ view->frame.height = height;
+ }
+
+ return rect;
}
static void
handleCrossing(PuglView* view, const PuglEventType type, POINT pos)
{
- POINT root_pos = pos;
- ClientToScreen(view->impl->hwnd, &root_pos);
-
- const PuglEventCrossing ev = {
- type,
- 0,
- GetMessageTime() / 1e3,
- (double)pos.x,
- (double)pos.y,
- (double)root_pos.x,
- (double)root_pos.y,
- getModifiers(),
- PUGL_CROSSING_NORMAL,
- };
-
- puglDispatchEvent(view, (const PuglEvent*)&ev);
+ POINT root_pos = pos;
+ ClientToScreen(view->impl->hwnd, &root_pos);
+
+ const PuglEventCrossing ev = {
+ type,
+ 0,
+ GetMessageTime() / 1e3,
+ (double)pos.x,
+ (double)pos.y,
+ (double)root_pos.x,
+ (double)root_pos.y,
+ getModifiers(),
+ PUGL_CROSSING_NORMAL,
+ };
+
+ puglDispatchEvent(view, (const PuglEvent*)&ev);
}
static void
@@ -511,501 +510,497 @@ constrainAspect(const PuglView* const view,
RECT* const size,
const WPARAM wParam)
{
- const float minA = (float)view->minAspectX / (float)view->minAspectY;
- const float maxA = (float)view->maxAspectX / (float)view->maxAspectY;
- const float w = (float)(size->right - size->left);
- const float h = (float)(size->bottom - size->top);
- const float a = w / h;
-
- switch (wParam) {
- case WMSZ_TOP:
- size->top = (a < minA ? (LONG)((float)size->bottom - w * minA) :
- a > maxA ? (LONG)((float)size->bottom - w * maxA) :
- size->top);
- break;
- case WMSZ_TOPRIGHT:
- case WMSZ_RIGHT:
- case WMSZ_BOTTOMRIGHT:
- size->right = (a < minA ? (LONG)((float)size->left + h * minA) :
- a > maxA ? (LONG)((float)size->left + h * maxA) :
- size->right);
- break;
- case WMSZ_BOTTOM:
- size->bottom = (a < minA ? (LONG)((float)size->top + w * minA) :
- a > maxA ? (LONG)((float)size->top + w * maxA) :
- size->bottom);
- break;
- case WMSZ_BOTTOMLEFT:
- case WMSZ_LEFT:
- case WMSZ_TOPLEFT:
- size->left = (a < minA ? (LONG)((float)size->right - h * minA) :
- a > maxA ? (LONG)((float)size->right - h * maxA) :
- size->left);
- break;
- }
+ const float minA = (float)view->minAspectX / (float)view->minAspectY;
+ const float maxA = (float)view->maxAspectX / (float)view->maxAspectY;
+ const float w = (float)(size->right - size->left);
+ const float h = (float)(size->bottom - size->top);
+ const float a = w / h;
+
+ switch (wParam) {
+ case WMSZ_TOP:
+ size->top = (a < minA ? (LONG)((float)size->bottom - w * minA)
+ : a > maxA ? (LONG)((float)size->bottom - w * maxA)
+ : size->top);
+ break;
+ case WMSZ_TOPRIGHT:
+ case WMSZ_RIGHT:
+ case WMSZ_BOTTOMRIGHT:
+ size->right = (a < minA ? (LONG)((float)size->left + h * minA)
+ : a > maxA ? (LONG)((float)size->left + h * maxA)
+ : size->right);
+ break;
+ case WMSZ_BOTTOM:
+ size->bottom = (a < minA ? (LONG)((float)size->top + w * minA)
+ : a > maxA ? (LONG)((float)size->top + w * maxA)
+ : size->bottom);
+ break;
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_LEFT:
+ case WMSZ_TOPLEFT:
+ size->left = (a < minA ? (LONG)((float)size->right - h * minA)
+ : a > maxA ? (LONG)((float)size->right - h * maxA)
+ : size->left);
+ break;
+ }
}
static LRESULT
handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
{
- PuglEvent event = {{PUGL_NOTHING, 0}};
- RECT rect = {0, 0, 0, 0};
- POINT pt = {0, 0};
- MINMAXINFO* mmi = NULL;
- void* dummy_ptr = NULL;
-
- if (InSendMessageEx(dummy_ptr)) {
- event.any.flags |= PUGL_IS_SEND_EVENT;
- }
-
- switch (message) {
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT) {
- SetCursor(view->impl->cursor);
- } else {
- return DefWindowProc(view->impl->hwnd, message, wParam, lParam);
- }
- break;
- case WM_SHOWWINDOW:
- if (wParam) {
- handleConfigure(view, &event);
- puglDispatchEvent(view, &event);
- event.type = PUGL_NOTHING;
-
- RedrawWindow(view->impl->hwnd, NULL, NULL,
- RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_INTERNALPAINT);
- }
-
- if ((bool)wParam != view->visible) {
- view->visible = wParam;
- event.any.type = wParam ? PUGL_MAP : PUGL_UNMAP;
- }
- break;
- case WM_SIZE:
- handleConfigure(view, &event);
- InvalidateRect(view->impl->hwnd, NULL, false);
- break;
- case WM_SIZING:
- if (view->minAspectX) {
- constrainAspect(view, (RECT*)lParam, wParam);
- return TRUE;
- }
- break;
- case WM_ENTERSIZEMOVE:
- case WM_ENTERMENULOOP:
- puglDispatchSimpleEvent(view, PUGL_LOOP_ENTER);
- break;
- case WM_TIMER:
- if (wParam >= PUGL_USER_TIMER_MIN) {
- PuglEvent ev = {{PUGL_TIMER, 0}};
- ev.timer.id = wParam - PUGL_USER_TIMER_MIN;
- puglDispatchEvent(view, &ev);
- }
- break;
- case WM_EXITSIZEMOVE:
- case WM_EXITMENULOOP:
- puglDispatchSimpleEvent(view, PUGL_LOOP_LEAVE);
- break;
- case WM_GETMINMAXINFO:
- mmi = (MINMAXINFO*)lParam;
- mmi->ptMinTrackSize.x = view->minWidth;
- mmi->ptMinTrackSize.y = view->minHeight;
- if (view->maxWidth > 0 && view->maxHeight > 0) {
- mmi->ptMaxTrackSize.x = view->maxWidth;
- mmi->ptMaxTrackSize.y = view->maxHeight;
- }
- break;
- case WM_PAINT:
- GetUpdateRect(view->impl->hwnd, &rect, false);
- event.expose.type = PUGL_EXPOSE;
- event.expose.x = rect.left;
- event.expose.y = rect.top;
- event.expose.width = rect.right - rect.left;
- event.expose.height = rect.bottom - rect.top;
- break;
- case WM_ERASEBKGND:
- return true;
- case WM_MOUSEMOVE:
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
-
- if (!view->impl->mouseTracked) {
- TRACKMOUSEEVENT tme = {0};
-
- tme.cbSize = sizeof(tme);
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = view->impl->hwnd;
- TrackMouseEvent(&tme);
-
- handleCrossing(view, PUGL_POINTER_IN, pt);
- view->impl->mouseTracked = true;
- }
-
- ClientToScreen(view->impl->hwnd, &pt);
- event.motion.type = PUGL_MOTION;
- event.motion.time = GetMessageTime() / 1e3;
- event.motion.x = GET_X_LPARAM(lParam);
- event.motion.y = GET_Y_LPARAM(lParam);
- event.motion.xRoot = pt.x;
- event.motion.yRoot = pt.y;
- event.motion.state = getModifiers();
- break;
- case WM_MOUSELEAVE:
- GetCursorPos(&pt);
- ScreenToClient(view->impl->hwnd, &pt);
- handleCrossing(view, PUGL_POINTER_OUT, pt);
- view->impl->mouseTracked = false;
- break;
- case WM_LBUTTONDOWN:
- initMouseEvent(&event, view, 1, true, lParam);
- break;
- case WM_MBUTTONDOWN:
- initMouseEvent(&event, view, 2, true, lParam);
- break;
- case WM_RBUTTONDOWN:
- initMouseEvent(&event, view, 3, true, lParam);
- break;
- case WM_LBUTTONUP:
- initMouseEvent(&event, view, 1, false, lParam);
- break;
- case WM_MBUTTONUP:
- initMouseEvent(&event, view, 2, false, lParam);
- break;
- case WM_RBUTTONUP:
- initMouseEvent(&event, view, 3, false, lParam);
- break;
- case WM_MOUSEWHEEL:
- initScrollEvent(&event, view, lParam);
- event.scroll.dy = GET_WHEEL_DELTA_WPARAM(wParam) / (double)WHEEL_DELTA;
- event.scroll.direction = (event.scroll.dy > 0
- ? PUGL_SCROLL_UP
- : PUGL_SCROLL_DOWN);
- break;
- case WM_MOUSEHWHEEL:
- initScrollEvent(&event, view, lParam);
- event.scroll.dx = GET_WHEEL_DELTA_WPARAM(wParam) / (double)WHEEL_DELTA;
- event.scroll.direction = (event.scroll.dx > 0
- ? PUGL_SCROLL_RIGHT
- : PUGL_SCROLL_LEFT);
- break;
- case WM_KEYDOWN:
- if (!ignoreKeyEvent(view, lParam)) {
- initKeyEvent(&event.key, view, true, wParam, lParam);
- }
- break;
- case WM_KEYUP:
- initKeyEvent(&event.key, view, false, wParam, lParam);
- break;
- case WM_CHAR:
- initCharEvent(&event, view, wParam, lParam);
- break;
- case WM_SETFOCUS:
- event.type = PUGL_FOCUS_IN;
- break;
- case WM_KILLFOCUS:
- event.type = PUGL_FOCUS_OUT;
- break;
- case WM_SYSKEYDOWN:
- initKeyEvent(&event.key, view, true, wParam, lParam);
- break;
- case WM_SYSKEYUP:
- initKeyEvent(&event.key, view, false, wParam, lParam);
- break;
- case WM_SYSCHAR:
- return TRUE;
- case PUGL_LOCAL_CLIENT_MSG:
- event.client.type = PUGL_CLIENT;
- event.client.data1 = (uintptr_t)wParam;
- event.client.data2 = (uintptr_t)lParam;
- break;
- case WM_QUIT:
- case PUGL_LOCAL_CLOSE_MSG:
- event.any.type = PUGL_CLOSE;
- break;
- default:
- return DefWindowProc(view->impl->hwnd, message, wParam, lParam);
- }
-
- puglDispatchEvent(view, &event);
-
- return 0;
+ PuglEvent event = {{PUGL_NOTHING, 0}};
+ RECT rect = {0, 0, 0, 0};
+ POINT pt = {0, 0};
+ MINMAXINFO* mmi = NULL;
+ void* dummy_ptr = NULL;
+
+ if (InSendMessageEx(dummy_ptr)) {
+ event.any.flags |= PUGL_IS_SEND_EVENT;
+ }
+
+ switch (message) {
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT) {
+ SetCursor(view->impl->cursor);
+ } else {
+ return DefWindowProc(view->impl->hwnd, message, wParam, lParam);
+ }
+ break;
+ case WM_SHOWWINDOW:
+ if (wParam) {
+ handleConfigure(view, &event);
+ puglDispatchEvent(view, &event);
+ event.type = PUGL_NOTHING;
+
+ RedrawWindow(view->impl->hwnd,
+ NULL,
+ NULL,
+ RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_INTERNALPAINT);
+ }
+
+ if ((bool)wParam != view->visible) {
+ view->visible = wParam;
+ event.any.type = wParam ? PUGL_MAP : PUGL_UNMAP;
+ }
+ break;
+ case WM_SIZE:
+ handleConfigure(view, &event);
+ InvalidateRect(view->impl->hwnd, NULL, false);
+ break;
+ case WM_SIZING:
+ if (view->minAspectX) {
+ constrainAspect(view, (RECT*)lParam, wParam);
+ return TRUE;
+ }
+ break;
+ case WM_ENTERSIZEMOVE:
+ case WM_ENTERMENULOOP:
+ puglDispatchSimpleEvent(view, PUGL_LOOP_ENTER);
+ break;
+ case WM_TIMER:
+ if (wParam >= PUGL_USER_TIMER_MIN) {
+ PuglEvent ev = {{PUGL_TIMER, 0}};
+ ev.timer.id = wParam - PUGL_USER_TIMER_MIN;
+ puglDispatchEvent(view, &ev);
+ }
+ break;
+ case WM_EXITSIZEMOVE:
+ case WM_EXITMENULOOP:
+ puglDispatchSimpleEvent(view, PUGL_LOOP_LEAVE);
+ break;
+ case WM_GETMINMAXINFO:
+ mmi = (MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x = view->minWidth;
+ mmi->ptMinTrackSize.y = view->minHeight;
+ if (view->maxWidth > 0 && view->maxHeight > 0) {
+ mmi->ptMaxTrackSize.x = view->maxWidth;
+ mmi->ptMaxTrackSize.y = view->maxHeight;
+ }
+ break;
+ case WM_PAINT:
+ GetUpdateRect(view->impl->hwnd, &rect, false);
+ event.expose.type = PUGL_EXPOSE;
+ event.expose.x = rect.left;
+ event.expose.y = rect.top;
+ event.expose.width = rect.right - rect.left;
+ event.expose.height = rect.bottom - rect.top;
+ break;
+ case WM_ERASEBKGND:
+ return true;
+ case WM_MOUSEMOVE:
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+
+ if (!view->impl->mouseTracked) {
+ TRACKMOUSEEVENT tme = {0};
+
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = view->impl->hwnd;
+ TrackMouseEvent(&tme);
+
+ handleCrossing(view, PUGL_POINTER_IN, pt);
+ view->impl->mouseTracked = true;
+ }
+
+ ClientToScreen(view->impl->hwnd, &pt);
+ event.motion.type = PUGL_MOTION;
+ event.motion.time = GetMessageTime() / 1e3;
+ event.motion.x = GET_X_LPARAM(lParam);
+ event.motion.y = GET_Y_LPARAM(lParam);
+ event.motion.xRoot = pt.x;
+ event.motion.yRoot = pt.y;
+ event.motion.state = getModifiers();
+ break;
+ case WM_MOUSELEAVE:
+ GetCursorPos(&pt);
+ ScreenToClient(view->impl->hwnd, &pt);
+ handleCrossing(view, PUGL_POINTER_OUT, pt);
+ view->impl->mouseTracked = false;
+ break;
+ case WM_LBUTTONDOWN:
+ initMouseEvent(&event, view, 1, true, lParam);
+ break;
+ case WM_MBUTTONDOWN:
+ initMouseEvent(&event, view, 2, true, lParam);
+ break;
+ case WM_RBUTTONDOWN:
+ initMouseEvent(&event, view, 3, true, lParam);
+ break;
+ case WM_LBUTTONUP:
+ initMouseEvent(&event, view, 1, false, lParam);
+ break;
+ case WM_MBUTTONUP:
+ initMouseEvent(&event, view, 2, false, lParam);
+ break;
+ case WM_RBUTTONUP:
+ initMouseEvent(&event, view, 3, false, lParam);
+ break;
+ case WM_MOUSEWHEEL:
+ initScrollEvent(&event, view, lParam);
+ event.scroll.dy = GET_WHEEL_DELTA_WPARAM(wParam) / (double)WHEEL_DELTA;
+ event.scroll.direction =
+ (event.scroll.dy > 0 ? PUGL_SCROLL_UP : PUGL_SCROLL_DOWN);
+ break;
+ case WM_MOUSEHWHEEL:
+ initScrollEvent(&event, view, lParam);
+ event.scroll.dx = GET_WHEEL_DELTA_WPARAM(wParam) / (double)WHEEL_DELTA;
+ event.scroll.direction =
+ (event.scroll.dx > 0 ? PUGL_SCROLL_RIGHT : PUGL_SCROLL_LEFT);
+ break;
+ case WM_KEYDOWN:
+ if (!ignoreKeyEvent(view, lParam)) {
+ initKeyEvent(&event.key, view, true, wParam, lParam);
+ }
+ break;
+ case WM_KEYUP:
+ initKeyEvent(&event.key, view, false, wParam, lParam);
+ break;
+ case WM_CHAR:
+ initCharEvent(&event, view, wParam, lParam);
+ break;
+ case WM_SETFOCUS:
+ event.type = PUGL_FOCUS_IN;
+ break;
+ case WM_KILLFOCUS:
+ event.type = PUGL_FOCUS_OUT;
+ break;
+ case WM_SYSKEYDOWN:
+ initKeyEvent(&event.key, view, true, wParam, lParam);
+ break;
+ case WM_SYSKEYUP:
+ initKeyEvent(&event.key, view, false, wParam, lParam);
+ break;
+ case WM_SYSCHAR:
+ return TRUE;
+ case PUGL_LOCAL_CLIENT_MSG:
+ event.client.type = PUGL_CLIENT;
+ event.client.data1 = (uintptr_t)wParam;
+ event.client.data2 = (uintptr_t)lParam;
+ break;
+ case WM_QUIT:
+ case PUGL_LOCAL_CLOSE_MSG:
+ event.any.type = PUGL_CLOSE;
+ break;
+ default:
+ return DefWindowProc(view->impl->hwnd, message, wParam, lParam);
+ }
+
+ puglDispatchEvent(view, &event);
+
+ return 0;
}
PuglStatus
puglGrabFocus(PuglView* view)
{
- SetFocus(view->impl->hwnd);
- return PUGL_SUCCESS;
+ SetFocus(view->impl->hwnd);
+ return PUGL_SUCCESS;
}
bool
puglHasFocus(const PuglView* view)
{
- return GetFocus() == view->impl->hwnd;
+ return GetFocus() == view->impl->hwnd;
}
PuglStatus
puglRequestAttention(PuglView* view)
{
- FLASHWINFO info = {sizeof(FLASHWINFO),
- view->impl->hwnd,
- FLASHW_ALL|FLASHW_TIMERNOFG,
- 1,
- 0};
+ FLASHWINFO info = {
+ sizeof(FLASHWINFO), view->impl->hwnd, FLASHW_ALL | FLASHW_TIMERNOFG, 1, 0};
- FlashWindowEx(&info);
+ FlashWindowEx(&info);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglStartTimer(PuglView* view, uintptr_t id, double timeout)
{
- const UINT msec = (UINT)floor(timeout * 1000.0);
+ const UINT msec = (UINT)floor(timeout * 1000.0);
- return (SetTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id, msec, NULL)
- ? PUGL_SUCCESS
- : PUGL_UNKNOWN_ERROR);
+ return (SetTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id, msec, NULL)
+ ? PUGL_SUCCESS
+ : PUGL_UNKNOWN_ERROR);
}
PuglStatus
puglStopTimer(PuglView* view, uintptr_t id)
{
- return (KillTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id)
- ? PUGL_SUCCESS
- : PUGL_UNKNOWN_ERROR);
+ return (KillTimer(view->impl->hwnd, PUGL_USER_TIMER_MIN + id)
+ ? PUGL_SUCCESS
+ : PUGL_UNKNOWN_ERROR);
}
PuglStatus
puglSendEvent(PuglView* view, const PuglEvent* event)
{
- if (event->type == PUGL_CLIENT) {
- PostMessage(view->impl->hwnd,
- PUGL_LOCAL_CLIENT_MSG,
- (WPARAM)event->client.data1,
- (LPARAM)event->client.data2);
+ if (event->type == PUGL_CLIENT) {
+ PostMessage(view->impl->hwnd,
+ PUGL_LOCAL_CLIENT_MSG,
+ (WPARAM)event->client.data1,
+ (LPARAM)event->client.data2);
- return PUGL_SUCCESS;
- }
+ return PUGL_SUCCESS;
+ }
- return PUGL_UNSUPPORTED_TYPE;
+ return PUGL_UNSUPPORTED_TYPE;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglWaitForEvent(PuglView* PUGL_UNUSED(view))
{
- WaitMessage();
- return PUGL_SUCCESS;
+ WaitMessage();
+ return PUGL_SUCCESS;
}
#endif
static PuglStatus
puglDispatchViewEvents(PuglView* view)
{
- /* Windows has no facility to process only currently queued messages, which
- causes the event loop to run forever in cases like mouse movement where
- the queue is constantly being filled with new messages. To work around
- this, we post a message to ourselves before starting, record its time
- when it is received, then break the loop on the first message that was
- created afterwards. */
-
- long markTime = 0;
- MSG msg;
- while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) {
- if (msg.message == PUGL_LOCAL_MARK_MSG) {
- markTime = GetMessageTime();
- } else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- if (markTime != 0 && GetMessageTime() > markTime) {
- break;
- }
- }
- }
-
- return PUGL_SUCCESS;
+ /* Windows has no facility to process only currently queued messages, which
+ causes the event loop to run forever in cases like mouse movement where
+ the queue is constantly being filled with new messages. To work around
+ this, we post a message to ourselves before starting, record its time
+ when it is received, then break the loop on the first message that was
+ created afterwards. */
+
+ long markTime = 0;
+ MSG msg;
+ while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) {
+ if (msg.message == PUGL_LOCAL_MARK_MSG) {
+ markTime = GetMessageTime();
+ } else {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ if (markTime != 0 && GetMessageTime() > markTime) {
+ break;
+ }
+ }
+ }
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglDispatchWinEvents(PuglWorld* world)
{
- for (size_t i = 0; i < world->numViews; ++i) {
- PostMessage(world->views[i]->impl->hwnd, PUGL_LOCAL_MARK_MSG, 0, 0);
- }
+ for (size_t i = 0; i < world->numViews; ++i) {
+ PostMessage(world->views[i]->impl->hwnd, PUGL_LOCAL_MARK_MSG, 0, 0);
+ }
- for (size_t i = 0; i < world->numViews; ++i) {
- puglDispatchViewEvents(world->views[i]);
- }
+ for (size_t i = 0; i < world->numViews; ++i) {
+ puglDispatchViewEvents(world->views[i]);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglUpdate(PuglWorld* world, double timeout)
{
- const double startTime = puglGetTime(world);
- PuglStatus st = PUGL_SUCCESS;
-
- if (timeout < 0.0) {
- st = puglPollWinEvents(world, timeout);
- st = st ? st : puglDispatchWinEvents(world);
- } else if (timeout == 0.0) {
- st = puglDispatchWinEvents(world);
- } else {
- const double endTime = startTime + timeout - 0.001;
- for (double t = startTime; t < endTime; t = puglGetTime(world)) {
- if ((st = puglPollWinEvents(world, endTime - t)) ||
- (st = puglDispatchWinEvents(world))) {
- break;
- }
- }
- }
-
- for (size_t i = 0; i < world->numViews; ++i) {
- if (world->views[i]->visible) {
- puglDispatchSimpleEvent(world->views[i], PUGL_UPDATE);
- }
-
- UpdateWindow(world->views[i]->impl->hwnd);
- }
-
- return st;
+ const double startTime = puglGetTime(world);
+ PuglStatus st = PUGL_SUCCESS;
+
+ if (timeout < 0.0) {
+ st = puglPollWinEvents(world, timeout);
+ st = st ? st : puglDispatchWinEvents(world);
+ } else if (timeout == 0.0) {
+ st = puglDispatchWinEvents(world);
+ } else {
+ const double endTime = startTime + timeout - 0.001;
+ for (double t = startTime; t < endTime; t = puglGetTime(world)) {
+ if ((st = puglPollWinEvents(world, endTime - t)) ||
+ (st = puglDispatchWinEvents(world))) {
+ break;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < world->numViews; ++i) {
+ if (world->views[i]->visible) {
+ puglDispatchSimpleEvent(world->views[i], PUGL_UPDATE);
+ }
+
+ UpdateWindow(world->views[i]->impl->hwnd);
+ }
+
+ return st;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglProcessEvents(PuglView* view)
{
- return puglUpdate(view->world, 0.0);
+ return puglUpdate(view->world, 0.0);
}
#endif
LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
- PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
- switch (message) {
- case WM_CREATE:
- PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
- return 0;
- case WM_CLOSE:
- PostMessage(hwnd, PUGL_LOCAL_CLOSE_MSG, wParam, lParam);
- return 0;
- case WM_DESTROY:
- return 0;
- default:
- if (view && hwnd == view->impl->hwnd) {
- return handleMessage(view, message, wParam, lParam);
- } else {
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- }
+ PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+ switch (message) {
+ case WM_CREATE:
+ PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
+ return 0;
+ case WM_CLOSE:
+ PostMessage(hwnd, PUGL_LOCAL_CLOSE_MSG, wParam, lParam);
+ return 0;
+ case WM_DESTROY:
+ return 0;
+ default:
+ if (view && hwnd == view->impl->hwnd) {
+ return handleMessage(view, message, wParam, lParam);
+ } else {
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ }
}
double
puglGetTime(const PuglWorld* world)
{
- LARGE_INTEGER count;
- QueryPerformanceCounter(&count);
- return ((double)count.QuadPart / world->impl->timerFrequency -
- world->startTime);
+ LARGE_INTEGER count;
+ QueryPerformanceCounter(&count);
+ return ((double)count.QuadPart / world->impl->timerFrequency -
+ world->startTime);
}
PuglStatus
puglPostRedisplay(PuglView* view)
{
- InvalidateRect(view->impl->hwnd, NULL, false);
- return PUGL_SUCCESS;
+ InvalidateRect(view->impl->hwnd, NULL, false);
+ return PUGL_SUCCESS;
}
PuglStatus
puglPostRedisplayRect(PuglView* view, const PuglRect rect)
{
- const RECT r = {(long)floor(rect.x),
- (long)floor(rect.y),
- (long)ceil(rect.x + rect.width),
- (long)ceil(rect.y + rect.height)};
+ const RECT r = {(long)floor(rect.x),
+ (long)floor(rect.y),
+ (long)ceil(rect.x + rect.width),
+ (long)ceil(rect.y + rect.height)};
- InvalidateRect(view->impl->hwnd, &r, false);
+ InvalidateRect(view->impl->hwnd, &r, false);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglNativeView
puglGetNativeWindow(PuglView* view)
{
- return (PuglNativeView)view->impl->hwnd;
+ return (PuglNativeView)view->impl->hwnd;
}
PuglStatus
puglSetWindowTitle(PuglView* view, const char* title)
{
- puglSetString(&view->title, title);
+ puglSetString(&view->title, title);
- if (view->impl->hwnd) {
- wchar_t* wtitle = puglUtf8ToWideChar(title);
- if (wtitle) {
- SetWindowTextW(view->impl->hwnd, wtitle);
- free(wtitle);
- }
- }
+ if (view->impl->hwnd) {
+ wchar_t* wtitle = puglUtf8ToWideChar(title);
+ if (wtitle) {
+ SetWindowTextW(view->impl->hwnd, wtitle);
+ free(wtitle);
+ }
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{
- view->frame = frame;
-
- if (view->impl->hwnd) {
- RECT rect = { (long)frame.x,
- (long)frame.y,
- (long)frame.x + (long)frame.width,
- (long)frame.y + (long)frame.height };
-
- AdjustWindowRectEx(&rect, puglWinGetWindowFlags(view),
- FALSE,
- puglWinGetWindowExFlags(view));
-
- if (!SetWindowPos(view->impl->hwnd,
- HWND_TOP,
- rect.left,
- rect.top,
- rect.right - rect.left,
- rect.bottom - rect.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER)) {
- return PUGL_UNKNOWN_ERROR;
- }
- }
-
- return PUGL_SUCCESS;
+ view->frame = frame;
+
+ if (view->impl->hwnd) {
+ RECT rect = {(long)frame.x,
+ (long)frame.y,
+ (long)frame.x + (long)frame.width,
+ (long)frame.y + (long)frame.height};
+
+ AdjustWindowRectEx(
+ &rect, puglWinGetWindowFlags(view), FALSE, puglWinGetWindowExFlags(view));
+
+ if (!SetWindowPos(view->impl->hwnd,
+ HWND_TOP,
+ rect.left,
+ rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+ }
+
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetDefaultSize(PuglView* const view, const int width, const int height)
{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return PUGL_SUCCESS;
+ view->defaultWidth = width;
+ view->defaultHeight = height;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetMinSize(PuglView* const view, const int width, const int height)
{
- view->minWidth = width;
- view->minHeight = height;
- return PUGL_SUCCESS;
+ view->minWidth = width;
+ view->minHeight = height;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetMaxSize(PuglView* const view, const int width, const int height)
{
- view->maxWidth = width;
- view->maxHeight = height;
- return PUGL_SUCCESS;
+ view->maxWidth = width;
+ view->maxHeight = height;
+ return PUGL_SUCCESS;
}
PuglStatus
@@ -1015,28 +1010,28 @@ puglSetAspectRatio(PuglView* const view,
const int maxX,
const int maxY)
{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
- return PUGL_SUCCESS;
+ view->minAspectX = minX;
+ view->minAspectY = minY;
+ view->maxAspectX = maxX;
+ view->maxAspectY = maxY;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetTransientFor(PuglView* view, PuglNativeView parent)
{
- if (view->parent) {
- return PUGL_FAILURE;
- }
+ if (view->parent) {
+ return PUGL_FAILURE;
+ }
- view->transientParent = parent;
+ view->transientParent = parent;
- if (view->impl->hwnd) {
- SetWindowLongPtr(view->impl->hwnd, GWLP_HWNDPARENT, (LONG_PTR)parent);
- return GetLastError() == NO_ERROR ? PUGL_SUCCESS : PUGL_FAILURE;
- }
+ if (view->impl->hwnd) {
+ SetWindowLongPtr(view->impl->hwnd, GWLP_HWNDPARENT, (LONG_PTR)parent);
+ return GetLastError() == NO_ERROR ? PUGL_SUCCESS : PUGL_FAILURE;
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
const void*
@@ -1044,26 +1039,26 @@ puglGetClipboard(PuglView* const view,
const char** const type,
size_t* const len)
{
- PuglInternals* const impl = view->impl;
-
- if (!IsClipboardFormatAvailable(CF_UNICODETEXT) ||
- !OpenClipboard(impl->hwnd)) {
- return NULL;
- }
-
- HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
- wchar_t* wstr = mem ? (wchar_t*)GlobalLock(mem) : NULL;
- if (!wstr) {
- CloseClipboard();
- return NULL;
- }
-
- free(view->clipboard.data);
- view->clipboard.data = puglWideCharToUtf8(wstr, &view->clipboard.len);
- GlobalUnlock(mem);
- CloseClipboard();
-
- return puglGetInternalClipboard(view, type, len);
+ PuglInternals* const impl = view->impl;
+
+ if (!IsClipboardFormatAvailable(CF_UNICODETEXT) ||
+ !OpenClipboard(impl->hwnd)) {
+ return NULL;
+ }
+
+ HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
+ wchar_t* wstr = mem ? (wchar_t*)GlobalLock(mem) : NULL;
+ if (!wstr) {
+ CloseClipboard();
+ return NULL;
+ }
+
+ free(view->clipboard.data);
+ view->clipboard.data = puglWideCharToUtf8(wstr, &view->clipboard.len);
+ GlobalUnlock(mem);
+ CloseClipboard();
+
+ return puglGetInternalClipboard(view, type, len);
}
PuglStatus
@@ -1072,72 +1067,72 @@ puglSetClipboard(PuglView* const view,
const void* const data,
const size_t len)
{
- PuglInternals* const impl = view->impl;
-
- PuglStatus st = puglSetInternalClipboard(view, type, data, len);
- if (st) {
- return st;
- } else if (!OpenClipboard(impl->hwnd)) {
- return PUGL_UNKNOWN_ERROR;
- }
-
- // Measure string and allocate global memory for clipboard
- const char* str = (const char*)data;
- const int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
- HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE,
- (size_t)(wlen + 1) * sizeof(wchar_t));
- if (!mem) {
- CloseClipboard();
- return PUGL_UNKNOWN_ERROR;
- }
-
- // Lock global memory
- wchar_t* wstr = (wchar_t*)GlobalLock(mem);
- if (!wstr) {
- GlobalFree(mem);
- CloseClipboard();
- return PUGL_UNKNOWN_ERROR;
- }
-
- // Convert string into global memory and set it as clipboard data
- MultiByteToWideChar(CP_UTF8, 0, str, (int)len, wstr, wlen);
- wstr[wlen] = 0;
- GlobalUnlock(mem);
- SetClipboardData(CF_UNICODETEXT, mem);
- CloseClipboard();
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+
+ PuglStatus st = puglSetInternalClipboard(view, type, data, len);
+ if (st) {
+ return st;
+ } else if (!OpenClipboard(impl->hwnd)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+
+ // Measure string and allocate global memory for clipboard
+ const char* str = (const char*)data;
+ const int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+ HGLOBAL mem =
+ GlobalAlloc(GMEM_MOVEABLE, (size_t)(wlen + 1) * sizeof(wchar_t));
+ if (!mem) {
+ CloseClipboard();
+ return PUGL_UNKNOWN_ERROR;
+ }
+
+ // Lock global memory
+ wchar_t* wstr = (wchar_t*)GlobalLock(mem);
+ if (!wstr) {
+ GlobalFree(mem);
+ CloseClipboard();
+ return PUGL_UNKNOWN_ERROR;
+ }
+
+ // Convert string into global memory and set it as clipboard data
+ MultiByteToWideChar(CP_UTF8, 0, str, (int)len, wstr, wlen);
+ wstr[wlen] = 0;
+ GlobalUnlock(mem);
+ SetClipboardData(CF_UNICODETEXT, mem);
+ CloseClipboard();
+ return PUGL_SUCCESS;
}
static const char* const cursor_ids[] = {
- IDC_ARROW, // ARROW
- IDC_IBEAM, // CARET
- IDC_CROSS, // CROSSHAIR
- IDC_HAND, // HAND
- IDC_NO, // NO
- IDC_SIZEWE, // LEFT_RIGHT
- IDC_SIZENS, // UP_DOWN
+ IDC_ARROW, // ARROW
+ IDC_IBEAM, // CARET
+ IDC_CROSS, // CROSSHAIR
+ IDC_HAND, // HAND
+ IDC_NO, // NO
+ IDC_SIZEWE, // LEFT_RIGHT
+ IDC_SIZENS, // UP_DOWN
};
PuglStatus
puglSetCursor(PuglView* view, PuglCursor cursor)
{
- PuglInternals* const impl = view->impl;
- const unsigned index = (unsigned)cursor;
- const unsigned count = sizeof(cursor_ids) / sizeof(cursor_ids[0]);
+ PuglInternals* const impl = view->impl;
+ const unsigned index = (unsigned)cursor;
+ const unsigned count = sizeof(cursor_ids) / sizeof(cursor_ids[0]);
- if (index >= count) {
- return PUGL_BAD_PARAMETER;
- }
+ if (index >= count) {
+ return PUGL_BAD_PARAMETER;
+ }
- const HCURSOR cur = LoadCursor(NULL, cursor_ids[index]);
- if (!cur) {
- return PUGL_FAILURE;
- }
+ const HCURSOR cur = LoadCursor(NULL, cursor_ids[index]);
+ if (!cur) {
+ return PUGL_FAILURE;
+ }
- impl->cursor = cur;
- if (impl->mouseTracked) {
- SetCursor(cur);
- }
+ impl->cursor = cur;
+ if (impl->mouseTracked) {
+ SetCursor(cur);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
diff --git a/src/win.h b/src/win.h
index bc1f763..ccab36a 100644
--- a/src/win.h
+++ b/src/win.h
@@ -26,62 +26,62 @@
typedef PIXELFORMATDESCRIPTOR PuglWinPFD;
struct PuglWorldInternalsImpl {
- double timerFrequency;
+ double timerFrequency;
};
struct PuglInternalsImpl {
- PuglWinPFD pfd;
- int pfId;
- HWND hwnd;
- HCURSOR cursor;
- HDC hdc;
- PuglSurface* surface;
- bool flashing;
- bool mouseTracked;
+ PuglWinPFD pfd;
+ int pfId;
+ HWND hwnd;
+ HCURSOR cursor;
+ HDC hdc;
+ PuglSurface* surface;
+ bool flashing;
+ bool mouseTracked;
};
static inline PuglWinPFD
puglWinGetPixelFormatDescriptor(const PuglHints hints)
{
- const int rgbBits = (hints[PUGL_RED_BITS] + //
- hints[PUGL_GREEN_BITS] + //
- hints[PUGL_BLUE_BITS]);
-
- const DWORD dwFlags = hints[PUGL_DOUBLE_BUFFER] ? PFD_DOUBLEBUFFER : 0u;
-
- PuglWinPFD pfd;
- ZeroMemory(&pfd, sizeof(pfd));
- pfd.nSize = sizeof(pfd);
- pfd.nVersion = 1;
- pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | dwFlags;
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = (BYTE)rgbBits;
- pfd.cRedBits = (BYTE)hints[PUGL_RED_BITS];
- pfd.cGreenBits = (BYTE)hints[PUGL_GREEN_BITS];
- pfd.cBlueBits = (BYTE)hints[PUGL_BLUE_BITS];
- pfd.cAlphaBits = (BYTE)hints[PUGL_ALPHA_BITS];
- pfd.cDepthBits = (BYTE)hints[PUGL_DEPTH_BITS];
- pfd.cStencilBits = (BYTE)hints[PUGL_STENCIL_BITS];
- pfd.iLayerType = PFD_MAIN_PLANE;
- return pfd;
+ const int rgbBits = (hints[PUGL_RED_BITS] + //
+ hints[PUGL_GREEN_BITS] + //
+ hints[PUGL_BLUE_BITS]);
+
+ const DWORD dwFlags = hints[PUGL_DOUBLE_BUFFER] ? PFD_DOUBLEBUFFER : 0u;
+
+ PuglWinPFD pfd;
+ ZeroMemory(&pfd, sizeof(pfd));
+ pfd.nSize = sizeof(pfd);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | dwFlags;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = (BYTE)rgbBits;
+ pfd.cRedBits = (BYTE)hints[PUGL_RED_BITS];
+ pfd.cGreenBits = (BYTE)hints[PUGL_GREEN_BITS];
+ pfd.cBlueBits = (BYTE)hints[PUGL_BLUE_BITS];
+ pfd.cAlphaBits = (BYTE)hints[PUGL_ALPHA_BITS];
+ pfd.cDepthBits = (BYTE)hints[PUGL_DEPTH_BITS];
+ pfd.cStencilBits = (BYTE)hints[PUGL_STENCIL_BITS];
+ pfd.iLayerType = PFD_MAIN_PLANE;
+ return pfd;
}
static inline unsigned
puglWinGetWindowFlags(const PuglView* const view)
{
- const bool resizable = view->hints[PUGL_RESIZABLE];
- const unsigned sizeFlags = resizable ? (WS_SIZEBOX | WS_MAXIMIZEBOX) : 0u;
+ const bool resizable = view->hints[PUGL_RESIZABLE];
+ const unsigned sizeFlags = resizable ? (WS_SIZEBOX | WS_MAXIMIZEBOX) : 0u;
- return (WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
- (view->parent
- ? WS_CHILD
- : (WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | sizeFlags)));
+ return (WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
+ (view->parent
+ ? WS_CHILD
+ : (WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX | sizeFlags)));
}
static inline unsigned
puglWinGetWindowExFlags(const PuglView* const view)
{
- return WS_EX_NOINHERITLAYOUT | (view->parent ? 0u : WS_EX_APPWINDOW);
+ return WS_EX_NOINHERITLAYOUT | (view->parent ? 0u : WS_EX_APPWINDOW);
}
static inline PuglStatus
@@ -90,48 +90,58 @@ puglWinCreateWindow(PuglView* const view,
HWND* const hwnd,
HDC* const hdc)
{
- const char* className = (const char*)view->world->className;
- const unsigned winFlags = puglWinGetWindowFlags(view);
- const unsigned winExFlags = puglWinGetWindowExFlags(view);
-
- if (view->frame.width == 0.0 && view->frame.height == 0.0) {
- if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
- return PUGL_BAD_CONFIGURATION;
- }
-
- RECT desktopRect;
- GetClientRect(GetDesktopWindow(), &desktopRect);
-
- const int screenWidth = desktopRect.right - desktopRect.left;
- const int screenHeight = desktopRect.bottom - desktopRect.top;
-
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
- view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0;
- view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0;
- }
-
- // The meaning of "parent" depends on the window type (WS_CHILD)
- PuglNativeView parent = view->parent ? view->parent : view->transientParent;
-
- // Calculate total window size to accommodate requested view size
- RECT wr = { (long)view->frame.x, (long)view->frame.y,
- (long)view->frame.width, (long)view->frame.height };
- AdjustWindowRectEx(&wr, winFlags, FALSE, winExFlags);
-
- // Create window and get drawing context
- if (!(*hwnd = CreateWindowEx(winExFlags, className, title, winFlags,
- CW_USEDEFAULT, CW_USEDEFAULT,
- wr.right-wr.left, wr.bottom-wr.top,
- (HWND)parent, NULL, NULL, NULL))) {
- return PUGL_REALIZE_FAILED;
- } else if (!(*hdc = GetDC(*hwnd))) {
- DestroyWindow(*hwnd);
- *hwnd = NULL;
- return PUGL_REALIZE_FAILED;
- }
-
- return PUGL_SUCCESS;
+ const char* className = (const char*)view->world->className;
+ const unsigned winFlags = puglWinGetWindowFlags(view);
+ const unsigned winExFlags = puglWinGetWindowExFlags(view);
+
+ if (view->frame.width == 0.0 && view->frame.height == 0.0) {
+ if (view->defaultWidth == 0.0 && view->defaultHeight == 0.0) {
+ return PUGL_BAD_CONFIGURATION;
+ }
+
+ RECT desktopRect;
+ GetClientRect(GetDesktopWindow(), &desktopRect);
+
+ const int screenWidth = desktopRect.right - desktopRect.left;
+ const int screenHeight = desktopRect.bottom - desktopRect.top;
+
+ view->frame.width = view->defaultWidth;
+ view->frame.height = view->defaultHeight;
+ view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0;
+ view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0;
+ }
+
+ // The meaning of "parent" depends on the window type (WS_CHILD)
+ PuglNativeView parent = view->parent ? view->parent : view->transientParent;
+
+ // Calculate total window size to accommodate requested view size
+ RECT wr = {(long)view->frame.x,
+ (long)view->frame.y,
+ (long)view->frame.width,
+ (long)view->frame.height};
+ AdjustWindowRectEx(&wr, winFlags, FALSE, winExFlags);
+
+ // Create window and get drawing context
+ if (!(*hwnd = CreateWindowEx(winExFlags,
+ className,
+ title,
+ winFlags,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ wr.right - wr.left,
+ wr.bottom - wr.top,
+ (HWND)parent,
+ NULL,
+ NULL,
+ NULL))) {
+ return PUGL_REALIZE_FAILED;
+ } else if (!(*hdc = GetDC(*hwnd))) {
+ DestroyWindow(*hwnd);
+ *hwnd = NULL;
+ return PUGL_REALIZE_FAILED;
+ }
+
+ return PUGL_SUCCESS;
}
PuglStatus
diff --git a/src/win_cairo.c b/src/win_cairo.c
index bab8ea0..9dc5ce0 100644
--- a/src/win_cairo.c
+++ b/src/win_cairo.c
@@ -25,149 +25,154 @@
#include <stdlib.h>
-typedef struct {
- cairo_surface_t* surface;
- cairo_t* cr;
- HDC drawDc;
- HBITMAP drawBitmap;
+typedef struct {
+ cairo_surface_t* surface;
+ cairo_t* cr;
+ HDC drawDc;
+ HBITMAP drawBitmap;
} PuglWinCairoSurface;
static PuglStatus
puglWinCairoCreateDrawContext(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
- surface->drawDc = CreateCompatibleDC(impl->hdc);
- surface->drawBitmap = CreateCompatibleBitmap(
- impl->hdc, (int)view->frame.width, (int)view->frame.height);
+ surface->drawDc = CreateCompatibleDC(impl->hdc);
+ surface->drawBitmap = CreateCompatibleBitmap(
+ impl->hdc, (int)view->frame.width, (int)view->frame.height);
- DeleteObject(SelectObject(surface->drawDc, surface->drawBitmap));
+ DeleteObject(SelectObject(surface->drawDc, surface->drawBitmap));
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinCairoDestroyDrawContext(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
- DeleteDC(surface->drawDc);
- DeleteObject(surface->drawBitmap);
+ DeleteDC(surface->drawDc);
+ DeleteObject(surface->drawBitmap);
- surface->drawDc = NULL;
- surface->drawBitmap = NULL;
+ surface->drawDc = NULL;
+ surface->drawBitmap = NULL;
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinCairoConfigure(PuglView* view)
{
- const PuglStatus st = puglWinStubConfigure(view);
+ const PuglStatus st = puglWinStubConfigure(view);
- if (!st) {
- view->impl->surface = (PuglWinCairoSurface*)calloc(
- 1, sizeof(PuglWinCairoSurface));
- }
+ if (!st) {
+ view->impl->surface =
+ (PuglWinCairoSurface*)calloc(1, sizeof(PuglWinCairoSurface));
+ }
- return st;
+ return st;
}
static void
puglWinCairoClose(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
- cairo_surface_destroy(surface->surface);
+ cairo_surface_destroy(surface->surface);
- surface->surface = NULL;
+ surface->surface = NULL;
}
static PuglStatus
puglWinCairoOpen(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
- if (!(surface->surface = cairo_win32_surface_create(surface->drawDc)) ||
- cairo_surface_status(surface->surface) ||
- !(surface->cr = cairo_create(surface->surface)) ||
- cairo_status(surface->cr)) {
- return PUGL_CREATE_CONTEXT_FAILED;
- }
+ if (!(surface->surface = cairo_win32_surface_create(surface->drawDc)) ||
+ cairo_surface_status(surface->surface) ||
+ !(surface->cr = cairo_create(surface->surface)) ||
+ cairo_status(surface->cr)) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinCairoDestroy(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
- puglWinCairoClose(view);
- puglWinCairoDestroyDrawContext(view);
- free(surface);
- impl->surface = NULL;
+ puglWinCairoClose(view);
+ puglWinCairoDestroyDrawContext(view);
+ free(surface);
+ impl->surface = NULL;
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinCairoEnter(PuglView* view, const PuglEventExpose* expose)
{
- PuglStatus st = PUGL_SUCCESS;
+ PuglStatus st = PUGL_SUCCESS;
- if (expose &&
- !(st = puglWinCairoCreateDrawContext(view)) &&
- !(st = puglWinCairoOpen(view))) {
- PAINTSTRUCT ps;
- BeginPaint(view->impl->hwnd, &ps);
- }
+ if (expose && !(st = puglWinCairoCreateDrawContext(view)) &&
+ !(st = puglWinCairoOpen(view))) {
+ PAINTSTRUCT ps;
+ BeginPaint(view->impl->hwnd, &ps);
+ }
- return st;
+ return st;
}
static PuglStatus
puglWinCairoLeave(PuglView* view, const PuglEventExpose* expose)
{
- PuglInternals* const impl = view->impl;
- PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
-
- if (expose) {
- cairo_surface_flush(surface->surface);
- BitBlt(impl->hdc,
- 0, 0, (int)view->frame.width, (int)view->frame.height,
- surface->drawDc, 0, 0, SRCCOPY);
-
- puglWinCairoClose(view);
- puglWinCairoDestroyDrawContext(view);
-
- PAINTSTRUCT ps;
- EndPaint(view->impl->hwnd, &ps);
- }
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglWinCairoSurface* const surface = (PuglWinCairoSurface*)impl->surface;
+
+ if (expose) {
+ cairo_surface_flush(surface->surface);
+ BitBlt(impl->hdc,
+ 0,
+ 0,
+ (int)view->frame.width,
+ (int)view->frame.height,
+ surface->drawDc,
+ 0,
+ 0,
+ SRCCOPY);
+
+ puglWinCairoClose(view);
+ puglWinCairoDestroyDrawContext(view);
+
+ PAINTSTRUCT ps;
+ EndPaint(view->impl->hwnd, &ps);
+ }
+
+ return PUGL_SUCCESS;
}
static void*
puglWinCairoGetContext(PuglView* view)
{
- return ((PuglWinCairoSurface*)view->impl->surface)->cr;
+ return ((PuglWinCairoSurface*)view->impl->surface)->cr;
}
const PuglBackend*
puglCairoBackend()
{
- static const PuglBackend backend = {puglWinCairoConfigure,
- puglStubCreate,
- puglWinCairoDestroy,
- puglWinCairoEnter,
- puglWinCairoLeave,
- puglWinCairoGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglWinCairoConfigure,
+ puglStubCreate,
+ puglWinCairoDestroy,
+ puglWinCairoEnter,
+ puglWinCairoLeave,
+ puglWinCairoGetContext};
+
+ return &backend;
}
diff --git a/src/win_gl.c b/src/win_gl.c
index fcf511b..4abd5ab 100644
--- a/src/win_gl.c
+++ b/src/win_gl.c
@@ -27,305 +27,301 @@
#include <stdbool.h>
#include <stdlib.h>
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_ALPHA_BITS_ARB 0x201b
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_ALPHA_BITS_ARB 0x201b
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
-#define WGL_TYPE_RGBA_ARB 0x202b
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
+#define WGL_TYPE_RGBA_ARB 0x202b
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
-#define WGL_CONTEXT_FLAGS_ARB 0x2094
-#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
-#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
typedef HGLRC (*WglCreateContextAttribs)(HDC, HGLRC, const int*);
typedef BOOL (*WglSwapInterval)(int);
-typedef BOOL (*WglChoosePixelFormat)(
- HDC, const int*, const FLOAT*, UINT, int*, UINT*);
+typedef BOOL (
+ *WglChoosePixelFormat)(HDC, const int*, const FLOAT*, UINT, int*, UINT*);
typedef struct {
- WglChoosePixelFormat wglChoosePixelFormat;
- WglCreateContextAttribs wglCreateContextAttribs;
- WglSwapInterval wglSwapInterval;
+ WglChoosePixelFormat wglChoosePixelFormat;
+ WglCreateContextAttribs wglCreateContextAttribs;
+ WglSwapInterval wglSwapInterval;
} PuglWinGlProcs;
typedef struct {
- PuglWinGlProcs procs;
- HGLRC hglrc;
+ PuglWinGlProcs procs;
+ HGLRC hglrc;
} PuglWinGlSurface;
// Struct to manage the fake window used during configuration
typedef struct {
- HWND hwnd;
- HDC hdc;
+ HWND hwnd;
+ HDC hdc;
} PuglFakeWindow;
static PuglStatus
puglWinError(PuglFakeWindow* fakeWin, const PuglStatus status)
{
- if (fakeWin->hwnd) {
- ReleaseDC(fakeWin->hwnd, fakeWin->hdc);
- DestroyWindow(fakeWin->hwnd);
- }
+ if (fakeWin->hwnd) {
+ ReleaseDC(fakeWin->hwnd, fakeWin->hdc);
+ DestroyWindow(fakeWin->hwnd);
+ }
- return status;
+ return status;
}
-static PuglWinGlProcs puglWinGlGetProcs(void)
+static PuglWinGlProcs
+puglWinGlGetProcs(void)
{
- const PuglWinGlProcs procs = {
- (WglChoosePixelFormat)(
- wglGetProcAddress("wglChoosePixelFormatARB")),
- (WglCreateContextAttribs)(
- wglGetProcAddress("wglCreateContextAttribsARB")),
- (WglSwapInterval)(
- wglGetProcAddress("wglSwapIntervalEXT"))
- };
-
- return procs;
+ const PuglWinGlProcs procs = {
+ (WglChoosePixelFormat)(wglGetProcAddress("wglChoosePixelFormatARB")),
+ (WglCreateContextAttribs)(wglGetProcAddress("wglCreateContextAttribsARB")),
+ (WglSwapInterval)(wglGetProcAddress("wglSwapIntervalEXT"))};
+
+ return procs;
}
static PuglStatus
puglWinGlConfigure(PuglView* view)
{
- PuglInternals* impl = view->impl;
-
- // Set attributes to default if they are unset
- // (There is no GLX_DONT_CARE equivalent on Windows)
- if (view->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_DEPTH_BITS] = 0;
- }
- if (view->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
- view->hints[PUGL_STENCIL_BITS] = 0;
- }
- if (view->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
- view->hints[PUGL_SAMPLES] = 1;
- }
- if (view->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
- view->hints[PUGL_DOUBLE_BUFFER] = 1;
- }
- if (view->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
- view->hints[PUGL_SWAP_INTERVAL] = 1;
- }
-
- // clang-format off
- const int pixelAttrs[] = {
- WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
- WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
- WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
- WGL_DOUBLE_BUFFER_ARB, view->hints[PUGL_DOUBLE_BUFFER],
- WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
- WGL_SAMPLE_BUFFERS_ARB, view->hints[PUGL_SAMPLES] ? 1 : 0,
- WGL_SAMPLES_ARB, view->hints[PUGL_SAMPLES],
- WGL_RED_BITS_ARB, view->hints[PUGL_RED_BITS],
- WGL_GREEN_BITS_ARB, view->hints[PUGL_GREEN_BITS],
- WGL_BLUE_BITS_ARB, view->hints[PUGL_BLUE_BITS],
- WGL_ALPHA_BITS_ARB, view->hints[PUGL_ALPHA_BITS],
- WGL_DEPTH_BITS_ARB, view->hints[PUGL_DEPTH_BITS],
- WGL_STENCIL_BITS_ARB, view->hints[PUGL_STENCIL_BITS],
- 0,
- };
- // clang-format on
-
- PuglWinGlSurface* const surface =
- (PuglWinGlSurface*)calloc(1, sizeof(PuglWinGlSurface));
- impl->surface = surface;
-
- // Create fake window for getting at GL context
- PuglStatus st = PUGL_SUCCESS;
- PuglFakeWindow fakeWin = {0, 0};
- static const char* title = "Pugl Configuration";
- if ((st = puglWinCreateWindow(view, title, &fakeWin.hwnd, &fakeWin.hdc))) {
- return puglWinError(&fakeWin, st);
- }
-
- // Set pixel format for fake window
- const PuglWinPFD fakePfd = puglWinGetPixelFormatDescriptor(view->hints);
- const int fakePfId = ChoosePixelFormat(fakeWin.hdc, &fakePfd);
- if (!fakePfId || !SetPixelFormat(fakeWin.hdc, fakePfId, &fakePfd)) {
- return puglWinError(&fakeWin, PUGL_SET_FORMAT_FAILED);
- }
-
- // Create fake GL context to get at the functions we need
- HGLRC fakeRc = wglCreateContext(fakeWin.hdc);
- if (!fakeRc) {
- return puglWinError(&fakeWin, PUGL_CREATE_CONTEXT_FAILED);
- }
-
- // Enter fake context and get extension functions
- wglMakeCurrent(fakeWin.hdc, fakeRc);
- surface->procs = puglWinGlGetProcs();
-
- if (surface->procs.wglChoosePixelFormat) {
- // Choose pixel format based on attributes
- UINT numFormats = 0;
- if (!surface->procs.wglChoosePixelFormat(
- fakeWin.hdc, pixelAttrs, NULL, 1u, &impl->pfId, &numFormats)) {
- return puglWinError(&fakeWin, PUGL_SET_FORMAT_FAILED);
- }
-
- DescribePixelFormat(
- impl->hdc, impl->pfId, sizeof(impl->pfd), &impl->pfd);
- } else {
- // Modern extensions not available, use basic pixel format
- impl->pfd = fakePfd;
- impl->pfId = fakePfId;
- }
-
- // Dispose of fake window and context
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(fakeRc);
- ReleaseDC(fakeWin.hwnd, fakeWin.hdc);
- DestroyWindow(fakeWin.hwnd);
-
- return PUGL_SUCCESS;
+ PuglInternals* impl = view->impl;
+
+ // Set attributes to default if they are unset
+ // (There is no GLX_DONT_CARE equivalent on Windows)
+ if (view->hints[PUGL_DEPTH_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_DEPTH_BITS] = 0;
+ }
+ if (view->hints[PUGL_STENCIL_BITS] == PUGL_DONT_CARE) {
+ view->hints[PUGL_STENCIL_BITS] = 0;
+ }
+ if (view->hints[PUGL_SAMPLES] == PUGL_DONT_CARE) {
+ view->hints[PUGL_SAMPLES] = 1;
+ }
+ if (view->hints[PUGL_DOUBLE_BUFFER] == PUGL_DONT_CARE) {
+ view->hints[PUGL_DOUBLE_BUFFER] = 1;
+ }
+ if (view->hints[PUGL_SWAP_INTERVAL] == PUGL_DONT_CARE) {
+ view->hints[PUGL_SWAP_INTERVAL] = 1;
+ }
+
+ // clang-format off
+ const int pixelAttrs[] = {
+ WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+ WGL_DOUBLE_BUFFER_ARB, view->hints[PUGL_DOUBLE_BUFFER],
+ WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+ WGL_SAMPLE_BUFFERS_ARB, view->hints[PUGL_SAMPLES] ? 1 : 0,
+ WGL_SAMPLES_ARB, view->hints[PUGL_SAMPLES],
+ WGL_RED_BITS_ARB, view->hints[PUGL_RED_BITS],
+ WGL_GREEN_BITS_ARB, view->hints[PUGL_GREEN_BITS],
+ WGL_BLUE_BITS_ARB, view->hints[PUGL_BLUE_BITS],
+ WGL_ALPHA_BITS_ARB, view->hints[PUGL_ALPHA_BITS],
+ WGL_DEPTH_BITS_ARB, view->hints[PUGL_DEPTH_BITS],
+ WGL_STENCIL_BITS_ARB, view->hints[PUGL_STENCIL_BITS],
+ 0,
+ };
+ // clang-format on
+
+ PuglWinGlSurface* const surface =
+ (PuglWinGlSurface*)calloc(1, sizeof(PuglWinGlSurface));
+ impl->surface = surface;
+
+ // Create fake window for getting at GL context
+ PuglStatus st = PUGL_SUCCESS;
+ PuglFakeWindow fakeWin = {0, 0};
+ static const char* title = "Pugl Configuration";
+ if ((st = puglWinCreateWindow(view, title, &fakeWin.hwnd, &fakeWin.hdc))) {
+ return puglWinError(&fakeWin, st);
+ }
+
+ // Set pixel format for fake window
+ const PuglWinPFD fakePfd = puglWinGetPixelFormatDescriptor(view->hints);
+ const int fakePfId = ChoosePixelFormat(fakeWin.hdc, &fakePfd);
+ if (!fakePfId || !SetPixelFormat(fakeWin.hdc, fakePfId, &fakePfd)) {
+ return puglWinError(&fakeWin, PUGL_SET_FORMAT_FAILED);
+ }
+
+ // Create fake GL context to get at the functions we need
+ HGLRC fakeRc = wglCreateContext(fakeWin.hdc);
+ if (!fakeRc) {
+ return puglWinError(&fakeWin, PUGL_CREATE_CONTEXT_FAILED);
+ }
+
+ // Enter fake context and get extension functions
+ wglMakeCurrent(fakeWin.hdc, fakeRc);
+ surface->procs = puglWinGlGetProcs();
+
+ if (surface->procs.wglChoosePixelFormat) {
+ // Choose pixel format based on attributes
+ UINT numFormats = 0;
+ if (!surface->procs.wglChoosePixelFormat(
+ fakeWin.hdc, pixelAttrs, NULL, 1u, &impl->pfId, &numFormats)) {
+ return puglWinError(&fakeWin, PUGL_SET_FORMAT_FAILED);
+ }
+
+ DescribePixelFormat(impl->hdc, impl->pfId, sizeof(impl->pfd), &impl->pfd);
+ } else {
+ // Modern extensions not available, use basic pixel format
+ impl->pfd = fakePfd;
+ impl->pfId = fakePfId;
+ }
+
+ // Dispose of fake window and context
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(fakeRc);
+ ReleaseDC(fakeWin.hwnd, fakeWin.hdc);
+ DestroyWindow(fakeWin.hwnd);
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinGlCreate(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWinGlSurface* const surface = (PuglWinGlSurface*)impl->surface;
- PuglStatus st = PUGL_SUCCESS;
-
- const int contextAttribs[] = {
- WGL_CONTEXT_MAJOR_VERSION_ARB,
- view->hints[PUGL_CONTEXT_VERSION_MAJOR],
-
- WGL_CONTEXT_MINOR_VERSION_ARB,
- view->hints[PUGL_CONTEXT_VERSION_MINOR],
-
- WGL_CONTEXT_FLAGS_ARB,
- (view->hints[PUGL_USE_DEBUG_CONTEXT] ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
-
- WGL_CONTEXT_PROFILE_MASK_ARB,
- (view->hints[PUGL_USE_COMPAT_PROFILE]
- ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB
- : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB),
-
- 0};
-
- // Create real window with desired pixel format
- if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
- return st;
- } else if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) {
- ReleaseDC(impl->hwnd, impl->hdc);
- DestroyWindow(impl->hwnd);
- impl->hwnd = NULL;
- impl->hdc = NULL;
- return PUGL_SET_FORMAT_FAILED;
- }
-
- // Create GL context
- if (surface->procs.wglCreateContextAttribs &&
- !(surface->hglrc = surface->procs.wglCreateContextAttribs(
- impl->hdc, 0, contextAttribs))) {
- return PUGL_CREATE_CONTEXT_FAILED;
- } else if (!(surface->hglrc = wglCreateContext(impl->hdc))) {
- return PUGL_CREATE_CONTEXT_FAILED;
- }
-
- // Enter context and set swap interval
- wglMakeCurrent(impl->hdc, surface->hglrc);
- const int swapInterval = view->hints[PUGL_SWAP_INTERVAL];
- if (surface->procs.wglSwapInterval && swapInterval != PUGL_DONT_CARE) {
- surface->procs.wglSwapInterval(swapInterval);
- }
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglWinGlSurface* const surface = (PuglWinGlSurface*)impl->surface;
+ PuglStatus st = PUGL_SUCCESS;
+
+ const int contextAttribs[] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB,
+ view->hints[PUGL_CONTEXT_VERSION_MAJOR],
+
+ WGL_CONTEXT_MINOR_VERSION_ARB,
+ view->hints[PUGL_CONTEXT_VERSION_MINOR],
+
+ WGL_CONTEXT_FLAGS_ARB,
+ (view->hints[PUGL_USE_DEBUG_CONTEXT] ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+
+ WGL_CONTEXT_PROFILE_MASK_ARB,
+ (view->hints[PUGL_USE_COMPAT_PROFILE]
+ ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB
+ : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB),
+
+ 0};
+
+ // Create real window with desired pixel format
+ if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
+ return st;
+ } else if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) {
+ ReleaseDC(impl->hwnd, impl->hdc);
+ DestroyWindow(impl->hwnd);
+ impl->hwnd = NULL;
+ impl->hdc = NULL;
+ return PUGL_SET_FORMAT_FAILED;
+ }
+
+ // Create GL context
+ if (surface->procs.wglCreateContextAttribs &&
+ !(surface->hglrc = surface->procs.wglCreateContextAttribs(
+ impl->hdc, 0, contextAttribs))) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ } else if (!(surface->hglrc = wglCreateContext(impl->hdc))) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
+
+ // Enter context and set swap interval
+ wglMakeCurrent(impl->hdc, surface->hglrc);
+ const int swapInterval = view->hints[PUGL_SWAP_INTERVAL];
+ if (surface->procs.wglSwapInterval && swapInterval != PUGL_DONT_CARE) {
+ surface->procs.wglSwapInterval(swapInterval);
+ }
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinGlDestroy(PuglView* view)
{
- PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
- if (surface) {
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(surface->hglrc);
- free(surface);
- view->impl->surface = NULL;
- }
-
- return PUGL_SUCCESS;
+ PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
+ if (surface) {
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(surface->hglrc);
+ free(surface);
+ view->impl->surface = NULL;
+ }
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinGlEnter(PuglView* view, const PuglEventExpose* expose)
{
- PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
+ PuglWinGlSurface* surface = (PuglWinGlSurface*)view->impl->surface;
- wglMakeCurrent(view->impl->hdc, surface->hglrc);
+ wglMakeCurrent(view->impl->hdc, surface->hglrc);
- if (expose) {
- PAINTSTRUCT ps;
- BeginPaint(view->impl->hwnd, &ps);
- }
+ if (expose) {
+ PAINTSTRUCT ps;
+ BeginPaint(view->impl->hwnd, &ps);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglWinGlLeave(PuglView* view, const PuglEventExpose* expose)
{
- if (expose) {
- PAINTSTRUCT ps;
- EndPaint(view->impl->hwnd, &ps);
- SwapBuffers(view->impl->hdc);
- }
-
- wglMakeCurrent(NULL, NULL);
- return PUGL_SUCCESS;
+ if (expose) {
+ PAINTSTRUCT ps;
+ EndPaint(view->impl->hwnd, &ps);
+ SwapBuffers(view->impl->hdc);
+ }
+
+ wglMakeCurrent(NULL, NULL);
+ return PUGL_SUCCESS;
}
PuglGlFunc
puglGetProcAddress(const char* name)
{
- const PuglGlFunc func = (PuglGlFunc)wglGetProcAddress(name);
+ const PuglGlFunc func = (PuglGlFunc)wglGetProcAddress(name);
- /* Windows has the annoying property that wglGetProcAddress returns NULL
- for functions from OpenGL 1.1, so we fall back to pulling them directly
- from opengl32.dll */
+ /* Windows has the annoying property that wglGetProcAddress returns NULL
+ for functions from OpenGL 1.1, so we fall back to pulling them directly
+ from opengl32.dll */
- return func
- ? func
- : (PuglGlFunc)GetProcAddress(GetModuleHandle("opengl32.dll"), name);
+ return func
+ ? func
+ : (PuglGlFunc)GetProcAddress(GetModuleHandle("opengl32.dll"), name);
}
PuglStatus
puglEnterContext(PuglView* view)
{
- return view->backend->enter(view, NULL);
+ return view->backend->enter(view, NULL);
}
PuglStatus
puglLeaveContext(PuglView* view)
{
- return view->backend->leave(view, NULL);
+ return view->backend->leave(view, NULL);
}
const PuglBackend*
puglGlBackend(void)
{
- static const PuglBackend backend = {puglWinGlConfigure,
- puglWinGlCreate,
- puglWinGlDestroy,
- puglWinGlEnter,
- puglWinGlLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglWinGlConfigure,
+ puglWinGlCreate,
+ puglWinGlDestroy,
+ puglWinGlEnter,
+ puglWinGlLeave,
+ puglStubGetContext};
+
+ return &backend;
}
diff --git a/src/win_stub.c b/src/win_stub.c
index 2027836..cf86390 100644
--- a/src/win_stub.c
+++ b/src/win_stub.c
@@ -23,58 +23,58 @@
PuglStatus
puglWinStubConfigure(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglStatus st = PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglStatus st = PUGL_SUCCESS;
- if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
- return st;
- }
+ if ((st = puglWinCreateWindow(view, "Pugl", &impl->hwnd, &impl->hdc))) {
+ return st;
+ }
- impl->pfd = puglWinGetPixelFormatDescriptor(view->hints);
- impl->pfId = ChoosePixelFormat(impl->hdc, &impl->pfd);
+ impl->pfd = puglWinGetPixelFormatDescriptor(view->hints);
+ impl->pfId = ChoosePixelFormat(impl->hdc, &impl->pfd);
- if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) {
- ReleaseDC(impl->hwnd, impl->hdc);
- DestroyWindow(impl->hwnd);
- impl->hwnd = NULL;
- impl->hdc = NULL;
- return PUGL_SET_FORMAT_FAILED;
- }
+ if (!SetPixelFormat(impl->hdc, impl->pfId, &impl->pfd)) {
+ ReleaseDC(impl->hwnd, impl->hdc);
+ DestroyWindow(impl->hwnd);
+ impl->hwnd = NULL;
+ impl->hdc = NULL;
+ return PUGL_SET_FORMAT_FAILED;
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglWinStubEnter(PuglView* view, const PuglEventExpose* expose)
{
- if (expose) {
- PAINTSTRUCT ps;
- BeginPaint(view->impl->hwnd, &ps);
- }
+ if (expose) {
+ PAINTSTRUCT ps;
+ BeginPaint(view->impl->hwnd, &ps);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglWinStubLeave(PuglView* view, const PuglEventExpose* expose)
{
- if (expose) {
- PAINTSTRUCT ps;
- EndPaint(view->impl->hwnd, &ps);
- }
+ if (expose) {
+ PAINTSTRUCT ps;
+ EndPaint(view->impl->hwnd, &ps);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
const PuglBackend*
puglStubBackend(void)
{
- static const PuglBackend backend = {puglWinStubConfigure,
- puglStubCreate,
- puglStubDestroy,
- puglWinStubEnter,
- puglWinStubLeave,
- puglStubGetContext};
+ static const PuglBackend backend = {puglWinStubConfigure,
+ puglStubCreate,
+ puglStubDestroy,
+ puglWinStubEnter,
+ puglWinStubLeave,
+ puglStubGetContext};
- return &backend;
+ return &backend;
}
diff --git a/src/win_vulkan.c b/src/win_vulkan.c
index f862716..d35d204 100644
--- a/src/win_vulkan.c
+++ b/src/win_vulkan.c
@@ -28,78 +28,77 @@
#include <stdlib.h>
-struct PuglVulkanLoaderImpl
-{
- HMODULE libvulkan;
- PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
- PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+struct PuglVulkanLoaderImpl {
+ HMODULE libvulkan;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
};
PuglVulkanLoader*
puglNewVulkanLoader(PuglWorld* PUGL_UNUSED(world))
{
- PuglVulkanLoader* loader =
- (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader));
- if (!loader) {
- return NULL;
- }
+ PuglVulkanLoader* loader =
+ (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader));
+ if (!loader) {
+ return NULL;
+ }
- if (!(loader->libvulkan = LoadLibrary("vulkan-1.dll"))) {
- free(loader);
- return NULL;
- }
+ if (!(loader->libvulkan = LoadLibrary("vulkan-1.dll"))) {
+ free(loader);
+ return NULL;
+ }
- loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(
- loader->libvulkan, "vkGetInstanceProcAddr");
+ loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(
+ loader->libvulkan, "vkGetInstanceProcAddr");
- loader->vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)GetProcAddress(
- loader->libvulkan, "vkGetDeviceProcAddr");
+ loader->vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)GetProcAddress(
+ loader->libvulkan, "vkGetDeviceProcAddr");
- return loader;
+ return loader;
}
void
puglFreeVulkanLoader(PuglVulkanLoader* loader)
{
- if (loader) {
- FreeLibrary(loader->libvulkan);
- free(loader);
- }
+ if (loader) {
+ FreeLibrary(loader->libvulkan);
+ free(loader);
+ }
}
PFN_vkGetInstanceProcAddr
puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetInstanceProcAddr;
+ return loader->vkGetInstanceProcAddr;
}
PFN_vkGetDeviceProcAddr
puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetDeviceProcAddr;
+ return loader->vkGetDeviceProcAddr;
}
const PuglBackend*
puglVulkanBackend()
{
- static const PuglBackend backend = {puglWinStubConfigure,
- puglStubCreate,
- puglStubDestroy,
- puglWinStubEnter,
- puglWinStubLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglWinStubConfigure,
+ puglStubCreate,
+ puglStubDestroy,
+ puglWinStubEnter,
+ puglWinStubLeave,
+ puglStubGetContext};
+
+ return &backend;
}
const char* const*
puglGetInstanceExtensions(uint32_t* const count)
{
- static const char* const extensions[] = {"VK_KHR_surface",
- "VK_KHR_win32_surface"};
+ static const char* const extensions[] = {"VK_KHR_surface",
+ "VK_KHR_win32_surface"};
- *count = 2;
- return extensions;
+ *count = 2;
+ return extensions;
}
VkResult
@@ -109,19 +108,19 @@ puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
const VkAllocationCallbacks* const pAllocator,
VkSurfaceKHR* const pSurface)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
- PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
- (PFN_vkCreateWin32SurfaceKHR)
- vkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR");
+ PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR =
+ (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr(
+ instance, "vkCreateWin32SurfaceKHR");
- const VkWin32SurfaceCreateInfoKHR createInfo = {
- VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
- NULL,
- 0,
- GetModuleHandle(NULL),
- impl->hwnd,
- };
+ const VkWin32SurfaceCreateInfoKHR createInfo = {
+ VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+ NULL,
+ 0,
+ GetModuleHandle(NULL),
+ impl->hwnd,
+ };
- return vkCreateWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface);
+ return vkCreateWin32SurfaceKHR(instance, &createInfo, pAllocator, pSurface);
}
diff --git a/src/x11.c b/src/x11.c
index 686e35c..2b594b7 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -32,17 +32,17 @@
#include <X11/keysym.h>
#ifdef HAVE_XRANDR
-# include <X11/extensions/Xrandr.h>
+# include <X11/extensions/Xrandr.h>
#endif
#ifdef HAVE_XSYNC
-# include <X11/extensions/sync.h>
-# include <X11/extensions/syncconst.h>
+# include <X11/extensions/sync.h>
+# include <X11/extensions/syncconst.h>
#endif
#ifdef HAVE_XCURSOR
-# include <X11/Xcursor/Xcursor.h>
-# include <X11/cursorfont.h>
+# include <X11/Xcursor/Xcursor.h>
+# include <X11/cursorfont.h>
#endif
#include <sys/select.h>
@@ -56,881 +56,913 @@
#include <time.h>
#ifndef MIN
-# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
-# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
enum WmClientStateMessageAction {
- WM_STATE_REMOVE,
- WM_STATE_ADD,
- WM_STATE_TOGGLE
+ WM_STATE_REMOVE,
+ WM_STATE_ADD,
+ WM_STATE_TOGGLE
};
static bool
puglInitXSync(PuglWorldInternals* impl)
{
#ifdef HAVE_XSYNC
- int syncMajor = 0;
- int syncMinor = 0;
- int errorBase = 0;
- XSyncSystemCounter* counters = NULL;
- int numCounters = 0;
-
- if (XSyncQueryExtension(impl->display, &impl->syncEventBase, &errorBase) &&
- XSyncInitialize(impl->display, &syncMajor, &syncMinor) &&
- (counters = XSyncListSystemCounters(impl->display, &numCounters))) {
-
- for (int n = 0; n < numCounters; ++n) {
- if (!strcmp(counters[n].name, "SERVERTIME")) {
- impl->serverTimeCounter = counters[n].counter;
- impl->syncSupported = true;
- break;
- }
- }
-
- XSyncFreeSystemCounterList(counters);
- }
+ int syncMajor = 0;
+ int syncMinor = 0;
+ int errorBase = 0;
+ XSyncSystemCounter* counters = NULL;
+ int numCounters = 0;
+
+ if (XSyncQueryExtension(impl->display, &impl->syncEventBase, &errorBase) &&
+ XSyncInitialize(impl->display, &syncMajor, &syncMinor) &&
+ (counters = XSyncListSystemCounters(impl->display, &numCounters))) {
+ for (int n = 0; n < numCounters; ++n) {
+ if (!strcmp(counters[n].name, "SERVERTIME")) {
+ impl->serverTimeCounter = counters[n].counter;
+ impl->syncSupported = true;
+ break;
+ }
+ }
+
+ XSyncFreeSystemCounterList(counters);
+ }
#else
- (void)impl;
+ (void)impl;
#endif
- return false;
+ return false;
}
PuglWorldInternals*
puglInitWorldInternals(PuglWorldType type, PuglWorldFlags flags)
{
- if (type == PUGL_PROGRAM && (flags & PUGL_WORLD_THREADS)) {
- XInitThreads();
- }
-
- Display* display = XOpenDisplay(NULL);
- if (!display) {
- return NULL;
- }
-
- PuglWorldInternals* impl = (PuglWorldInternals*)calloc(
- 1, sizeof(PuglWorldInternals));
-
- impl->display = display;
-
- // Intern the various atoms we will need
- impl->atoms.CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
- impl->atoms.UTF8_STRING = XInternAtom(display, "UTF8_STRING", 0);
- impl->atoms.WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", 0);
- impl->atoms.WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", 0);
- impl->atoms.PUGL_CLIENT_MSG = XInternAtom(display, "_PUGL_CLIENT_MSG", 0);
- impl->atoms.NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", 0);
- impl->atoms.NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", 0);
- impl->atoms.NET_WM_STATE_DEMANDS_ATTENTION =
- XInternAtom(display, "_NET_WM_STATE_DEMANDS_ATTENTION", 0);
-
- // Open input method
- XSetLocaleModifiers("");
- if (!(impl->xim = XOpenIM(display, NULL, NULL, NULL))) {
- XSetLocaleModifiers("@im=");
- impl->xim = XOpenIM(display, NULL, NULL, NULL);
- }
-
- puglInitXSync(impl);
- XFlush(display);
-
- return impl;
+ if (type == PUGL_PROGRAM && (flags & PUGL_WORLD_THREADS)) {
+ XInitThreads();
+ }
+
+ Display* display = XOpenDisplay(NULL);
+ if (!display) {
+ return NULL;
+ }
+
+ PuglWorldInternals* impl =
+ (PuglWorldInternals*)calloc(1, sizeof(PuglWorldInternals));
+
+ impl->display = display;
+
+ // Intern the various atoms we will need
+ impl->atoms.CLIPBOARD = XInternAtom(display, "CLIPBOARD", 0);
+ impl->atoms.UTF8_STRING = XInternAtom(display, "UTF8_STRING", 0);
+ impl->atoms.WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", 0);
+ impl->atoms.WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", 0);
+ impl->atoms.PUGL_CLIENT_MSG = XInternAtom(display, "_PUGL_CLIENT_MSG", 0);
+ impl->atoms.NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", 0);
+ impl->atoms.NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", 0);
+ impl->atoms.NET_WM_STATE_DEMANDS_ATTENTION =
+ XInternAtom(display, "_NET_WM_STATE_DEMANDS_ATTENTION", 0);
+
+ // Open input method
+ XSetLocaleModifiers("");
+ if (!(impl->xim = XOpenIM(display, NULL, NULL, NULL))) {
+ XSetLocaleModifiers("@im=");
+ impl->xim = XOpenIM(display, NULL, NULL, NULL);
+ }
+
+ puglInitXSync(impl);
+ XFlush(display);
+
+ return impl;
}
void*
puglGetNativeWorld(PuglWorld* world)
{
- return world->impl->display;
+ return world->impl->display;
}
PuglInternals*
puglInitViewInternals(void)
{
- PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
+ PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
#ifdef HAVE_XCURSOR
- impl->cursorShape = XC_arrow;
+ impl->cursorShape = XC_arrow;
#endif
- return impl;
+ return impl;
}
static PuglStatus
puglPollX11Socket(PuglWorld* world, const double timeout)
{
- if (XPending(world->impl->display) > 0) {
- return PUGL_SUCCESS;
- }
-
- const int fd = ConnectionNumber(world->impl->display);
- const int nfds = fd + 1;
- int ret = 0;
- fd_set fds;
- FD_ZERO(&fds); // NOLINT
- FD_SET(fd, &fds);
-
- if (timeout < 0.0) {
- ret = select(nfds, &fds, NULL, NULL, NULL);
- } else {
- const long sec = (long)timeout;
- const long usec = (long)((timeout - (double)sec) * 1e6);
- struct timeval tv = {sec, usec};
- ret = select(nfds, &fds, NULL, NULL, &tv);
- }
-
- return ret < 0 ? PUGL_UNKNOWN_ERROR : PUGL_SUCCESS;
+ if (XPending(world->impl->display) > 0) {
+ return PUGL_SUCCESS;
+ }
+
+ const int fd = ConnectionNumber(world->impl->display);
+ const int nfds = fd + 1;
+ int ret = 0;
+ fd_set fds;
+ FD_ZERO(&fds); // NOLINT
+ FD_SET(fd, &fds);
+
+ if (timeout < 0.0) {
+ ret = select(nfds, &fds, NULL, NULL, NULL);
+ } else {
+ const long sec = (long)timeout;
+ const long usec = (long)((timeout - (double)sec) * 1e6);
+ struct timeval tv = {sec, usec};
+ ret = select(nfds, &fds, NULL, NULL, &tv);
+ }
+
+ return ret < 0 ? PUGL_UNKNOWN_ERROR : PUGL_SUCCESS;
}
static PuglView*
puglFindView(PuglWorld* world, const Window window)
{
- for (size_t i = 0; i < world->numViews; ++i) {
- if (world->views[i]->impl->win == window) {
- return world->views[i];
- }
- }
+ for (size_t i = 0; i < world->numViews; ++i) {
+ if (world->views[i]->impl->win == window) {
+ return world->views[i];
+ }
+ }
- return NULL;
+ return NULL;
}
static PuglStatus
updateSizeHints(const PuglView* view)
{
- if (!view->impl->win) {
- return PUGL_SUCCESS;
- }
-
- Display* display = view->world->impl->display;
- XSizeHints sizeHints = {0};
-
- if (!view->hints[PUGL_RESIZABLE]) {
- sizeHints.flags = PBaseSize | PMinSize | PMaxSize;
- sizeHints.base_width = (int)view->frame.width;
- sizeHints.base_height = (int)view->frame.height;
- sizeHints.min_width = (int)view->frame.width;
- sizeHints.min_height = (int)view->frame.height;
- sizeHints.max_width = (int)view->frame.width;
- sizeHints.max_height = (int)view->frame.height;
- } else {
- if (view->defaultWidth || view->defaultHeight) {
- sizeHints.flags = PBaseSize;
- sizeHints.base_width = view->defaultWidth;
- sizeHints.base_height = view->defaultHeight;
- }
- if (view->minWidth || view->minHeight) {
- sizeHints.flags = PMinSize;
- sizeHints.min_width = view->minWidth;
- sizeHints.min_height = view->minHeight;
- }
- if (view->maxWidth || view->maxHeight) {
- sizeHints.flags = PMaxSize;
- sizeHints.max_width = view->maxWidth;
- sizeHints.max_height = view->maxHeight;
- }
- if (view->minAspectX) {
- sizeHints.flags |= PAspect;
- sizeHints.min_aspect.x = view->minAspectX;
- sizeHints.min_aspect.y = view->minAspectY;
- sizeHints.max_aspect.x = view->maxAspectX;
- sizeHints.max_aspect.y = view->maxAspectY;
- }
- }
-
- XSetNormalHints(display, view->impl->win, &sizeHints);
- return PUGL_SUCCESS;
+ if (!view->impl->win) {
+ return PUGL_SUCCESS;
+ }
+
+ Display* display = view->world->impl->display;
+ XSizeHints sizeHints = {0};
+
+ if (!view->hints[PUGL_RESIZABLE]) {
+ sizeHints.flags = PBaseSize | PMinSize | PMaxSize;
+ sizeHints.base_width = (int)view->frame.width;
+ sizeHints.base_height = (int)view->frame.height;
+ sizeHints.min_width = (int)view->frame.width;
+ sizeHints.min_height = (int)view->frame.height;
+ sizeHints.max_width = (int)view->frame.width;
+ sizeHints.max_height = (int)view->frame.height;
+ } else {
+ if (view->defaultWidth || view->defaultHeight) {
+ sizeHints.flags = PBaseSize;
+ sizeHints.base_width = view->defaultWidth;
+ sizeHints.base_height = view->defaultHeight;
+ }
+ if (view->minWidth || view->minHeight) {
+ sizeHints.flags = PMinSize;
+ sizeHints.min_width = view->minWidth;
+ sizeHints.min_height = view->minHeight;
+ }
+ if (view->maxWidth || view->maxHeight) {
+ sizeHints.flags = PMaxSize;
+ sizeHints.max_width = view->maxWidth;
+ sizeHints.max_height = view->maxHeight;
+ }
+ if (view->minAspectX) {
+ sizeHints.flags |= PAspect;
+ sizeHints.min_aspect.x = view->minAspectX;
+ sizeHints.min_aspect.y = view->minAspectY;
+ sizeHints.max_aspect.x = view->maxAspectX;
+ sizeHints.max_aspect.y = view->maxAspectY;
+ }
+ }
+
+ XSetNormalHints(display, view->impl->win, &sizeHints);
+ return PUGL_SUCCESS;
}
#ifdef HAVE_XCURSOR
static PuglStatus
puglDefineCursorShape(PuglView* view, unsigned shape)
{
- PuglInternals* const impl = view->impl;
- PuglWorld* const world = view->world;
- Display* const display = world->impl->display;
- const Cursor cur = XcursorShapeLoadCursor(display, shape);
-
- if (cur) {
- XDefineCursor(display, impl->win, cur);
- XFreeCursor(display, cur);
- return PUGL_SUCCESS;
- }
-
- return PUGL_FAILURE;
+ PuglInternals* const impl = view->impl;
+ PuglWorld* const world = view->world;
+ Display* const display = world->impl->display;
+ const Cursor cur = XcursorShapeLoadCursor(display, shape);
+
+ if (cur) {
+ XDefineCursor(display, impl->win, cur);
+ XFreeCursor(display, cur);
+ return PUGL_SUCCESS;
+ }
+
+ return PUGL_FAILURE;
}
#endif
PuglStatus
puglRealize(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglWorld* const world = view->world;
- PuglX11Atoms* const atoms = &view->world->impl->atoms;
- Display* const display = world->impl->display;
- const int screen = DefaultScreen(display);
- const Window root = RootWindow(display, screen);
- const Window parent = view->parent ? (Window)view->parent : root;
- XSetWindowAttributes attr = {0};
- PuglStatus st = PUGL_SUCCESS;
-
- // Ensure that we're unrealized and that a reasonable backend has been set
- if (impl->win) {
- return PUGL_FAILURE;
- } else if (!view->backend || !view->backend->configure) {
- return PUGL_BAD_BACKEND;
- }
-
- // Set the size to the default if it has not already been set
- if (view->frame.width == 0.0 && view->frame.height == 0.0) {
- if (view->defaultWidth == 0.0 || view->defaultHeight == 0.0) {
- return PUGL_BAD_CONFIGURATION;
- }
-
- view->frame.width = view->defaultWidth;
- view->frame.height = view->defaultHeight;
- }
-
- // Center top-level windows if a position has not been set
- if (!view->parent && view->frame.x == 0.0 && view->frame.y == 0.0) {
- const int screenWidth = DisplayWidth(display, screen);
- const int screenHeight = DisplayHeight(display, screen);
-
- view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0;
- view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0;
- }
-
- // Configure the backend to get the visual info
- impl->display = display;
- impl->screen = screen;
- if ((st = view->backend->configure(view)) || !impl->vi) {
- view->backend->destroy(view);
- return st ? st : PUGL_BACKEND_FAILED;
- }
-
- // Create a colormap based on the visual info from the backend
- attr.colormap =
- XCreateColormap(display, parent, impl->vi->visual, AllocNone);
-
- // Set the event mask to request all of the event types we react to
- attr.event_mask |= ButtonPressMask;
- attr.event_mask |= ButtonReleaseMask;
- attr.event_mask |= EnterWindowMask;
- attr.event_mask |= ExposureMask;
- attr.event_mask |= FocusChangeMask;
- attr.event_mask |= KeyPressMask;
- attr.event_mask |= KeyReleaseMask;
- attr.event_mask |= LeaveWindowMask;
- attr.event_mask |= PointerMotionMask;
- attr.event_mask |= StructureNotifyMask;
- attr.event_mask |= VisibilityChangeMask;
-
- // Create the window
- impl->win = XCreateWindow(display,
- parent,
- (int)view->frame.x,
- (int)view->frame.y,
- (unsigned)view->frame.width,
- (unsigned)view->frame.height,
- 0,
- impl->vi->depth,
- InputOutput,
- impl->vi->visual,
- CWColormap | CWEventMask,
- &attr);
-
- // Create the backend drawing context/surface
- if ((st = view->backend->create(view))) {
- return st;
- }
+ PuglInternals* const impl = view->impl;
+ PuglWorld* const world = view->world;
+ PuglX11Atoms* const atoms = &view->world->impl->atoms;
+ Display* const display = world->impl->display;
+ const int screen = DefaultScreen(display);
+ const Window root = RootWindow(display, screen);
+ const Window parent = view->parent ? (Window)view->parent : root;
+ XSetWindowAttributes attr = {0};
+ PuglStatus st = PUGL_SUCCESS;
+
+ // Ensure that we're unrealized and that a reasonable backend has been set
+ if (impl->win) {
+ return PUGL_FAILURE;
+ } else if (!view->backend || !view->backend->configure) {
+ return PUGL_BAD_BACKEND;
+ }
+
+ // Set the size to the default if it has not already been set
+ if (view->frame.width == 0.0 && view->frame.height == 0.0) {
+ if (view->defaultWidth == 0.0 || view->defaultHeight == 0.0) {
+ return PUGL_BAD_CONFIGURATION;
+ }
+
+ view->frame.width = view->defaultWidth;
+ view->frame.height = view->defaultHeight;
+ }
+
+ // Center top-level windows if a position has not been set
+ if (!view->parent && view->frame.x == 0.0 && view->frame.y == 0.0) {
+ const int screenWidth = DisplayWidth(display, screen);
+ const int screenHeight = DisplayHeight(display, screen);
+
+ view->frame.x = screenWidth / 2.0 - view->frame.width / 2.0;
+ view->frame.y = screenHeight / 2.0 - view->frame.height / 2.0;
+ }
+
+ // Configure the backend to get the visual info
+ impl->display = display;
+ impl->screen = screen;
+ if ((st = view->backend->configure(view)) || !impl->vi) {
+ view->backend->destroy(view);
+ return st ? st : PUGL_BACKEND_FAILED;
+ }
+
+ // Create a colormap based on the visual info from the backend
+ attr.colormap = XCreateColormap(display, parent, impl->vi->visual, AllocNone);
+
+ // Set the event mask to request all of the event types we react to
+ attr.event_mask |= ButtonPressMask;
+ attr.event_mask |= ButtonReleaseMask;
+ attr.event_mask |= EnterWindowMask;
+ attr.event_mask |= ExposureMask;
+ attr.event_mask |= FocusChangeMask;
+ attr.event_mask |= KeyPressMask;
+ attr.event_mask |= KeyReleaseMask;
+ attr.event_mask |= LeaveWindowMask;
+ attr.event_mask |= PointerMotionMask;
+ attr.event_mask |= StructureNotifyMask;
+ attr.event_mask |= VisibilityChangeMask;
+
+ // Create the window
+ impl->win = XCreateWindow(display,
+ parent,
+ (int)view->frame.x,
+ (int)view->frame.y,
+ (unsigned)view->frame.width,
+ (unsigned)view->frame.height,
+ 0,
+ impl->vi->depth,
+ InputOutput,
+ impl->vi->visual,
+ CWColormap | CWEventMask,
+ &attr);
+
+ // Create the backend drawing context/surface
+ if ((st = view->backend->create(view))) {
+ return st;
+ }
#ifdef HAVE_XRANDR
- // Set refresh rate hint to the real refresh rate
- XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent);
- short current_rate = XRRConfigCurrentRate(conf);
+ // Set refresh rate hint to the real refresh rate
+ XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent);
+ short current_rate = XRRConfigCurrentRate(conf);
- view->hints[PUGL_REFRESH_RATE] = current_rate;
- XRRFreeScreenConfigInfo(conf);
+ view->hints[PUGL_REFRESH_RATE] = current_rate;
+ XRRFreeScreenConfigInfo(conf);
#endif
- updateSizeHints(view);
+ updateSizeHints(view);
- XClassHint classHint = { world->className, world->className };
- XSetClassHint(display, impl->win, &classHint);
+ XClassHint classHint = {world->className, world->className};
+ XSetClassHint(display, impl->win, &classHint);
- if (view->title) {
- puglSetWindowTitle(view, view->title);
- }
+ if (view->title) {
+ puglSetWindowTitle(view, view->title);
+ }
- if (parent == root) {
- XSetWMProtocols(display, impl->win, &atoms->WM_DELETE_WINDOW, 1);
- }
+ if (parent == root) {
+ XSetWMProtocols(display, impl->win, &atoms->WM_DELETE_WINDOW, 1);
+ }
- if (view->transientParent) {
- XSetTransientForHint(display, impl->win, (Window)view->transientParent);
- }
+ if (view->transientParent) {
+ XSetTransientForHint(display, impl->win, (Window)view->transientParent);
+ }
- // Create input context
- impl->xic = XCreateIC(world->impl->xim,
- XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
- XNClientWindow, impl->win,
- XNFocusWindow, impl->win,
- NULL);
+ // Create input context
+ impl->xic = XCreateIC(world->impl->xim,
+ XNInputStyle,
+ XIMPreeditNothing | XIMStatusNothing,
+ XNClientWindow,
+ impl->win,
+ XNFocusWindow,
+ impl->win,
+ NULL);
#ifdef HAVE_XCURSOR
- puglDefineCursorShape(view, impl->cursorShape);
+ puglDefineCursorShape(view, impl->cursorShape);
#endif
- puglDispatchSimpleEvent(view, PUGL_CREATE);
+ puglDispatchSimpleEvent(view, PUGL_CREATE);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
PuglStatus
puglShow(PuglView* view)
{
- PuglStatus st = PUGL_SUCCESS;
+ PuglStatus st = PUGL_SUCCESS;
- if (!view->impl->win) {
- if ((st = puglRealize(view))) {
- return st;
- }
- }
+ if (!view->impl->win) {
+ if ((st = puglRealize(view))) {
+ return st;
+ }
+ }
- XMapRaised(view->impl->display, view->impl->win);
- puglPostRedisplay(view);
+ XMapRaised(view->impl->display, view->impl->win);
+ puglPostRedisplay(view);
- return st;
+ return st;
}
PuglStatus
puglHide(PuglView* view)
{
- XUnmapWindow(view->impl->display, view->impl->win);
- return PUGL_SUCCESS;
+ XUnmapWindow(view->impl->display, view->impl->win);
+ return PUGL_SUCCESS;
}
void
puglFreeViewInternals(PuglView* view)
{
- if (view && view->impl) {
- if (view->impl->xic) {
- XDestroyIC(view->impl->xic);
- }
- if (view->backend) {
- view->backend->destroy(view);
- }
- if (view->impl->display) {
- XDestroyWindow(view->impl->display, view->impl->win);
- }
- XFree(view->impl->vi);
- free(view->impl);
- }
+ if (view && view->impl) {
+ if (view->impl->xic) {
+ XDestroyIC(view->impl->xic);
+ }
+ if (view->backend) {
+ view->backend->destroy(view);
+ }
+ if (view->impl->display) {
+ XDestroyWindow(view->impl->display, view->impl->win);
+ }
+ XFree(view->impl->vi);
+ free(view->impl);
+ }
}
void
puglFreeWorldInternals(PuglWorld* world)
{
- if (world->impl->xim) {
- XCloseIM(world->impl->xim);
- }
- XCloseDisplay(world->impl->display);
- free(world->impl->timers);
- free(world->impl);
+ if (world->impl->xim) {
+ XCloseIM(world->impl->xim);
+ }
+ XCloseDisplay(world->impl->display);
+ free(world->impl->timers);
+ free(world->impl);
}
static PuglKey
keySymToSpecial(KeySym sym)
{
- switch (sym) {
- case XK_F1: return PUGL_KEY_F1;
- case XK_F2: return PUGL_KEY_F2;
- case XK_F3: return PUGL_KEY_F3;
- case XK_F4: return PUGL_KEY_F4;
- case XK_F5: return PUGL_KEY_F5;
- case XK_F6: return PUGL_KEY_F6;
- case XK_F7: return PUGL_KEY_F7;
- case XK_F8: return PUGL_KEY_F8;
- case XK_F9: return PUGL_KEY_F9;
- case XK_F10: return PUGL_KEY_F10;
- case XK_F11: return PUGL_KEY_F11;
- case XK_F12: return PUGL_KEY_F12;
- case XK_Left: return PUGL_KEY_LEFT;
- case XK_Up: return PUGL_KEY_UP;
- case XK_Right: return PUGL_KEY_RIGHT;
- case XK_Down: return PUGL_KEY_DOWN;
- case XK_Page_Up: return PUGL_KEY_PAGE_UP;
- case XK_Page_Down: return PUGL_KEY_PAGE_DOWN;
- case XK_Home: return PUGL_KEY_HOME;
- case XK_End: return PUGL_KEY_END;
- case XK_Insert: return PUGL_KEY_INSERT;
- case XK_Shift_L: return PUGL_KEY_SHIFT_L;
- case XK_Shift_R: return PUGL_KEY_SHIFT_R;
- case XK_Control_L: return PUGL_KEY_CTRL_L;
- case XK_Control_R: return PUGL_KEY_CTRL_R;
- case XK_Alt_L: return PUGL_KEY_ALT_L;
- case XK_ISO_Level3_Shift:
- case XK_Alt_R: return PUGL_KEY_ALT_R;
- case XK_Super_L: return PUGL_KEY_SUPER_L;
- case XK_Super_R: return PUGL_KEY_SUPER_R;
- case XK_Menu: return PUGL_KEY_MENU;
- case XK_Caps_Lock: return PUGL_KEY_CAPS_LOCK;
- case XK_Scroll_Lock: return PUGL_KEY_SCROLL_LOCK;
- case XK_Num_Lock: return PUGL_KEY_NUM_LOCK;
- case XK_Print: return PUGL_KEY_PRINT_SCREEN;
- case XK_Pause: return PUGL_KEY_PAUSE;
- default: break;
- }
- return (PuglKey)0;
+ switch (sym) {
+ case XK_F1:
+ return PUGL_KEY_F1;
+ case XK_F2:
+ return PUGL_KEY_F2;
+ case XK_F3:
+ return PUGL_KEY_F3;
+ case XK_F4:
+ return PUGL_KEY_F4;
+ case XK_F5:
+ return PUGL_KEY_F5;
+ case XK_F6:
+ return PUGL_KEY_F6;
+ case XK_F7:
+ return PUGL_KEY_F7;
+ case XK_F8:
+ return PUGL_KEY_F8;
+ case XK_F9:
+ return PUGL_KEY_F9;
+ case XK_F10:
+ return PUGL_KEY_F10;
+ case XK_F11:
+ return PUGL_KEY_F11;
+ case XK_F12:
+ return PUGL_KEY_F12;
+ case XK_Left:
+ return PUGL_KEY_LEFT;
+ case XK_Up:
+ return PUGL_KEY_UP;
+ case XK_Right:
+ return PUGL_KEY_RIGHT;
+ case XK_Down:
+ return PUGL_KEY_DOWN;
+ case XK_Page_Up:
+ return PUGL_KEY_PAGE_UP;
+ case XK_Page_Down:
+ return PUGL_KEY_PAGE_DOWN;
+ case XK_Home:
+ return PUGL_KEY_HOME;
+ case XK_End:
+ return PUGL_KEY_END;
+ case XK_Insert:
+ return PUGL_KEY_INSERT;
+ case XK_Shift_L:
+ return PUGL_KEY_SHIFT_L;
+ case XK_Shift_R:
+ return PUGL_KEY_SHIFT_R;
+ case XK_Control_L:
+ return PUGL_KEY_CTRL_L;
+ case XK_Control_R:
+ return PUGL_KEY_CTRL_R;
+ case XK_Alt_L:
+ return PUGL_KEY_ALT_L;
+ case XK_ISO_Level3_Shift:
+ case XK_Alt_R:
+ return PUGL_KEY_ALT_R;
+ case XK_Super_L:
+ return PUGL_KEY_SUPER_L;
+ case XK_Super_R:
+ return PUGL_KEY_SUPER_R;
+ case XK_Menu:
+ return PUGL_KEY_MENU;
+ case XK_Caps_Lock:
+ return PUGL_KEY_CAPS_LOCK;
+ case XK_Scroll_Lock:
+ return PUGL_KEY_SCROLL_LOCK;
+ case XK_Num_Lock:
+ return PUGL_KEY_NUM_LOCK;
+ case XK_Print:
+ return PUGL_KEY_PRINT_SCREEN;
+ case XK_Pause:
+ return PUGL_KEY_PAUSE;
+ default:
+ break;
+ }
+ return (PuglKey)0;
}
static int
lookupString(XIC xic, XEvent* xevent, char* str, KeySym* sym)
{
- Status status = 0;
+ Status status = 0;
#ifdef X_HAVE_UTF8_STRING
- const int n = Xutf8LookupString(xic, &xevent->xkey, str, 7, sym, &status);
+ const int n = Xutf8LookupString(xic, &xevent->xkey, str, 7, sym, &status);
#else
- const int n = XmbLookupString(xic, &xevent->xkey, str, 7, sym, &status);
+ const int n = XmbLookupString(xic, &xevent->xkey, str, 7, sym, &status);
#endif
- return status == XBufferOverflow ? 0 : n;
+ return status == XBufferOverflow ? 0 : n;
}
static void
translateKey(PuglView* view, XEvent* xevent, PuglEvent* event)
{
- const unsigned state = xevent->xkey.state;
- const bool filter = XFilterEvent(xevent, None);
-
- event->key.keycode = xevent->xkey.keycode;
- xevent->xkey.state = 0;
-
- // Lookup unshifted key
- char ustr[8] = {0};
- KeySym sym = 0;
- const int ufound = XLookupString(&xevent->xkey, ustr, 8, &sym, NULL);
- const PuglKey special = keySymToSpecial(sym);
-
- event->key.key = ((special || ufound <= 0)
- ? special
- : puglDecodeUTF8((const uint8_t*)ustr));
-
- if (xevent->type == KeyPress && !filter && !special) {
- // Lookup shifted key for possible text event
- xevent->xkey.state = state;
-
- char sstr[8] = {0};
- const int sfound = lookupString(view->impl->xic, xevent, sstr, &sym);
- if (sfound > 0) {
- // Dispatch key event now
- puglDispatchEvent(view, event);
-
- // "Return" a text event in its place
- event->text.type = PUGL_TEXT;
- event->text.character = puglDecodeUTF8((const uint8_t*)sstr);
- memcpy(event->text.string, sstr, sizeof(sstr));
- }
- }
+ const unsigned state = xevent->xkey.state;
+ const bool filter = XFilterEvent(xevent, None);
+
+ event->key.keycode = xevent->xkey.keycode;
+ xevent->xkey.state = 0;
+
+ // Lookup unshifted key
+ char ustr[8] = {0};
+ KeySym sym = 0;
+ const int ufound = XLookupString(&xevent->xkey, ustr, 8, &sym, NULL);
+ const PuglKey special = keySymToSpecial(sym);
+
+ event->key.key =
+ ((special || ufound <= 0) ? special : puglDecodeUTF8((const uint8_t*)ustr));
+
+ if (xevent->type == KeyPress && !filter && !special) {
+ // Lookup shifted key for possible text event
+ xevent->xkey.state = state;
+
+ char sstr[8] = {0};
+ const int sfound = lookupString(view->impl->xic, xevent, sstr, &sym);
+ if (sfound > 0) {
+ // Dispatch key event now
+ puglDispatchEvent(view, event);
+
+ // "Return" a text event in its place
+ event->text.type = PUGL_TEXT;
+ event->text.character = puglDecodeUTF8((const uint8_t*)sstr);
+ memcpy(event->text.string, sstr, sizeof(sstr));
+ }
+ }
}
static uint32_t
translateModifiers(const unsigned xstate)
{
- return (((xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0u) |
- ((xstate & ControlMask) ? PUGL_MOD_CTRL : 0u) |
- ((xstate & Mod1Mask) ? PUGL_MOD_ALT : 0u) |
- ((xstate & Mod4Mask) ? PUGL_MOD_SUPER : 0u));
+ return (((xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0u) |
+ ((xstate & ControlMask) ? PUGL_MOD_CTRL : 0u) |
+ ((xstate & Mod1Mask) ? PUGL_MOD_ALT : 0u) |
+ ((xstate & Mod4Mask) ? PUGL_MOD_SUPER : 0u));
}
static PuglEvent
translateEvent(PuglView* view, XEvent xevent)
{
- const PuglX11Atoms* atoms = &view->world->impl->atoms;
-
- PuglEvent event = {{PUGL_NOTHING, 0}};
- event.any.flags = xevent.xany.send_event ? PUGL_IS_SEND_EVENT : 0;
-
- switch (xevent.type) {
- case ClientMessage:
- if (xevent.xclient.message_type == atoms->WM_PROTOCOLS) {
- const Atom protocol = (Atom)xevent.xclient.data.l[0];
- if (protocol == atoms->WM_DELETE_WINDOW) {
- event.type = PUGL_CLOSE;
- }
- } else if (xevent.xclient.message_type == atoms->PUGL_CLIENT_MSG) {
- event.type = PUGL_CLIENT;
- event.client.data1 = (uintptr_t)xevent.xclient.data.l[0];
- event.client.data2 = (uintptr_t)xevent.xclient.data.l[1];
- }
- break;
- case VisibilityNotify:
- view->visible = xevent.xvisibility.state != VisibilityFullyObscured;
- break;
- case MapNotify:
- event.type = PUGL_MAP;
- break;
- case UnmapNotify:
- event.type = PUGL_UNMAP;
- view->visible = false;
- break;
- case ConfigureNotify:
- event.type = PUGL_CONFIGURE;
- event.configure.x = xevent.xconfigure.x;
- event.configure.y = xevent.xconfigure.y;
- event.configure.width = xevent.xconfigure.width;
- event.configure.height = xevent.xconfigure.height;
- break;
- case Expose:
- event.type = PUGL_EXPOSE;
- event.expose.x = xevent.xexpose.x;
- event.expose.y = xevent.xexpose.y;
- event.expose.width = xevent.xexpose.width;
- event.expose.height = xevent.xexpose.height;
- break;
- case MotionNotify:
- event.type = PUGL_MOTION;
- event.motion.time = (double)xevent.xmotion.time / 1e3;
- event.motion.x = xevent.xmotion.x;
- event.motion.y = xevent.xmotion.y;
- event.motion.xRoot = xevent.xmotion.x_root;
- event.motion.yRoot = xevent.xmotion.y_root;
- event.motion.state = translateModifiers(xevent.xmotion.state);
- if (xevent.xmotion.is_hint == NotifyHint) {
- event.motion.flags |= PUGL_IS_HINT;
- }
- break;
- case ButtonPress:
- if (xevent.xbutton.button >= 4 && xevent.xbutton.button <= 7) {
- event.type = PUGL_SCROLL;
- event.scroll.time = (double)xevent.xbutton.time / 1e3;
- event.scroll.x = xevent.xbutton.x;
- event.scroll.y = xevent.xbutton.y;
- event.scroll.xRoot = xevent.xbutton.x_root;
- event.scroll.yRoot = xevent.xbutton.y_root;
- event.scroll.state = translateModifiers(xevent.xbutton.state);
- event.scroll.dx = 0.0;
- event.scroll.dy = 0.0;
- switch (xevent.xbutton.button) {
- case 4:
- event.scroll.dy = 1.0;
- event.scroll.direction = PUGL_SCROLL_UP;
- break;
- case 5:
- event.scroll.dy = -1.0;
- event.scroll.direction = PUGL_SCROLL_DOWN;
- break;
- case 6:
- event.scroll.dx = -1.0;
- event.scroll.direction = PUGL_SCROLL_LEFT;
- break;
- case 7:
- event.scroll.dx = 1.0;
- event.scroll.direction = PUGL_SCROLL_RIGHT;
- break;
- }
- // fallthru
- }
- // fallthru
- case ButtonRelease:
- if (xevent.xbutton.button < 4 || xevent.xbutton.button > 7) {
- event.button.type = ((xevent.type == ButtonPress)
- ? PUGL_BUTTON_PRESS
- : PUGL_BUTTON_RELEASE);
- event.button.time = (double)xevent.xbutton.time / 1e3;
- event.button.x = xevent.xbutton.x;
- event.button.y = xevent.xbutton.y;
- event.button.xRoot = xevent.xbutton.x_root;
- event.button.yRoot = xevent.xbutton.y_root;
- event.button.state = translateModifiers(xevent.xbutton.state);
- event.button.button = xevent.xbutton.button;
- }
- break;
- case KeyPress:
- case KeyRelease:
- event.type = ((xevent.type == KeyPress)
- ? PUGL_KEY_PRESS
- : PUGL_KEY_RELEASE);
- event.key.time = (double)xevent.xkey.time / 1e3;
- event.key.x = xevent.xkey.x;
- event.key.y = xevent.xkey.y;
- event.key.xRoot = xevent.xkey.x_root;
- event.key.yRoot = xevent.xkey.y_root;
- event.key.state = translateModifiers(xevent.xkey.state);
- translateKey(view, &xevent, &event);
- break;
- case EnterNotify:
- case LeaveNotify:
- event.type = ((xevent.type == EnterNotify)
- ? PUGL_POINTER_IN
- : PUGL_POINTER_OUT);
- event.crossing.time = (double)xevent.xcrossing.time / 1e3;
- event.crossing.x = xevent.xcrossing.x;
- event.crossing.y = xevent.xcrossing.y;
- event.crossing.xRoot = xevent.xcrossing.x_root;
- event.crossing.yRoot = xevent.xcrossing.y_root;
- event.crossing.state = translateModifiers(xevent.xcrossing.state);
- event.crossing.mode = PUGL_CROSSING_NORMAL;
- if (xevent.xcrossing.mode == NotifyGrab) {
- event.crossing.mode = PUGL_CROSSING_GRAB;
- } else if (xevent.xcrossing.mode == NotifyUngrab) {
- event.crossing.mode = PUGL_CROSSING_UNGRAB;
- }
- break;
-
- case FocusIn:
- case FocusOut:
- event.type = (xevent.type == FocusIn) ? PUGL_FOCUS_IN : PUGL_FOCUS_OUT;
- event.focus.mode = PUGL_CROSSING_NORMAL;
- if (xevent.xfocus.mode == NotifyGrab) {
- event.focus.mode = PUGL_CROSSING_GRAB;
- } else if (xevent.xfocus.mode == NotifyUngrab) {
- event.focus.mode = PUGL_CROSSING_UNGRAB;
- }
- break;
-
- default:
- break;
- }
-
- return event;
+ const PuglX11Atoms* atoms = &view->world->impl->atoms;
+
+ PuglEvent event = {{PUGL_NOTHING, 0}};
+ event.any.flags = xevent.xany.send_event ? PUGL_IS_SEND_EVENT : 0;
+
+ switch (xevent.type) {
+ case ClientMessage:
+ if (xevent.xclient.message_type == atoms->WM_PROTOCOLS) {
+ const Atom protocol = (Atom)xevent.xclient.data.l[0];
+ if (protocol == atoms->WM_DELETE_WINDOW) {
+ event.type = PUGL_CLOSE;
+ }
+ } else if (xevent.xclient.message_type == atoms->PUGL_CLIENT_MSG) {
+ event.type = PUGL_CLIENT;
+ event.client.data1 = (uintptr_t)xevent.xclient.data.l[0];
+ event.client.data2 = (uintptr_t)xevent.xclient.data.l[1];
+ }
+ break;
+ case VisibilityNotify:
+ view->visible = xevent.xvisibility.state != VisibilityFullyObscured;
+ break;
+ case MapNotify:
+ event.type = PUGL_MAP;
+ break;
+ case UnmapNotify:
+ event.type = PUGL_UNMAP;
+ view->visible = false;
+ break;
+ case ConfigureNotify:
+ event.type = PUGL_CONFIGURE;
+ event.configure.x = xevent.xconfigure.x;
+ event.configure.y = xevent.xconfigure.y;
+ event.configure.width = xevent.xconfigure.width;
+ event.configure.height = xevent.xconfigure.height;
+ break;
+ case Expose:
+ event.type = PUGL_EXPOSE;
+ event.expose.x = xevent.xexpose.x;
+ event.expose.y = xevent.xexpose.y;
+ event.expose.width = xevent.xexpose.width;
+ event.expose.height = xevent.xexpose.height;
+ break;
+ case MotionNotify:
+ event.type = PUGL_MOTION;
+ event.motion.time = (double)xevent.xmotion.time / 1e3;
+ event.motion.x = xevent.xmotion.x;
+ event.motion.y = xevent.xmotion.y;
+ event.motion.xRoot = xevent.xmotion.x_root;
+ event.motion.yRoot = xevent.xmotion.y_root;
+ event.motion.state = translateModifiers(xevent.xmotion.state);
+ if (xevent.xmotion.is_hint == NotifyHint) {
+ event.motion.flags |= PUGL_IS_HINT;
+ }
+ break;
+ case ButtonPress:
+ if (xevent.xbutton.button >= 4 && xevent.xbutton.button <= 7) {
+ event.type = PUGL_SCROLL;
+ event.scroll.time = (double)xevent.xbutton.time / 1e3;
+ event.scroll.x = xevent.xbutton.x;
+ event.scroll.y = xevent.xbutton.y;
+ event.scroll.xRoot = xevent.xbutton.x_root;
+ event.scroll.yRoot = xevent.xbutton.y_root;
+ event.scroll.state = translateModifiers(xevent.xbutton.state);
+ event.scroll.dx = 0.0;
+ event.scroll.dy = 0.0;
+ switch (xevent.xbutton.button) {
+ case 4:
+ event.scroll.dy = 1.0;
+ event.scroll.direction = PUGL_SCROLL_UP;
+ break;
+ case 5:
+ event.scroll.dy = -1.0;
+ event.scroll.direction = PUGL_SCROLL_DOWN;
+ break;
+ case 6:
+ event.scroll.dx = -1.0;
+ event.scroll.direction = PUGL_SCROLL_LEFT;
+ break;
+ case 7:
+ event.scroll.dx = 1.0;
+ event.scroll.direction = PUGL_SCROLL_RIGHT;
+ break;
+ }
+ // fallthru
+ }
+ // fallthru
+ case ButtonRelease:
+ if (xevent.xbutton.button < 4 || xevent.xbutton.button > 7) {
+ event.button.type = ((xevent.type == ButtonPress) ? PUGL_BUTTON_PRESS
+ : PUGL_BUTTON_RELEASE);
+ event.button.time = (double)xevent.xbutton.time / 1e3;
+ event.button.x = xevent.xbutton.x;
+ event.button.y = xevent.xbutton.y;
+ event.button.xRoot = xevent.xbutton.x_root;
+ event.button.yRoot = xevent.xbutton.y_root;
+ event.button.state = translateModifiers(xevent.xbutton.state);
+ event.button.button = xevent.xbutton.button;
+ }
+ break;
+ case KeyPress:
+ case KeyRelease:
+ event.type =
+ ((xevent.type == KeyPress) ? PUGL_KEY_PRESS : PUGL_KEY_RELEASE);
+ event.key.time = (double)xevent.xkey.time / 1e3;
+ event.key.x = xevent.xkey.x;
+ event.key.y = xevent.xkey.y;
+ event.key.xRoot = xevent.xkey.x_root;
+ event.key.yRoot = xevent.xkey.y_root;
+ event.key.state = translateModifiers(xevent.xkey.state);
+ translateKey(view, &xevent, &event);
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ event.type =
+ ((xevent.type == EnterNotify) ? PUGL_POINTER_IN : PUGL_POINTER_OUT);
+ event.crossing.time = (double)xevent.xcrossing.time / 1e3;
+ event.crossing.x = xevent.xcrossing.x;
+ event.crossing.y = xevent.xcrossing.y;
+ event.crossing.xRoot = xevent.xcrossing.x_root;
+ event.crossing.yRoot = xevent.xcrossing.y_root;
+ event.crossing.state = translateModifiers(xevent.xcrossing.state);
+ event.crossing.mode = PUGL_CROSSING_NORMAL;
+ if (xevent.xcrossing.mode == NotifyGrab) {
+ event.crossing.mode = PUGL_CROSSING_GRAB;
+ } else if (xevent.xcrossing.mode == NotifyUngrab) {
+ event.crossing.mode = PUGL_CROSSING_UNGRAB;
+ }
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ event.type = (xevent.type == FocusIn) ? PUGL_FOCUS_IN : PUGL_FOCUS_OUT;
+ event.focus.mode = PUGL_CROSSING_NORMAL;
+ if (xevent.xfocus.mode == NotifyGrab) {
+ event.focus.mode = PUGL_CROSSING_GRAB;
+ } else if (xevent.xfocus.mode == NotifyUngrab) {
+ event.focus.mode = PUGL_CROSSING_UNGRAB;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return event;
}
PuglStatus
puglGrabFocus(PuglView* view)
{
- XSetInputFocus(
- view->impl->display, view->impl->win, RevertToNone, CurrentTime);
- return PUGL_SUCCESS;
+ XSetInputFocus(
+ view->impl->display, view->impl->win, RevertToNone, CurrentTime);
+ return PUGL_SUCCESS;
}
bool
puglHasFocus(const PuglView* view)
{
- int revertTo = 0;
- Window focusedWindow = 0;
- XGetInputFocus(view->impl->display, &focusedWindow, &revertTo);
- return focusedWindow == view->impl->win;
+ int revertTo = 0;
+ Window focusedWindow = 0;
+ XGetInputFocus(view->impl->display, &focusedWindow, &revertTo);
+ return focusedWindow == view->impl->win;
}
PuglStatus
puglRequestAttention(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- const PuglX11Atoms* const atoms = &view->world->impl->atoms;
- XEvent event = {0};
-
- event.type = ClientMessage;
- event.xclient.window = impl->win;
- event.xclient.format = 32;
- event.xclient.message_type = atoms->NET_WM_STATE;
- event.xclient.data.l[0] = WM_STATE_ADD;
- event.xclient.data.l[1] = (long)atoms->NET_WM_STATE_DEMANDS_ATTENTION;
- event.xclient.data.l[2] = 0;
- event.xclient.data.l[3] = 1;
- event.xclient.data.l[4] = 0;
-
- const Window root = RootWindow(impl->display, impl->screen);
- XSendEvent(impl->display,
- root,
- False,
- SubstructureNotifyMask | SubstructureRedirectMask,
- &event);
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ const PuglX11Atoms* const atoms = &view->world->impl->atoms;
+ XEvent event = {0};
+
+ event.type = ClientMessage;
+ event.xclient.window = impl->win;
+ event.xclient.format = 32;
+ event.xclient.message_type = atoms->NET_WM_STATE;
+ event.xclient.data.l[0] = WM_STATE_ADD;
+ event.xclient.data.l[1] = (long)atoms->NET_WM_STATE_DEMANDS_ATTENTION;
+ event.xclient.data.l[2] = 0;
+ event.xclient.data.l[3] = 1;
+ event.xclient.data.l[4] = 0;
+
+ const Window root = RootWindow(impl->display, impl->screen);
+ XSendEvent(impl->display,
+ root,
+ False,
+ SubstructureNotifyMask | SubstructureRedirectMask,
+ &event);
+
+ return PUGL_SUCCESS;
}
PuglStatus
puglStartTimer(PuglView* view, uintptr_t id, double timeout)
{
#ifdef HAVE_XSYNC
- if (view->world->impl->syncSupported) {
- XSyncValue value;
- XSyncIntToValue(&value, (int)floor(timeout * 1000.0));
-
- PuglWorldInternals* w = view->world->impl;
- Display* const display = w->display;
- const XSyncCounter counter = w->serverTimeCounter;
- const XSyncTestType type = XSyncPositiveTransition;
- const XSyncTrigger trigger = {counter, XSyncRelative, value, type};
- XSyncAlarmAttributes attr = {trigger, value, True, XSyncAlarmActive};
- const XSyncAlarm alarm = XSyncCreateAlarm(display, 0x17, &attr);
- const PuglTimer timer = {alarm, view, id};
-
- if (alarm != None) {
- for (size_t i = 0; i < w->numTimers; ++i) {
- if (w->timers[i].view == view && w->timers[i].id == id) {
- // Replace existing timer
- XSyncDestroyAlarm(w->display, w->timers[i].alarm);
- w->timers[i] = timer;
- return PUGL_SUCCESS;
- }
- }
-
- // Add new timer
- const size_t size = ++w->numTimers * sizeof(timer);
- w->timers = (PuglTimer*)realloc(w->timers, size);
- w->timers[w->numTimers - 1] = timer;
- return PUGL_SUCCESS;
- }
- }
+ if (view->world->impl->syncSupported) {
+ XSyncValue value;
+ XSyncIntToValue(&value, (int)floor(timeout * 1000.0));
+
+ PuglWorldInternals* w = view->world->impl;
+ Display* const display = w->display;
+ const XSyncCounter counter = w->serverTimeCounter;
+ const XSyncTestType type = XSyncPositiveTransition;
+ const XSyncTrigger trigger = {counter, XSyncRelative, value, type};
+ XSyncAlarmAttributes attr = {trigger, value, True, XSyncAlarmActive};
+ const XSyncAlarm alarm = XSyncCreateAlarm(display, 0x17, &attr);
+ const PuglTimer timer = {alarm, view, id};
+
+ if (alarm != None) {
+ for (size_t i = 0; i < w->numTimers; ++i) {
+ if (w->timers[i].view == view && w->timers[i].id == id) {
+ // Replace existing timer
+ XSyncDestroyAlarm(w->display, w->timers[i].alarm);
+ w->timers[i] = timer;
+ return PUGL_SUCCESS;
+ }
+ }
+
+ // Add new timer
+ const size_t size = ++w->numTimers * sizeof(timer);
+ w->timers = (PuglTimer*)realloc(w->timers, size);
+ w->timers[w->numTimers - 1] = timer;
+ return PUGL_SUCCESS;
+ }
+ }
#else
- (void)view;
- (void)id;
- (void)timeout;
+ (void)view;
+ (void)id;
+ (void)timeout;
#endif
- return PUGL_FAILURE;
+ return PUGL_FAILURE;
}
PuglStatus
puglStopTimer(PuglView* view, uintptr_t id)
{
#ifdef HAVE_XSYNC
- PuglWorldInternals* w = view->world->impl;
-
- for (size_t i = 0; i < w->numTimers; ++i) {
- if (w->timers[i].view == view && w->timers[i].id == id) {
- XSyncDestroyAlarm(w->display, w->timers[i].alarm);
-
- if (i == w->numTimers - 1) {
- memset(&w->timers[i], 0, sizeof(PuglTimer));
- } else {
- memmove(w->timers + i,
- w->timers + i + 1,
- sizeof(PuglTimer) * (w->numTimers - i - 1));
-
- memset(&w->timers[i], 0, sizeof(PuglTimer));
- }
-
- --w->numTimers;
- return PUGL_SUCCESS;
- }
- }
+ PuglWorldInternals* w = view->world->impl;
+
+ for (size_t i = 0; i < w->numTimers; ++i) {
+ if (w->timers[i].view == view && w->timers[i].id == id) {
+ XSyncDestroyAlarm(w->display, w->timers[i].alarm);
+
+ if (i == w->numTimers - 1) {
+ memset(&w->timers[i], 0, sizeof(PuglTimer));
+ } else {
+ memmove(w->timers + i,
+ w->timers + i + 1,
+ sizeof(PuglTimer) * (w->numTimers - i - 1));
+
+ memset(&w->timers[i], 0, sizeof(PuglTimer));
+ }
+
+ --w->numTimers;
+ return PUGL_SUCCESS;
+ }
+ }
#else
- (void)view;
- (void)id;
+ (void)view;
+ (void)id;
#endif
- return PUGL_FAILURE;
+ return PUGL_FAILURE;
}
static XEvent
puglEventToX(PuglView* view, const PuglEvent* event)
{
- XEvent xev = {0};
- xev.xany.send_event = True;
-
- switch (event->type) {
- case PUGL_EXPOSE: {
- const double x = floor(event->expose.x);
- const double y = floor(event->expose.y);
- const double w = ceil(event->expose.x + event->expose.width) - x;
- const double h = ceil(event->expose.y + event->expose.height) - y;
-
- xev.xexpose.type = Expose;
- xev.xexpose.serial = 0;
- xev.xexpose.display = view->impl->display;
- xev.xexpose.window = view->impl->win;
- xev.xexpose.x = (int)x;
- xev.xexpose.y = (int)y;
- xev.xexpose.width = (int)w;
- xev.xexpose.height = (int)h;
- break;
- }
-
- case PUGL_CLIENT:
- xev.xclient.type = ClientMessage;
- xev.xclient.serial = 0;
- xev.xclient.send_event = True;
- xev.xclient.display = view->impl->display;
- xev.xclient.window = view->impl->win;
- xev.xclient.message_type = view->world->impl->atoms.PUGL_CLIENT_MSG;
- xev.xclient.format = 32;
- xev.xclient.data.l[0] = (long)event->client.data1;
- xev.xclient.data.l[1] = (long)event->client.data2;
- break;
-
- default:
- break;
- }
-
- return xev;
+ XEvent xev = {0};
+ xev.xany.send_event = True;
+
+ switch (event->type) {
+ case PUGL_EXPOSE: {
+ const double x = floor(event->expose.x);
+ const double y = floor(event->expose.y);
+ const double w = ceil(event->expose.x + event->expose.width) - x;
+ const double h = ceil(event->expose.y + event->expose.height) - y;
+
+ xev.xexpose.type = Expose;
+ xev.xexpose.serial = 0;
+ xev.xexpose.display = view->impl->display;
+ xev.xexpose.window = view->impl->win;
+ xev.xexpose.x = (int)x;
+ xev.xexpose.y = (int)y;
+ xev.xexpose.width = (int)w;
+ xev.xexpose.height = (int)h;
+ break;
+ }
+
+ case PUGL_CLIENT:
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = view->impl->display;
+ xev.xclient.window = view->impl->win;
+ xev.xclient.message_type = view->world->impl->atoms.PUGL_CLIENT_MSG;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = (long)event->client.data1;
+ xev.xclient.data.l[1] = (long)event->client.data2;
+ break;
+
+ default:
+ break;
+ }
+
+ return xev;
}
PuglStatus
puglSendEvent(PuglView* view, const PuglEvent* event)
{
- XEvent xev = puglEventToX(view, event);
+ XEvent xev = puglEventToX(view, event);
- if (xev.type) {
- if (XSendEvent(view->impl->display, view->impl->win, False, 0, &xev)) {
- return PUGL_SUCCESS;
- } else {
- return PUGL_UNKNOWN_ERROR;
- }
- }
+ if (xev.type) {
+ if (XSendEvent(view->impl->display, view->impl->win, False, 0, &xev)) {
+ return PUGL_SUCCESS;
+ } else {
+ return PUGL_UNKNOWN_ERROR;
+ }
+ }
- return PUGL_UNSUPPORTED_TYPE;
+ return PUGL_UNSUPPORTED_TYPE;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglWaitForEvent(PuglView* view)
{
- XEvent xevent;
- XPeekEvent(view->impl->display, &xevent);
- return PUGL_SUCCESS;
+ XEvent xevent;
+ XPeekEvent(view->impl->display, &xevent);
+ return PUGL_SUCCESS;
}
#endif
static void
mergeExposeEvents(PuglEventExpose* dst, const PuglEventExpose* src)
{
- if (!dst->type) {
- *dst = *src;
- } else {
- const double max_x = MAX(dst->x + dst->width, src->x + src->width);
- const double max_y = MAX(dst->y + dst->height, src->y + src->height);
-
- dst->x = MIN(dst->x, src->x);
- dst->y = MIN(dst->y, src->y);
- dst->width = max_x - dst->x;
- dst->height = max_y - dst->y;
- }
+ if (!dst->type) {
+ *dst = *src;
+ } else {
+ const double max_x = MAX(dst->x + dst->width, src->x + src->width);
+ const double max_y = MAX(dst->y + dst->height, src->y + src->height);
+
+ dst->x = MIN(dst->x, src->x);
+ dst->y = MIN(dst->y, src->y);
+ dst->width = max_x - dst->x;
+ dst->height = max_y - dst->y;
+ }
}
static void
handleSelectionNotify(const PuglWorld* world, PuglView* view)
{
- uint8_t* str = NULL;
- Atom type = 0;
- int fmt = 0;
- unsigned long len = 0;
- unsigned long left = 0;
-
- XGetWindowProperty(world->impl->display,
- view->impl->win,
- XA_PRIMARY,
- 0,
- 0x1FFFFFFF,
- False,
- AnyPropertyType,
- &type,
- &fmt,
- &len,
- &left,
- &str);
-
- if (str && fmt == 8 && type == world->impl->atoms.UTF8_STRING &&
- left == 0) {
- puglSetBlob(&view->clipboard, str, len);
- }
-
- XFree(str);
+ uint8_t* str = NULL;
+ Atom type = 0;
+ int fmt = 0;
+ unsigned long len = 0;
+ unsigned long left = 0;
+
+ XGetWindowProperty(world->impl->display,
+ view->impl->win,
+ XA_PRIMARY,
+ 0,
+ 0x1FFFFFFF,
+ False,
+ AnyPropertyType,
+ &type,
+ &fmt,
+ &len,
+ &left,
+ &str);
+
+ if (str && fmt == 8 && type == world->impl->atoms.UTF8_STRING && left == 0) {
+ puglSetBlob(&view->clipboard, str, len);
+ }
+
+ XFree(str);
}
static void
@@ -938,305 +970,308 @@ handleSelectionRequest(const PuglWorld* world,
PuglView* view,
const XSelectionRequestEvent* request)
{
- XSelectionEvent note = {SelectionNotify,
- request->serial,
- False,
- world->impl->display,
- request->requestor,
- request->selection,
- request->target,
- None,
- request->time};
-
- const char* type = NULL;
- size_t len = 0;
- const void* data = puglGetInternalClipboard(view, &type, &len);
- if (data && request->selection == world->impl->atoms.CLIPBOARD &&
- request->target == world->impl->atoms.UTF8_STRING) {
- note.property = request->property;
- XChangeProperty(world->impl->display,
- note.requestor,
- note.property,
- note.target,
- 8,
- PropModeReplace,
- (const uint8_t*)data,
- (int)len);
- } else {
- note.property = None;
- }
-
- XSendEvent(world->impl->display, note.requestor, True, 0, (XEvent*)&note);
+ XSelectionEvent note = {SelectionNotify,
+ request->serial,
+ False,
+ world->impl->display,
+ request->requestor,
+ request->selection,
+ request->target,
+ None,
+ request->time};
+
+ const char* type = NULL;
+ size_t len = 0;
+ const void* data = puglGetInternalClipboard(view, &type, &len);
+ if (data && request->selection == world->impl->atoms.CLIPBOARD &&
+ request->target == world->impl->atoms.UTF8_STRING) {
+ note.property = request->property;
+ XChangeProperty(world->impl->display,
+ note.requestor,
+ note.property,
+ note.target,
+ 8,
+ PropModeReplace,
+ (const uint8_t*)data,
+ (int)len);
+ } else {
+ note.property = None;
+ }
+
+ XSendEvent(world->impl->display, note.requestor, True, 0, (XEvent*)&note);
}
/// Flush pending configure and expose events for all views
static void
flushExposures(PuglWorld* world)
{
- for (size_t i = 0; i < world->numViews; ++i) {
- PuglView* const view = world->views[i];
-
- if (view->visible) {
- puglDispatchSimpleEvent(view, PUGL_UPDATE);
- }
-
- const PuglEvent configure = view->impl->pendingConfigure;
- const PuglEvent expose = view->impl->pendingExpose;
-
- view->impl->pendingConfigure.type = PUGL_NOTHING;
- view->impl->pendingExpose.type = PUGL_NOTHING;
-
- if (configure.type || expose.type) {
- view->backend->enter(view, expose.type ? &expose.expose : NULL);
- puglDispatchEventInContext(view, &configure);
- puglDispatchEventInContext(view, &expose);
- view->backend->leave(view, expose.type ? &expose.expose : NULL);
- }
- }
+ for (size_t i = 0; i < world->numViews; ++i) {
+ PuglView* const view = world->views[i];
+
+ if (view->visible) {
+ puglDispatchSimpleEvent(view, PUGL_UPDATE);
+ }
+
+ const PuglEvent configure = view->impl->pendingConfigure;
+ const PuglEvent expose = view->impl->pendingExpose;
+
+ view->impl->pendingConfigure.type = PUGL_NOTHING;
+ view->impl->pendingExpose.type = PUGL_NOTHING;
+
+ if (configure.type || expose.type) {
+ view->backend->enter(view, expose.type ? &expose.expose : NULL);
+ puglDispatchEventInContext(view, &configure);
+ puglDispatchEventInContext(view, &expose);
+ view->backend->leave(view, expose.type ? &expose.expose : NULL);
+ }
+ }
}
static bool
handleTimerEvent(PuglWorld* world, XEvent xevent)
{
#ifdef HAVE_XSYNC
- if (xevent.type == world->impl->syncEventBase + XSyncAlarmNotify) {
- XSyncAlarmNotifyEvent* notify = ((XSyncAlarmNotifyEvent*)&xevent);
-
- for (size_t i = 0; i < world->impl->numTimers; ++i) {
- if (world->impl->timers[i].alarm == notify->alarm) {
- PuglEvent event = {{PUGL_TIMER, 0}};
- event.timer.id = world->impl->timers[i].id;
- puglDispatchEvent(world->impl->timers[i].view,
- (const PuglEvent*)&event);
- }
- }
-
- return true;
- }
+ if (xevent.type == world->impl->syncEventBase + XSyncAlarmNotify) {
+ XSyncAlarmNotifyEvent* notify = ((XSyncAlarmNotifyEvent*)&xevent);
+
+ for (size_t i = 0; i < world->impl->numTimers; ++i) {
+ if (world->impl->timers[i].alarm == notify->alarm) {
+ PuglEvent event = {{PUGL_TIMER, 0}};
+ event.timer.id = world->impl->timers[i].id;
+ puglDispatchEvent(world->impl->timers[i].view,
+ (const PuglEvent*)&event);
+ }
+ }
+
+ return true;
+ }
#else
- (void)world;
- (void)xevent;
+ (void)world;
+ (void)xevent;
#endif
- return false;
+ return false;
}
static PuglStatus
puglDispatchX11Events(PuglWorld* world)
{
- const PuglX11Atoms* const atoms = &world->impl->atoms;
-
- // Flush output to the server once at the start
- Display* display = world->impl->display;
- XFlush(display);
-
- // Process all queued events (without further flushing)
- while (XEventsQueued(display, QueuedAfterReading) > 0) {
- XEvent xevent;
- XNextEvent(display, &xevent);
-
- if (handleTimerEvent(world, xevent)) {
- continue;
- }
-
- PuglView* view = puglFindView(world, xevent.xany.window);
- if (!view) {
- continue;
- }
-
- // Handle special events
- PuglInternals* const impl = view->impl;
- if (xevent.type == KeyRelease && view->hints[PUGL_IGNORE_KEY_REPEAT]) {
- XEvent next;
- if (XCheckTypedWindowEvent(display, impl->win, KeyPress, &next) &&
- next.type == KeyPress &&
- next.xkey.time == xevent.xkey.time &&
- next.xkey.keycode == xevent.xkey.keycode) {
- continue;
- }
- } else if (xevent.type == FocusIn) {
- XSetICFocus(impl->xic);
- } else if (xevent.type == FocusOut) {
- XUnsetICFocus(impl->xic);
- } else if (xevent.type == SelectionClear) {
- puglSetBlob(&view->clipboard, NULL, 0);
- } else if (xevent.type == SelectionNotify &&
- xevent.xselection.selection == atoms->CLIPBOARD &&
- xevent.xselection.target == atoms->UTF8_STRING &&
- xevent.xselection.property == XA_PRIMARY) {
- handleSelectionNotify(world, view);
- } else if (xevent.type == SelectionRequest) {
- handleSelectionRequest(world, view, &xevent.xselectionrequest);
- }
-
- // Translate X11 event to Pugl event
- const PuglEvent event = translateEvent(view, xevent);
-
- if (event.type == PUGL_EXPOSE) {
- // Expand expose event to be dispatched after loop
- mergeExposeEvents(&view->impl->pendingExpose.expose, &event.expose);
- } else if (event.type == PUGL_CONFIGURE) {
- // Expand configure event to be dispatched after loop
- view->impl->pendingConfigure = event;
- view->frame.x = event.configure.x;
- view->frame.y = event.configure.y;
- view->frame.width = event.configure.width;
- view->frame.height = event.configure.height;
- } else if (event.type == PUGL_MAP && view->parent) {
- XWindowAttributes attrs;
- XGetWindowAttributes(view->impl->display, view->impl->win, &attrs);
-
- const PuglEventConfigure configure = {
- PUGL_CONFIGURE, 0, attrs.x, attrs.y, attrs.width, attrs.height};
-
- puglDispatchEvent(view, (const PuglEvent*)&configure);
- puglDispatchEvent(view, &event);
- } else {
- // Dispatch event to application immediately
- puglDispatchEvent(view, &event);
- }
- }
-
- return PUGL_SUCCESS;
+ const PuglX11Atoms* const atoms = &world->impl->atoms;
+
+ // Flush output to the server once at the start
+ Display* display = world->impl->display;
+ XFlush(display);
+
+ // Process all queued events (without further flushing)
+ while (XEventsQueued(display, QueuedAfterReading) > 0) {
+ XEvent xevent;
+ XNextEvent(display, &xevent);
+
+ if (handleTimerEvent(world, xevent)) {
+ continue;
+ }
+
+ PuglView* view = puglFindView(world, xevent.xany.window);
+ if (!view) {
+ continue;
+ }
+
+ // Handle special events
+ PuglInternals* const impl = view->impl;
+ if (xevent.type == KeyRelease && view->hints[PUGL_IGNORE_KEY_REPEAT]) {
+ XEvent next;
+ if (XCheckTypedWindowEvent(display, impl->win, KeyPress, &next) &&
+ next.type == KeyPress && next.xkey.time == xevent.xkey.time &&
+ next.xkey.keycode == xevent.xkey.keycode) {
+ continue;
+ }
+ } else if (xevent.type == FocusIn) {
+ XSetICFocus(impl->xic);
+ } else if (xevent.type == FocusOut) {
+ XUnsetICFocus(impl->xic);
+ } else if (xevent.type == SelectionClear) {
+ puglSetBlob(&view->clipboard, NULL, 0);
+ } else if (xevent.type == SelectionNotify &&
+ xevent.xselection.selection == atoms->CLIPBOARD &&
+ xevent.xselection.target == atoms->UTF8_STRING &&
+ xevent.xselection.property == XA_PRIMARY) {
+ handleSelectionNotify(world, view);
+ } else if (xevent.type == SelectionRequest) {
+ handleSelectionRequest(world, view, &xevent.xselectionrequest);
+ }
+
+ // Translate X11 event to Pugl event
+ const PuglEvent event = translateEvent(view, xevent);
+
+ if (event.type == PUGL_EXPOSE) {
+ // Expand expose event to be dispatched after loop
+ mergeExposeEvents(&view->impl->pendingExpose.expose, &event.expose);
+ } else if (event.type == PUGL_CONFIGURE) {
+ // Expand configure event to be dispatched after loop
+ view->impl->pendingConfigure = event;
+ view->frame.x = event.configure.x;
+ view->frame.y = event.configure.y;
+ view->frame.width = event.configure.width;
+ view->frame.height = event.configure.height;
+ } else if (event.type == PUGL_MAP && view->parent) {
+ XWindowAttributes attrs;
+ XGetWindowAttributes(view->impl->display, view->impl->win, &attrs);
+
+ const PuglEventConfigure configure = {
+ PUGL_CONFIGURE, 0, attrs.x, attrs.y, attrs.width, attrs.height};
+
+ puglDispatchEvent(view, (const PuglEvent*)&configure);
+ puglDispatchEvent(view, &event);
+ } else {
+ // Dispatch event to application immediately
+ puglDispatchEvent(view, &event);
+ }
+ }
+
+ return PUGL_SUCCESS;
}
#ifndef PUGL_DISABLE_DEPRECATED
PuglStatus
puglProcessEvents(PuglView* view)
{
- return puglUpdate(view->world, 0.0);
+ return puglUpdate(view->world, 0.0);
}
#endif
PuglStatus
puglUpdate(PuglWorld* world, double timeout)
{
- const double startTime = puglGetTime(world);
- PuglStatus st = PUGL_SUCCESS;
-
- world->impl->dispatchingEvents = true;
-
- if (timeout < 0.0) {
- st = puglPollX11Socket(world, timeout);
- st = st ? st : puglDispatchX11Events(world);
- } else if (timeout <= 0.001) {
- st = puglDispatchX11Events(world);
- } else {
- const double endTime = startTime + timeout - 0.001;
- for (double t = startTime; t < endTime; t = puglGetTime(world)) {
- if ((st = puglPollX11Socket(world, endTime - t)) ||
- (st = puglDispatchX11Events(world))) {
- break;
- }
- }
- }
-
- flushExposures(world);
-
- world->impl->dispatchingEvents = false;
-
- return st;
+ const double startTime = puglGetTime(world);
+ PuglStatus st = PUGL_SUCCESS;
+
+ world->impl->dispatchingEvents = true;
+
+ if (timeout < 0.0) {
+ st = puglPollX11Socket(world, timeout);
+ st = st ? st : puglDispatchX11Events(world);
+ } else if (timeout <= 0.001) {
+ st = puglDispatchX11Events(world);
+ } else {
+ const double endTime = startTime + timeout - 0.001;
+ for (double t = startTime; t < endTime; t = puglGetTime(world)) {
+ if ((st = puglPollX11Socket(world, endTime - t)) ||
+ (st = puglDispatchX11Events(world))) {
+ break;
+ }
+ }
+ }
+
+ flushExposures(world);
+
+ world->impl->dispatchingEvents = false;
+
+ return st;
}
double
puglGetTime(const PuglWorld* world)
{
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return ((double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0) -
- world->startTime;
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ((double)ts.tv_sec + (double)ts.tv_nsec / 1000000000.0) -
+ world->startTime;
}
PuglStatus
puglPostRedisplay(PuglView* view)
{
- const PuglRect rect = { 0, 0, view->frame.width, view->frame.height };
+ const PuglRect rect = {0, 0, view->frame.width, view->frame.height};
- return puglPostRedisplayRect(view, rect);
+ return puglPostRedisplayRect(view, rect);
}
PuglStatus
puglPostRedisplayRect(PuglView* view, PuglRect rect)
{
- const PuglEventExpose event = {
- PUGL_EXPOSE, 0, rect.x, rect.y, rect.width, rect.height
- };
-
- if (view->world->impl->dispatchingEvents) {
- // Currently dispatching events, add/expand expose for the loop end
- mergeExposeEvents(&view->impl->pendingExpose.expose, &event);
- } else if (view->visible) {
- // Not dispatching events, send an X expose so we wake up next time
- return puglSendEvent(view, (const PuglEvent*)&event);
- }
-
- return PUGL_SUCCESS;
+ const PuglEventExpose event = {
+ PUGL_EXPOSE, 0, rect.x, rect.y, rect.width, rect.height};
+
+ if (view->world->impl->dispatchingEvents) {
+ // Currently dispatching events, add/expand expose for the loop end
+ mergeExposeEvents(&view->impl->pendingExpose.expose, &event);
+ } else if (view->visible) {
+ // Not dispatching events, send an X expose so we wake up next time
+ return puglSendEvent(view, (const PuglEvent*)&event);
+ }
+
+ return PUGL_SUCCESS;
}
PuglNativeView
puglGetNativeWindow(PuglView* view)
{
- return (PuglNativeView)view->impl->win;
+ return (PuglNativeView)view->impl->win;
}
PuglStatus
puglSetWindowTitle(PuglView* view, const char* title)
{
- Display* display = view->world->impl->display;
- const PuglX11Atoms* const atoms = &view->world->impl->atoms;
-
- puglSetString(&view->title, title);
-
- if (view->impl->win) {
- XStoreName(display, view->impl->win, title);
- XChangeProperty(display, view->impl->win, atoms->NET_WM_NAME,
- atoms->UTF8_STRING, 8, PropModeReplace,
- (const uint8_t*)title, (int)strlen(title));
- }
-
- return PUGL_SUCCESS;
+ Display* display = view->world->impl->display;
+ const PuglX11Atoms* const atoms = &view->world->impl->atoms;
+
+ puglSetString(&view->title, title);
+
+ if (view->impl->win) {
+ XStoreName(display, view->impl->win, title);
+ XChangeProperty(display,
+ view->impl->win,
+ atoms->NET_WM_NAME,
+ atoms->UTF8_STRING,
+ 8,
+ PropModeReplace,
+ (const uint8_t*)title,
+ (int)strlen(title));
+ }
+
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetFrame(PuglView* view, const PuglRect frame)
{
- if (view->impl->win) {
- if (!XMoveResizeWindow(view->world->impl->display,
- view->impl->win,
- (int)frame.x,
- (int)frame.y,
- (unsigned)frame.width,
- (unsigned)frame.height)) {
- return PUGL_UNKNOWN_ERROR;
- }
- }
-
- view->frame = frame;
- return PUGL_SUCCESS;
+ if (view->impl->win) {
+ if (!XMoveResizeWindow(view->world->impl->display,
+ view->impl->win,
+ (int)frame.x,
+ (int)frame.y,
+ (unsigned)frame.width,
+ (unsigned)frame.height)) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+ }
+
+ view->frame = frame;
+ return PUGL_SUCCESS;
}
PuglStatus
puglSetDefaultSize(PuglView* const view, const int width, const int height)
{
- view->defaultWidth = width;
- view->defaultHeight = height;
- return updateSizeHints(view);
+ view->defaultWidth = width;
+ view->defaultHeight = height;
+ return updateSizeHints(view);
}
PuglStatus
puglSetMinSize(PuglView* const view, const int width, const int height)
{
- view->minWidth = width;
- view->minHeight = height;
- return updateSizeHints(view);
+ view->minWidth = width;
+ view->minHeight = height;
+ return updateSizeHints(view);
}
PuglStatus
puglSetMaxSize(PuglView* const view, const int width, const int height)
{
- view->minWidth = width;
- view->minHeight = height;
- return updateSizeHints(view);
+ view->minWidth = width;
+ view->minHeight = height;
+ return updateSizeHints(view);
}
PuglStatus
@@ -1246,27 +1281,27 @@ puglSetAspectRatio(PuglView* const view,
const int maxX,
const int maxY)
{
- view->minAspectX = minX;
- view->minAspectY = minY;
- view->maxAspectX = maxX;
- view->maxAspectY = maxY;
+ view->minAspectX = minX;
+ view->minAspectY = minY;
+ view->maxAspectX = maxX;
+ view->maxAspectY = maxY;
- return updateSizeHints(view);
+ return updateSizeHints(view);
}
PuglStatus
puglSetTransientFor(PuglView* view, PuglNativeView parent)
{
- Display* display = view->world->impl->display;
+ Display* display = view->world->impl->display;
- view->transientParent = parent;
+ view->transientParent = parent;
- if (view->impl->win) {
- XSetTransientForHint(display, view->impl->win,
- (Window)view->transientParent);
- }
+ if (view->impl->win) {
+ XSetTransientForHint(
+ display, view->impl->win, (Window)view->transientParent);
+ }
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
const void*
@@ -1274,29 +1309,29 @@ puglGetClipboard(PuglView* const view,
const char** const type,
size_t* const len)
{
- PuglInternals* const impl = view->impl;
- const PuglX11Atoms* const atoms = &view->world->impl->atoms;
-
- const Window owner = XGetSelectionOwner(impl->display, atoms->CLIPBOARD);
- if (owner != None && owner != impl->win) {
- // Clear internal selection
- puglSetBlob(&view->clipboard, NULL, 0);
-
- // Request selection from the owner
- XConvertSelection(impl->display,
- atoms->CLIPBOARD,
- atoms->UTF8_STRING,
- XA_PRIMARY,
- impl->win,
- CurrentTime);
-
- // Run event loop until data is received
- while (!view->clipboard.data) {
- puglUpdate(view->world, -1.0);
- }
- }
-
- return puglGetInternalClipboard(view, type, len);
+ PuglInternals* const impl = view->impl;
+ const PuglX11Atoms* const atoms = &view->world->impl->atoms;
+
+ const Window owner = XGetSelectionOwner(impl->display, atoms->CLIPBOARD);
+ if (owner != None && owner != impl->win) {
+ // Clear internal selection
+ puglSetBlob(&view->clipboard, NULL, 0);
+
+ // Request selection from the owner
+ XConvertSelection(impl->display,
+ atoms->CLIPBOARD,
+ atoms->UTF8_STRING,
+ XA_PRIMARY,
+ impl->win,
+ CurrentTime);
+
+ // Run event loop until data is received
+ while (!view->clipboard.data) {
+ puglUpdate(view->world, -1.0);
+ }
+ }
+
+ return puglGetInternalClipboard(view, type, len);
}
PuglStatus
@@ -1305,27 +1340,27 @@ puglSetClipboard(PuglView* const view,
const void* const data,
const size_t len)
{
- PuglInternals* const impl = view->impl;
- const PuglX11Atoms* const atoms = &view->world->impl->atoms;
+ PuglInternals* const impl = view->impl;
+ const PuglX11Atoms* const atoms = &view->world->impl->atoms;
- PuglStatus st = puglSetInternalClipboard(view, type, data, len);
- if (st) {
- return st;
- }
+ PuglStatus st = puglSetInternalClipboard(view, type, data, len);
+ if (st) {
+ return st;
+ }
- XSetSelectionOwner(impl->display, atoms->CLIPBOARD, impl->win, CurrentTime);
- return PUGL_SUCCESS;
+ XSetSelectionOwner(impl->display, atoms->CLIPBOARD, impl->win, CurrentTime);
+ return PUGL_SUCCESS;
}
#ifdef HAVE_XCURSOR
static const unsigned cursor_nums[] = {
- XC_arrow, // ARROW
- XC_xterm, // CARET
- XC_crosshair, // CROSSHAIR
- XC_hand2, // HAND
- XC_pirate, // NO
- XC_sb_h_double_arrow, // LEFT_RIGHT
- XC_sb_v_double_arrow, // UP_DOWN
+ XC_arrow, // ARROW
+ XC_xterm, // CARET
+ XC_crosshair, // CROSSHAIR
+ XC_hand2, // HAND
+ XC_pirate, // NO
+ XC_sb_h_double_arrow, // LEFT_RIGHT
+ XC_sb_v_double_arrow, // UP_DOWN
};
#endif
@@ -1333,24 +1368,24 @@ PuglStatus
puglSetCursor(PuglView* view, PuglCursor cursor)
{
#ifdef HAVE_XCURSOR
- PuglInternals* const impl = view->impl;
- const unsigned index = (unsigned)cursor;
- const unsigned count = sizeof(cursor_nums) / sizeof(cursor_nums[0]);
- if (index >= count) {
- return PUGL_BAD_PARAMETER;
- }
+ PuglInternals* const impl = view->impl;
+ const unsigned index = (unsigned)cursor;
+ const unsigned count = sizeof(cursor_nums) / sizeof(cursor_nums[0]);
+ if (index >= count) {
+ return PUGL_BAD_PARAMETER;
+ }
- const unsigned shape = cursor_nums[index];
- if (!impl->win || impl->cursorShape == shape) {
- return PUGL_SUCCESS;
- }
+ const unsigned shape = cursor_nums[index];
+ if (!impl->win || impl->cursorShape == shape) {
+ return PUGL_SUCCESS;
+ }
- impl->cursorShape = cursor_nums[index];
+ impl->cursorShape = cursor_nums[index];
- return puglDefineCursorShape(view, impl->cursorShape);
+ return puglDefineCursorShape(view, impl->cursorShape);
#else
- (void)view;
- (void)cursor;
- return PUGL_FAILURE;
+ (void)view;
+ (void)cursor;
+ return PUGL_FAILURE;
#endif
}
diff --git a/src/x11.h b/src/x11.h
index 5749a19..313b4f5 100644
--- a/src/x11.h
+++ b/src/x11.h
@@ -30,48 +30,49 @@
#include <stdint.h>
typedef struct {
- Atom CLIPBOARD;
- Atom UTF8_STRING;
- Atom WM_PROTOCOLS;
- Atom WM_DELETE_WINDOW;
- Atom PUGL_CLIENT_MSG;
- Atom NET_WM_NAME;
- Atom NET_WM_STATE;
- Atom NET_WM_STATE_DEMANDS_ATTENTION;
+ Atom CLIPBOARD;
+ Atom UTF8_STRING;
+ Atom WM_PROTOCOLS;
+ Atom WM_DELETE_WINDOW;
+ Atom PUGL_CLIENT_MSG;
+ Atom NET_WM_NAME;
+ Atom NET_WM_STATE;
+ Atom NET_WM_STATE_DEMANDS_ATTENTION;
} PuglX11Atoms;
typedef struct {
- XID alarm;
- PuglView* view;
- uintptr_t id;
+ XID alarm;
+ PuglView* view;
+ uintptr_t id;
} PuglTimer;
struct PuglWorldInternalsImpl {
- Display* display;
- PuglX11Atoms atoms;
- XIM xim;
- PuglTimer* timers;
- size_t numTimers;
- XID serverTimeCounter;
- int syncEventBase;
- bool syncSupported;
- bool dispatchingEvents;
+ Display* display;
+ PuglX11Atoms atoms;
+ XIM xim;
+ PuglTimer* timers;
+ size_t numTimers;
+ XID serverTimeCounter;
+ int syncEventBase;
+ bool syncSupported;
+ bool dispatchingEvents;
};
struct PuglInternalsImpl {
- Display* display;
- XVisualInfo* vi;
- Window win;
- XIC xic;
- PuglSurface* surface;
- PuglEvent pendingConfigure;
- PuglEvent pendingExpose;
- int screen;
+ Display* display;
+ XVisualInfo* vi;
+ Window win;
+ XIC xic;
+ PuglSurface* surface;
+ PuglEvent pendingConfigure;
+ PuglEvent pendingExpose;
+ int screen;
#ifdef HAVE_XCURSOR
- unsigned cursorShape;
+ unsigned cursorShape;
#endif
};
-PuglStatus puglX11StubConfigure(PuglView* view);
+PuglStatus
+puglX11StubConfigure(PuglView* view);
#endif // PUGL_DETAIL_X11_H
diff --git a/src/x11_cairo.c b/src/x11_cairo.c
index 3147266..a0e7d08 100644
--- a/src/x11_cairo.c
+++ b/src/x11_cairo.c
@@ -27,140 +27,137 @@
#include <stdlib.h>
typedef struct {
- cairo_surface_t* back;
- cairo_surface_t* front;
- cairo_t* cr;
+ cairo_surface_t* back;
+ cairo_surface_t* front;
+ cairo_t* cr;
} PuglX11CairoSurface;
static void
puglX11CairoClose(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- cairo_surface_destroy(surface->front);
- cairo_surface_destroy(surface->back);
- surface->front = surface->back = NULL;
+ cairo_surface_destroy(surface->front);
+ cairo_surface_destroy(surface->back);
+ surface->front = surface->back = NULL;
}
static PuglStatus
puglX11CairoOpen(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
-
- surface->back = cairo_xlib_surface_create(impl->display,
- impl->win,
- impl->vi->visual,
- (int)view->frame.width,
- (int)view->frame.height);
-
- surface->front = cairo_surface_create_similar(
- surface->back,
- cairo_surface_get_content(surface->back),
- (int)view->frame.width,
- (int)view->frame.height);
-
- if (cairo_surface_status(surface->back) ||
- cairo_surface_status(surface->front)) {
- puglX11CairoClose(view);
- return PUGL_CREATE_CONTEXT_FAILED;
- }
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+
+ surface->back = cairo_xlib_surface_create(impl->display,
+ impl->win,
+ impl->vi->visual,
+ (int)view->frame.width,
+ (int)view->frame.height);
+
+ surface->front =
+ cairo_surface_create_similar(surface->back,
+ cairo_surface_get_content(surface->back),
+ (int)view->frame.width,
+ (int)view->frame.height);
+
+ if (cairo_surface_status(surface->back) ||
+ cairo_surface_status(surface->front)) {
+ puglX11CairoClose(view);
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11CairoCreate(PuglView* view)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* const impl = view->impl;
- impl->surface = (cairo_surface_t*)calloc(1, sizeof(PuglX11CairoSurface));
+ impl->surface = (cairo_surface_t*)calloc(1, sizeof(PuglX11CairoSurface));
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11CairoDestroy(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- puglX11CairoClose(view);
- free(surface);
+ puglX11CairoClose(view);
+ free(surface);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11CairoEnter(PuglView* view, const PuglEventExpose* expose)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- PuglStatus st = PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+ PuglStatus st = PUGL_SUCCESS;
- if (expose && !(st = puglX11CairoOpen(view))) {
- surface->cr = cairo_create(surface->front);
+ if (expose && !(st = puglX11CairoOpen(view))) {
+ surface->cr = cairo_create(surface->front);
- if (cairo_status(surface->cr)) {
- st = PUGL_CREATE_CONTEXT_FAILED;
- }
- }
+ if (cairo_status(surface->cr)) {
+ st = PUGL_CREATE_CONTEXT_FAILED;
+ }
+ }
- return st;
+ return st;
}
static PuglStatus
puglX11CairoLeave(PuglView* view, const PuglEventExpose* expose)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
-
- if (expose) {
- // Destroy front context and create a new one for drawing to the back
- cairo_destroy(surface->cr);
- surface->cr = cairo_create(surface->back);
-
- // Clip to expose region
- cairo_rectangle(surface->cr,
- expose->x,
- expose->y,
- expose->width,
- expose->height);
- cairo_clip(surface->cr);
-
- // Paint front onto back
- cairo_set_source_surface(surface->cr, surface->front, 0, 0);
- cairo_paint(surface->cr);
-
- // Flush to X and close everything
- cairo_destroy(surface->cr);
- cairo_surface_flush(surface->back);
- puglX11CairoClose(view);
- surface->cr = NULL;
- }
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+
+ if (expose) {
+ // Destroy front context and create a new one for drawing to the back
+ cairo_destroy(surface->cr);
+ surface->cr = cairo_create(surface->back);
+
+ // Clip to expose region
+ cairo_rectangle(
+ surface->cr, expose->x, expose->y, expose->width, expose->height);
+ cairo_clip(surface->cr);
+
+ // Paint front onto back
+ cairo_set_source_surface(surface->cr, surface->front, 0, 0);
+ cairo_paint(surface->cr);
+
+ // Flush to X and close everything
+ cairo_destroy(surface->cr);
+ cairo_surface_flush(surface->back);
+ puglX11CairoClose(view);
+ surface->cr = NULL;
+ }
+
+ return PUGL_SUCCESS;
}
static void*
puglX11CairoGetContext(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
+ PuglInternals* const impl = view->impl;
+ PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- return surface->cr;
+ return surface->cr;
}
const PuglBackend*
puglCairoBackend(void)
{
- static const PuglBackend backend = {puglX11StubConfigure,
- puglX11CairoCreate,
- puglX11CairoDestroy,
- puglX11CairoEnter,
- puglX11CairoLeave,
- puglX11CairoGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglX11StubConfigure,
+ puglX11CairoCreate,
+ puglX11CairoDestroy,
+ puglX11CairoEnter,
+ puglX11CairoLeave,
+ puglX11CairoGetContext};
+
+ return &backend;
}
diff --git a/src/x11_gl.c b/src/x11_gl.c
index 50b37b8..d0330b0 100644
--- a/src/x11_gl.c
+++ b/src/x11_gl.c
@@ -31,14 +31,14 @@
#include <stdlib.h>
typedef struct {
- GLXFBConfig fb_config;
- GLXContext ctx;
+ GLXFBConfig fb_config;
+ GLXContext ctx;
} PuglX11GlSurface;
static int
puglX11GlHintValue(const int value)
{
- return value == PUGL_DONT_CARE ? (int)GLX_DONT_CARE : value;
+ return value == PUGL_DONT_CARE ? (int)GLX_DONT_CARE : value;
}
static int
@@ -46,185 +46,191 @@ puglX11GlGetAttrib(Display* const display,
GLXFBConfig fb_config,
const int attrib)
{
- int value = 0;
- glXGetFBConfigAttrib(display, fb_config, attrib, &value);
- return value;
+ int value = 0;
+ glXGetFBConfigAttrib(display, fb_config, attrib, &value);
+ return value;
}
static PuglStatus
puglX11GlConfigure(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- const int screen = impl->screen;
- Display* const display = impl->display;
-
- PuglX11GlSurface* const surface =
- (PuglX11GlSurface*)calloc(1, sizeof(PuglX11GlSurface));
- impl->surface = surface;
-
- const int attrs[] = {
- GLX_X_RENDERABLE, True,
- GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
- GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_SAMPLES, puglX11GlHintValue(view->hints[PUGL_SAMPLES]),
- GLX_RED_SIZE, puglX11GlHintValue(view->hints[PUGL_RED_BITS]),
- GLX_GREEN_SIZE, puglX11GlHintValue(view->hints[PUGL_GREEN_BITS]),
- GLX_BLUE_SIZE, puglX11GlHintValue(view->hints[PUGL_BLUE_BITS]),
- GLX_ALPHA_SIZE, puglX11GlHintValue(view->hints[PUGL_ALPHA_BITS]),
- GLX_DEPTH_SIZE, puglX11GlHintValue(view->hints[PUGL_DEPTH_BITS]),
- GLX_STENCIL_SIZE, puglX11GlHintValue(view->hints[PUGL_STENCIL_BITS]),
- GLX_DOUBLEBUFFER, puglX11GlHintValue(view->hints[PUGL_DOUBLE_BUFFER]),
- None
- };
-
- int n_fbc = 0;
- GLXFBConfig* fbc = glXChooseFBConfig(display, screen, attrs, &n_fbc);
- if (n_fbc <= 0) {
- return PUGL_CREATE_CONTEXT_FAILED;
- }
-
- surface->fb_config = fbc[0];
- impl->vi = glXGetVisualFromFBConfig(impl->display, fbc[0]);
-
- view->hints[PUGL_RED_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_RED_SIZE);
- view->hints[PUGL_GREEN_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_GREEN_SIZE);
- view->hints[PUGL_BLUE_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_BLUE_SIZE);
- view->hints[PUGL_ALPHA_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_ALPHA_SIZE);
- view->hints[PUGL_DEPTH_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_DEPTH_SIZE);
- view->hints[PUGL_STENCIL_BITS] = puglX11GlGetAttrib(
- display, fbc[0], GLX_STENCIL_SIZE);
- view->hints[PUGL_SAMPLES] = puglX11GlGetAttrib(
- display, fbc[0], GLX_SAMPLES);
- view->hints[PUGL_DOUBLE_BUFFER] = puglX11GlGetAttrib(
- display, fbc[0], GLX_DOUBLEBUFFER);
-
- XFree(fbc);
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ const int screen = impl->screen;
+ Display* const display = impl->display;
+
+ PuglX11GlSurface* const surface =
+ (PuglX11GlSurface*)calloc(1, sizeof(PuglX11GlSurface));
+ impl->surface = surface;
+
+ // clang-format off
+ const int attrs[] = {
+ GLX_X_RENDERABLE, True,
+ GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_SAMPLES, puglX11GlHintValue(view->hints[PUGL_SAMPLES]),
+ GLX_RED_SIZE, puglX11GlHintValue(view->hints[PUGL_RED_BITS]),
+ GLX_GREEN_SIZE, puglX11GlHintValue(view->hints[PUGL_GREEN_BITS]),
+ GLX_BLUE_SIZE, puglX11GlHintValue(view->hints[PUGL_BLUE_BITS]),
+ GLX_ALPHA_SIZE, puglX11GlHintValue(view->hints[PUGL_ALPHA_BITS]),
+ GLX_DEPTH_SIZE, puglX11GlHintValue(view->hints[PUGL_DEPTH_BITS]),
+ GLX_STENCIL_SIZE, puglX11GlHintValue(view->hints[PUGL_STENCIL_BITS]),
+ GLX_DOUBLEBUFFER, puglX11GlHintValue(view->hints[PUGL_DOUBLE_BUFFER]),
+ None
+ };
+ // clang-format on
+
+ int n_fbc = 0;
+ GLXFBConfig* fbc = glXChooseFBConfig(display, screen, attrs, &n_fbc);
+ if (n_fbc <= 0) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
+
+ surface->fb_config = fbc[0];
+ impl->vi = glXGetVisualFromFBConfig(impl->display, fbc[0]);
+
+ view->hints[PUGL_RED_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_RED_SIZE);
+ view->hints[PUGL_GREEN_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_GREEN_SIZE);
+ view->hints[PUGL_BLUE_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_BLUE_SIZE);
+ view->hints[PUGL_ALPHA_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_ALPHA_SIZE);
+ view->hints[PUGL_DEPTH_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_DEPTH_SIZE);
+ view->hints[PUGL_STENCIL_BITS] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_STENCIL_SIZE);
+ view->hints[PUGL_SAMPLES] = puglX11GlGetAttrib(display, fbc[0], GLX_SAMPLES);
+ view->hints[PUGL_DOUBLE_BUFFER] =
+ puglX11GlGetAttrib(display, fbc[0], GLX_DOUBLEBUFFER);
+
+ XFree(fbc);
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11GlEnter(PuglView* view, const PuglEventExpose* PUGL_UNUSED(expose))
{
- PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
- glXMakeCurrent(view->impl->display, view->impl->win, surface->ctx);
- return PUGL_SUCCESS;
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
+ glXMakeCurrent(view->impl->display, view->impl->win, surface->ctx);
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11GlLeave(PuglView* view, const PuglEventExpose* expose)
{
- if (expose && view->hints[PUGL_DOUBLE_BUFFER]) {
- glXSwapBuffers(view->impl->display, view->impl->win);
- }
+ if (expose && view->hints[PUGL_DOUBLE_BUFFER]) {
+ glXSwapBuffers(view->impl->display, view->impl->win);
+ }
- glXMakeCurrent(view->impl->display, None, NULL);
+ glXMakeCurrent(view->impl->display, None, NULL);
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11GlCreate(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- PuglX11GlSurface* const surface = (PuglX11GlSurface*)impl->surface;
- Display* const display = impl->display;
- GLXFBConfig fb_config = surface->fb_config;
-
- const int ctx_attrs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, view->hints[PUGL_CONTEXT_VERSION_MAJOR],
- GLX_CONTEXT_MINOR_VERSION_ARB, view->hints[PUGL_CONTEXT_VERSION_MINOR],
- GLX_CONTEXT_FLAGS_ARB, (view->hints[PUGL_USE_DEBUG_CONTEXT]
- ? GLX_CONTEXT_DEBUG_BIT_ARB
- : 0),
- GLX_CONTEXT_PROFILE_MASK_ARB, (view->hints[PUGL_USE_COMPAT_PROFILE]
- ? GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
- : GLX_CONTEXT_CORE_PROFILE_BIT_ARB),
- 0};
-
- PFNGLXCREATECONTEXTATTRIBSARBPROC create_context =
- (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(
- (const uint8_t*)"glXCreateContextAttribsARB");
-
- PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
- (PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress(
- (const uint8_t*)"glXSwapIntervalEXT");
-
- surface->ctx = create_context(display, fb_config, 0, True, ctx_attrs);
- if (!surface->ctx) {
- surface->ctx =
- glXCreateNewContext(display, fb_config, GLX_RGBA_TYPE, 0, True);
- }
-
- if (!surface->ctx) {
- return PUGL_CREATE_CONTEXT_FAILED;
- }
-
- const int swapInterval = view->hints[PUGL_SWAP_INTERVAL];
- if (glXSwapIntervalEXT && swapInterval != PUGL_DONT_CARE) {
- puglX11GlEnter(view, NULL);
- glXSwapIntervalEXT(display, impl->win, swapInterval);
- puglX11GlLeave(view, NULL);
- }
-
- glXGetConfig(impl->display,
- impl->vi,
- GLX_DOUBLEBUFFER,
- &view->hints[PUGL_DOUBLE_BUFFER]);
-
- glXQueryDrawable(display,
- impl->win,
- GLX_SWAP_INTERVAL_EXT,
- (unsigned int*)&view->hints[PUGL_SWAP_INTERVAL]);
-
- return PUGL_SUCCESS;
+ PuglInternals* const impl = view->impl;
+ PuglX11GlSurface* const surface = (PuglX11GlSurface*)impl->surface;
+ Display* const display = impl->display;
+ GLXFBConfig fb_config = surface->fb_config;
+
+ const int ctx_attrs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB,
+ view->hints[PUGL_CONTEXT_VERSION_MAJOR],
+
+ GLX_CONTEXT_MINOR_VERSION_ARB,
+ view->hints[PUGL_CONTEXT_VERSION_MINOR],
+
+ GLX_CONTEXT_FLAGS_ARB,
+ (view->hints[PUGL_USE_DEBUG_CONTEXT] ? GLX_CONTEXT_DEBUG_BIT_ARB : 0),
+
+ GLX_CONTEXT_PROFILE_MASK_ARB,
+ (view->hints[PUGL_USE_COMPAT_PROFILE]
+ ? GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
+ : GLX_CONTEXT_CORE_PROFILE_BIT_ARB),
+ 0};
+
+ PFNGLXCREATECONTEXTATTRIBSARBPROC create_context =
+ (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress(
+ (const uint8_t*)"glXCreateContextAttribsARB");
+
+ PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT =
+ (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress(
+ (const uint8_t*)"glXSwapIntervalEXT");
+
+ surface->ctx = create_context(display, fb_config, 0, True, ctx_attrs);
+ if (!surface->ctx) {
+ surface->ctx =
+ glXCreateNewContext(display, fb_config, GLX_RGBA_TYPE, 0, True);
+ }
+
+ if (!surface->ctx) {
+ return PUGL_CREATE_CONTEXT_FAILED;
+ }
+
+ const int swapInterval = view->hints[PUGL_SWAP_INTERVAL];
+ if (glXSwapIntervalEXT && swapInterval != PUGL_DONT_CARE) {
+ puglX11GlEnter(view, NULL);
+ glXSwapIntervalEXT(display, impl->win, swapInterval);
+ puglX11GlLeave(view, NULL);
+ }
+
+ glXGetConfig(impl->display,
+ impl->vi,
+ GLX_DOUBLEBUFFER,
+ &view->hints[PUGL_DOUBLE_BUFFER]);
+
+ glXQueryDrawable(display,
+ impl->win,
+ GLX_SWAP_INTERVAL_EXT,
+ (unsigned int*)&view->hints[PUGL_SWAP_INTERVAL]);
+
+ return PUGL_SUCCESS;
}
static PuglStatus
puglX11GlDestroy(PuglView* view)
{
- PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
- if (surface) {
- glXDestroyContext(view->impl->display, surface->ctx);
- free(surface);
- view->impl->surface = NULL;
- }
- return PUGL_SUCCESS;
+ PuglX11GlSurface* surface = (PuglX11GlSurface*)view->impl->surface;
+ if (surface) {
+ glXDestroyContext(view->impl->display, surface->ctx);
+ free(surface);
+ view->impl->surface = NULL;
+ }
+ return PUGL_SUCCESS;
}
PuglGlFunc
puglGetProcAddress(const char* name)
{
- return glXGetProcAddress((const uint8_t*)name);
+ return glXGetProcAddress((const uint8_t*)name);
}
PuglStatus
puglEnterContext(PuglView* view)
{
- return view->backend->enter(view, NULL);
+ return view->backend->enter(view, NULL);
}
PuglStatus
puglLeaveContext(PuglView* view)
{
- return view->backend->leave(view, NULL);
+ return view->backend->leave(view, NULL);
}
const PuglBackend*
puglGlBackend(void)
{
- static const PuglBackend backend = {puglX11GlConfigure,
- puglX11GlCreate,
- puglX11GlDestroy,
- puglX11GlEnter,
- puglX11GlLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglX11GlConfigure,
+ puglX11GlCreate,
+ puglX11GlDestroy,
+ puglX11GlEnter,
+ puglX11GlLeave,
+ puglStubGetContext};
+
+ return &backend;
}
diff --git a/src/x11_stub.c b/src/x11_stub.c
index be66a88..de89a86 100644
--- a/src/x11_stub.c
+++ b/src/x11_stub.c
@@ -27,32 +27,32 @@
PuglStatus
puglX11StubConfigure(PuglView* view)
{
- PuglInternals* const impl = view->impl;
- XVisualInfo pat = {0};
- int n = 0;
+ PuglInternals* const impl = view->impl;
+ XVisualInfo pat = {0};
+ int n = 0;
- pat.screen = impl->screen;
- impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n);
+ pat.screen = impl->screen;
+ impl->vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n);
- view->hints[PUGL_RED_BITS] = impl->vi->bits_per_rgb;
- view->hints[PUGL_GREEN_BITS] = impl->vi->bits_per_rgb;
- view->hints[PUGL_BLUE_BITS] = impl->vi->bits_per_rgb;
- view->hints[PUGL_ALPHA_BITS] = 0;
+ view->hints[PUGL_RED_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_GREEN_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_BLUE_BITS] = impl->vi->bits_per_rgb;
+ view->hints[PUGL_ALPHA_BITS] = 0;
- return PUGL_SUCCESS;
+ return PUGL_SUCCESS;
}
const PuglBackend*
puglStubBackend(void)
{
- static const PuglBackend backend = {
- puglX11StubConfigure,
- puglStubCreate,
- puglStubDestroy,
- puglStubEnter,
- puglStubLeave,
- puglStubGetContext,
- };
-
- return &backend;
+ static const PuglBackend backend = {
+ puglX11StubConfigure,
+ puglStubCreate,
+ puglStubDestroy,
+ puglStubEnter,
+ puglStubLeave,
+ puglStubGetContext,
+ };
+
+ return &backend;
}
diff --git a/src/x11_vulkan.c b/src/x11_vulkan.c
index b32111c..77bdd59 100644
--- a/src/x11_vulkan.c
+++ b/src/x11_vulkan.c
@@ -31,78 +31,77 @@
#include <stdint.h>
#include <stdlib.h>
-struct PuglVulkanLoaderImpl
-{
- void* libvulkan;
- PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
- PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+struct PuglVulkanLoaderImpl {
+ void* libvulkan;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
};
PuglVulkanLoader*
puglNewVulkanLoader(PuglWorld* PUGL_UNUSED(world))
{
- PuglVulkanLoader* loader =
- (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader));
- if (!loader) {
- return NULL;
- }
+ PuglVulkanLoader* loader =
+ (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader));
+ if (!loader) {
+ return NULL;
+ }
- if (!(loader->libvulkan = dlopen("libvulkan.so", RTLD_LAZY))) {
- free(loader);
- return NULL;
- }
+ if (!(loader->libvulkan = dlopen("libvulkan.so", RTLD_LAZY))) {
+ free(loader);
+ return NULL;
+ }
- loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(
- loader->libvulkan, "vkGetInstanceProcAddr");
+ loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(
+ loader->libvulkan, "vkGetInstanceProcAddr");
- loader->vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)dlsym(
- loader->libvulkan, "vkGetDeviceProcAddr");
+ loader->vkGetDeviceProcAddr =
+ (PFN_vkGetDeviceProcAddr)dlsym(loader->libvulkan, "vkGetDeviceProcAddr");
- return loader;
+ return loader;
}
void
puglFreeVulkanLoader(PuglVulkanLoader* loader)
{
- if (loader) {
- dlclose(loader->libvulkan);
- free(loader);
- }
+ if (loader) {
+ dlclose(loader->libvulkan);
+ free(loader);
+ }
}
PFN_vkGetInstanceProcAddr
puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetInstanceProcAddr;
+ return loader->vkGetInstanceProcAddr;
}
PFN_vkGetDeviceProcAddr
puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader)
{
- return loader->vkGetDeviceProcAddr;
+ return loader->vkGetDeviceProcAddr;
}
const PuglBackend*
puglVulkanBackend(void)
{
- static const PuglBackend backend = {puglX11StubConfigure,
- puglStubCreate,
- puglStubDestroy,
- puglStubEnter,
- puglStubLeave,
- puglStubGetContext};
-
- return &backend;
+ static const PuglBackend backend = {puglX11StubConfigure,
+ puglStubCreate,
+ puglStubDestroy,
+ puglStubEnter,
+ puglStubLeave,
+ puglStubGetContext};
+
+ return &backend;
}
const char* const*
puglGetInstanceExtensions(uint32_t* const count)
{
- static const char* const extensions[] = {"VK_KHR_surface",
- "VK_KHR_xlib_surface"};
+ static const char* const extensions[] = {"VK_KHR_surface",
+ "VK_KHR_xlib_surface"};
- *count = 2;
- return extensions;
+ *count = 2;
+ return extensions;
}
VkResult
@@ -112,20 +111,20 @@ puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr,
const VkAllocationCallbacks* const allocator,
VkSurfaceKHR* const surface)
{
- PuglInternals* const impl = view->impl;
- PuglWorldInternals* world_impl = view->world->impl;
-
- PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
- (PFN_vkCreateXlibSurfaceKHR)
- vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");
-
- const VkXlibSurfaceCreateInfoKHR info = {
- VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
- NULL,
- 0,
- world_impl->display,
- impl->win,
- };
-
- return vkCreateXlibSurfaceKHR(instance, &info, allocator, surface);
+ PuglInternals* const impl = view->impl;
+ PuglWorldInternals* world_impl = view->world->impl;
+
+ PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR =
+ (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr(instance,
+ "vkCreateXlibSurfaceKHR");
+
+ const VkXlibSurfaceCreateInfoKHR info = {
+ VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
+ NULL,
+ 0,
+ world_impl->display,
+ impl->win,
+ };
+
+ return vkCreateXlibSurfaceKHR(instance, &info, allocator, surface);
}