From 87351f2a8aaaad988b44e985ac5240af43d331e3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 15 Mar 2020 18:14:19 +0100 Subject: Add type and flags to world Unfortunately this is an API break, but there's no reasonable way to deprecate the old function and this is required for things to work correctly. The type will be used in following commits to tick the main loop and dispatch events correctly for either case. --- examples/pugl_cairo_demo.c | 2 +- examples/pugl_embed_demo.c | 2 +- examples/pugl_gl3_demo.c | 2 +- examples/pugl_print_events.c | 2 +- examples/pugl_window_demo.c | 2 +- pugl/detail/implementation.c | 4 ++-- pugl/detail/implementation.h | 3 ++- pugl/detail/mac.m | 3 ++- pugl/detail/win.c | 3 ++- pugl/detail/x11.c | 6 +++++- pugl/pugl.h | 31 +++++++++++++++++++++++++++++-- test/test_redisplay.c | 2 +- test/test_show_hide.c | 2 +- 13 files changed, 49 insertions(+), 15 deletions(-) diff --git a/examples/pugl_cairo_demo.c b/examples/pugl_cairo_demo.c index da59e8c..d2e57f8 100644 --- a/examples/pugl_cairo_demo.c +++ b/examples/pugl_cairo_demo.c @@ -227,7 +227,7 @@ main(int argc, char** argv) return 1; } - app.world = puglNewWorld(); + app.world = puglNewWorld(PUGL_PROGRAM, 0); puglSetClassName(app.world, "PuglCairoTest"); PuglRect frame = { 0, 0, 512, 512 }; diff --git a/examples/pugl_embed_demo.c b/examples/pugl_embed_demo.c index dc80b18..6bafae5 100644 --- a/examples/pugl_embed_demo.c +++ b/examples/pugl_embed_demo.c @@ -262,7 +262,7 @@ main(int argc, char** argv) app.continuous = opts.continuous; app.verbose = opts.verbose; - app.world = puglNewWorld(); + app.world = puglNewWorld(PUGL_PROGRAM, 0); app.parent = puglNewView(app.world); app.child = puglNewView(app.world); diff --git a/examples/pugl_gl3_demo.c b/examples/pugl_gl3_demo.c index ec36d16..e0c63ca 100644 --- a/examples/pugl_gl3_demo.c +++ b/examples/pugl_gl3_demo.c @@ -260,7 +260,7 @@ static void setupPugl(PuglTestApp* app, const PuglRect frame) { // Create world, view, and rect data - app->world = puglNewWorld(); + app->world = puglNewWorld(PUGL_PROGRAM, 0); app->view = puglNewView(app->world); app->rects = makeRects(app->numRects); diff --git a/examples/pugl_print_events.c b/examples/pugl_print_events.c index 5d2785e..c662117 100644 --- a/examples/pugl_print_events.c +++ b/examples/pugl_print_events.c @@ -53,7 +53,7 @@ main(void) { PuglPrintEventsApp app = {NULL, NULL, 0}; - app.world = puglNewWorld(); + app.world = puglNewWorld(PUGL_PROGRAM, 0); app.view = puglNewView(app.world); puglSetClassName(app.world, "Pugl Print Events"); diff --git a/examples/pugl_window_demo.c b/examples/pugl_window_demo.c index 18def43..394b959 100644 --- a/examples/pugl_window_demo.c +++ b/examples/pugl_window_demo.c @@ -181,7 +181,7 @@ main(int argc, char** argv) app.continuous = opts.continuous; app.verbose = opts.verbose; - app.world = puglNewWorld(); + app.world = puglNewWorld(PUGL_PROGRAM, 0); app.cubes[0].view = puglNewView(app.world); app.cubes[1].view = puglNewView(app.world); diff --git a/pugl/detail/implementation.c b/pugl/detail/implementation.c index 17cc6fd..b2306c6 100644 --- a/pugl/detail/implementation.c +++ b/pugl/detail/implementation.c @@ -115,10 +115,10 @@ puglSetDefaultHints(PuglHints hints) } PuglWorld* -puglNewWorld(void) +puglNewWorld(PuglWorldType type, PuglWorldFlags flags) { PuglWorld* world = (PuglWorld*)calloc(1, sizeof(PuglWorld)); - if (!world || !(world->impl = puglInitWorldInternals())) { + if (!world || !(world->impl = puglInitWorldInternals(type, flags))) { free(world); return NULL; } diff --git a/pugl/detail/implementation.h b/pugl/detail/implementation.h index f363a30..2ad3f65 100644 --- a/pugl/detail/implementation.h +++ b/pugl/detail/implementation.h @@ -36,7 +36,8 @@ void puglSetBlob(PuglBlob* dest, const void* data, size_t len); void puglSetString(char** dest, const char* string); /** Allocate and initialise world internals (implemented once per platform) */ -PuglWorldInternals* puglInitWorldInternals(void); +PuglWorldInternals* +puglInitWorldInternals(PuglWorldType type, PuglWorldFlags flags); /** Destroy and free world internals (implemented once per platform) */ void puglFreeWorldInternals(PuglWorld* world); diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m index 2920675..ab59b99 100644 --- a/pugl/detail/mac.m +++ b/pugl/detail/mac.m @@ -695,7 +695,8 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type) @end PuglWorldInternals* -puglInitWorldInternals(void) +puglInitWorldInternals(PuglWorldType PUGL_UNUSED(type), + PuglWorldFlags PUGL_UNUSED(flags)) { PuglWorldInternals* impl = (PuglWorldInternals*)calloc( 1, sizeof(PuglWorldInternals)); diff --git a/pugl/detail/win.c b/pugl/detail/win.c index 290a658..bbaa872 100644 --- a/pugl/detail/win.c +++ b/pugl/detail/win.c @@ -105,7 +105,8 @@ puglRegisterWindowClass(const char* name) } PuglWorldInternals* -puglInitWorldInternals(void) +puglInitWorldInternals(PuglWorldType PUGL_UNUSED(type), + PuglWorldFlags PUGL_UNUSED(flags)) { PuglWorldInternals* impl = (PuglWorldInternals*)calloc( 1, sizeof(PuglWorldInternals)); diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c index 10ae0bb..7edc1ed 100644 --- a/pugl/detail/x11.c +++ b/pugl/detail/x11.c @@ -66,8 +66,12 @@ static const long eventMask = ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask); PuglWorldInternals* -puglInitWorldInternals(void) +puglInitWorldInternals(PuglWorldType type, PuglWorldFlags flags) { + if (type == PUGL_PROGRAM && (flags & PUGL_WORLD_THREADS)) { + XInitThreads(); + } + Display* display = XOpenDisplay(NULL); if (!display) { return NULL; diff --git a/pugl/pugl.h b/pugl/pugl.h index c5f8969..d215749 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -490,6 +490,31 @@ typedef struct PuglWorldImpl PuglWorld; */ typedef void* PuglWorldHandle; +/** + The type of a PuglWorld. +*/ +typedef enum { + PUGL_PROGRAM, ///< Top-level application + PUGL_MODULE ///< Plugin or module within a larger application +} PuglWorldType; + +/** + World flags. +*/ +typedef enum { + /** + Set up support for threads if necessary. + + - X11: Calls XInitThreads() which is required for some drivers. + */ + PUGL_WORLD_THREADS = 1 << 0 +} PuglWorldFlag; + +/** + Bitwise OR of #PuglWorldFlag values. +*/ +typedef uint32_t PuglWorldFlags; + /** A log message level, compatible with syslog. */ @@ -514,10 +539,12 @@ typedef void (*PuglLogFunc)(PuglWorld* world, /** Create a new world. + @param type The type, which dictates what this world is responsible for. + @param flags Flags to control world features. @return A new world, which must be later freed with puglFreeWorld(). */ PUGL_API PuglWorld* -puglNewWorld(void); +puglNewWorld(PuglWorldType type, PuglWorldFlags flags); /** Free a world allocated with puglNewWorld(). @@ -1057,7 +1084,7 @@ puglInit(const int* pargc, char** argv) (void)pargc; (void)argv; - return puglNewView(puglNewWorld()); + return puglNewView(puglNewWorld(PUGL_MODULE, 0)); } /** diff --git a/test/test_redisplay.c b/test/test_redisplay.c index f5f0707..4470053 100644 --- a/test/test_redisplay.c +++ b/test/test_redisplay.c @@ -96,7 +96,7 @@ int main(int argc, char** argv) { PuglTest app = {puglParseTestOptions(&argc, &argv), - puglNewWorld(), + puglNewWorld(PUGL_PROGRAM, 0), NULL, START}; diff --git a/test/test_show_hide.c b/test/test_show_hide.c index 4877388..b942f45 100644 --- a/test/test_show_hide.c +++ b/test/test_show_hide.c @@ -107,7 +107,7 @@ int main(int argc, char** argv) { PuglTest test = {puglParseTestOptions(&argc, &argv), - puglNewWorld(), + puglNewWorld(PUGL_PROGRAM, 0), NULL, START}; -- cgit v1.2.1