aboutsummaryrefslogtreecommitdiff
path: root/pugl/src/implementation.c
diff options
context:
space:
mode:
Diffstat (limited to 'pugl/src/implementation.c')
-rw-r--r--pugl/src/implementation.c461
1 files changed, 237 insertions, 224 deletions
diff --git a/pugl/src/implementation.c b/pugl/src/implementation.c
index e9b7e5a..47b52b8 100644
--- a/pugl/src/implementation.c
+++ b/pugl/src/implementation.c
@@ -26,249 +26,250 @@
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);
+ 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);
free(view->clipboardType.data);
- puglFreeViewInternals(view);
- free(view);
+ 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
@@ -276,25 +277,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
@@ -302,112 +303,125 @@ 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];
+ }
+
+ if (buf[0] < 0xC2) {
+ return 0xFFFD;
+ }
+
+ if (buf[0] < 0xE0) {
+ FAIL_IF((buf[1] & 0xC0u) != 0x80);
+ return ((uint32_t)buf[0] << 6u) + buf[1] - 0x3080u;
+ }
+
+ 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);
+ }
+
+ 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*
@@ -415,15 +429,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) {
+ if (type) {
*type = view->clipboardType.data;
- }
+ }
- return view->clipboard.data;
+ return view->clipboard.data;
}
PuglStatus
@@ -433,11 +447,10 @@ puglSetInternalClipboard(PuglView* const view,
const size_t len)
{
if (!type) {
- return PUGL_UNSUPPORTED_TYPE;
- }
+ return PUGL_UNSUPPORTED_TYPE;
+ }
puglSetBlob(&view->clipboardType, type, strlen(type) + 1);
- puglSetBlob(&view->clipboard, data, len);
- return PUGL_SUCCESS;
+ puglSetBlob(&view->clipboard, data, len);
+ return PUGL_SUCCESS;
}
-