From a739e6116f026e2fe334f447082616712a1cfd78 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 13 May 2014 15:30:36 +0000 Subject: Fix non-extensible puglInit API. Fix memory leak. --- pugl/pugl.h | 61 ++++++++++++++++++++++++++++++++++---------- pugl/pugl_internal.h | 48 +++++++++++++++++++++++++++++++++-- pugl/pugl_win.cpp | 28 +++++++++++++++----- pugl/pugl_x11.c | 72 ++++++++++++++++++++++++++++------------------------ pugl_test.c | 8 +++++- 5 files changed, 161 insertions(+), 56 deletions(-) diff --git a/pugl/pugl.h b/pugl/pugl.h index 2a6a59f..360f8e8 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -1,5 +1,5 @@ /* - Copyright 2012 David Robillard + Copyright 2012-2014 David Robillard Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -217,21 +217,54 @@ typedef void (*PuglScrollFunc)(PuglView* view, typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key); /** - Create a new GL window. - @param parent Parent window, or 0 for top level. - @param title Window title, or NULL. - @param width Window width in pixels. - @param height Window height in pixels. - @param resizable Whether window should be user resizable. - @param visible Whether window should be initially visible. + Create a Pugl context. + + To create a window, call the various puglInit* functions as necessary, then + call puglCreateWindow(). + + @param pargc Pointer to argument count (unused, for GLUT compatibility). + @param argv Arguments (unused, for GLUT compatibility). */ PUGL_API PuglView* -puglCreate(PuglNativeWindow parent, - const char* title, - int width, - int height, - bool resizable, - bool visible); +puglInit(int* pargc, char** argv); + +/** + Set the parent window before creating a window (for embedding). +*/ +PUGL_API void +puglInitWindowParent(PuglView* view, PuglNativeWindow parent); + +/** + Set the window size before creating a window. +*/ +PUGL_API void +puglInitWindowSize(PuglView* view, int width, int height); + +/** + Enable or disable resizing before creating a window. +*/ +PUGL_API void +puglInitResizable(PuglView* view, bool resizable); + +/** + Create a window with the settings given by the various puglInit functions. + + @return 1 (pugl does not currently support multiple windows). +*/ +PUGL_API int +puglCreateWindow(PuglView* view, const char* title); + +/** + Show the current window. +*/ +PUGL_API void +puglShowWindow(PuglView* view); + +/** + Hide the current window. +*/ +PUGL_API void +puglHideWindow(PuglView* view); /** Set the handle to be passed to all callbacks. diff --git a/pugl/pugl_internal.h b/pugl/pugl_internal.h index 74aae55..6813fef 100644 --- a/pugl/pugl_internal.h +++ b/pugl/pugl_internal.h @@ -39,8 +39,6 @@ # define PUGL_LOGF(fmt, ...) #endif -void puglDefaultReshape(PuglView* view, int width, int height); - typedef struct PuglInternalsImpl PuglInternals; struct PuglViewImpl { @@ -56,15 +54,61 @@ struct PuglViewImpl { PuglInternals* impl; + PuglNativeWindow parent; + int width; int height; int mods; bool mouse_in_view; bool ignoreKeyRepeat; bool redisplay; + bool resizable; uint32_t event_timestamp_ms; }; +PuglInternals* puglInitInternals(); + +void puglDefaultReshape(PuglView* view, int width, int height); + +PuglView* +puglInit(int* pargc, char** argv) +{ + PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); + if (!view) { + return NULL; + } + + PuglInternals* impl = puglInitInternals(); + if (!impl) { + return NULL; + } + + view->impl = impl; + view->width = 640; + view->height = 480; + + return view; +} + +void +puglInitWindowSize(PuglView* view, int width, int height) +{ + view->width = width; + view->height = height; +} + +void +puglInitWindowParent(PuglView* view, PuglNativeWindow parent) +{ + view->parent = parent; +} + +void +puglInitResizable(PuglView* view, bool resizable) +{ + view->resizable = true; +} + void puglSetHandle(PuglView* view, PuglHandle handle) { diff --git a/pugl/pugl_win.cpp b/pugl/pugl_win.cpp index 47ba18e..3cdfcb5 100644 --- a/pugl/pugl_win.cpp +++ b/pugl/pugl_win.cpp @@ -50,12 +50,28 @@ LRESULT CALLBACK wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); PuglView* -puglCreate(PuglNativeWindow parent, - const char* title, - int width, - int height, - bool resizable, - bool visible) +puglInit() +{ + PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); + PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); + if (!view || !impl) { + return NULL; + } + + view->impl = impl; + view->width = 640; + view->height = 480; + + return view; +} + +PuglView* +puglCreateInternals(PuglNativeWindow parent, + const char* title, + int width, + int height, + bool resizable, + bool visible) { PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); diff --git a/pugl/pugl_x11.c b/pugl/pugl_x11.c index 8e1de69..ce3547f 100644 --- a/pugl/pugl_x11.c +++ b/pugl/pugl_x11.c @@ -65,23 +65,16 @@ static int attrListDbl[] = { None }; -PuglView* -puglCreate(PuglNativeWindow parent, - const char* title, - int width, - int height, - bool resizable, - bool visible) +PuglInternals* +puglInitInternals() { - PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); - PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); - if (!view || !impl) { - return NULL; - } + return (PuglInternals*)calloc(1, sizeof(PuglInternals)); +} - view->impl = impl; - view->width = width; - view->height = height; +int +puglCreateWindow(PuglView* view, const char* title) +{ + PuglInternals* impl = view->impl; impl->display = XOpenDisplay(0); impl->screen = DefaultScreen(impl->display); @@ -102,8 +95,8 @@ puglCreate(PuglNativeWindow parent, impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); - Window xParent = parent - ? (Window)parent + Window xParent = view->parent + ? (Window)view->parent : RootWindow(impl->display, impl->screen); Colormap cmap = XCreateColormap( @@ -128,12 +121,12 @@ puglCreate(PuglNativeWindow parent, XSizeHints sizeHints; memset(&sizeHints, 0, sizeof(sizeHints)); - if (!resizable) { + if (!view->resizable) { sizeHints.flags = PMinSize|PMaxSize; - sizeHints.min_width = width; - sizeHints.min_height = height; - sizeHints.max_width = width; - sizeHints.max_height = height; + sizeHints.min_width = view->width; + sizeHints.min_height = view->height; + sizeHints.max_width = view->width; + sizeHints.max_height = view->height; XSetNormalHints(impl->display, impl->win, &sizeHints); } @@ -141,15 +134,11 @@ puglCreate(PuglNativeWindow parent, XStoreName(impl->display, impl->win, title); } - if (!parent) { + if (!view->parent) { Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True); XSetWMProtocols(impl->display, impl->win, &wmDelete, 1); } - if (visible) { - XMapRaised(impl->display, impl->win); - } - if (glXIsDirect(impl->display, impl->ctx)) { PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n"); } else { @@ -158,7 +147,23 @@ puglCreate(PuglNativeWindow parent, XFree(vi); - return view; + return 0; +} + +PUGL_API void +puglShowWindow(PuglView* view) +{ + PuglInternals* impl = view->impl; + + XMapRaised(impl->display, impl->win); +} + +void +puglHideWindow(PuglView* view) +{ + PuglInternals* impl = view->impl; + + XUnmapWindow(impl->display, impl->win); } void @@ -355,15 +360,16 @@ puglProcessEvents(PuglView* view) } dispatchKey(view, &event, false); break; - case ClientMessage: - if (!strcmp(XGetAtomName(view->impl->display, - event.xclient.message_type), - "WM_PROTOCOLS")) { + case ClientMessage: { + char* type = XGetAtomName(view->impl->display, + event.xclient.message_type); + if (!strcmp(type, "WM_PROTOCOLS")) { if (view->closeFunc) { view->closeFunc(view); } } - break; + XFree(type); + } break; #ifdef PUGL_GRAB_FOCUS case EnterNotify: XSetInputFocus(view->impl->display, diff --git a/pugl_test.c b/pugl_test.c index b9a54f5..9282420 100644 --- a/pugl_test.c +++ b/pugl_test.c @@ -173,7 +173,10 @@ main(int argc, char** argv) } } - PuglView* view = puglCreate(0, "Pugl Test", 512, 512, resizable, true); + PuglView* view = puglInit(NULL, NULL); + puglInitWindowSize(view, 512, 512); + puglInitResizable(view, resizable); + puglIgnoreKeyRepeat(view, ignoreKeyRepeat); puglSetKeyboardFunc(view, onKeyboard); puglSetMotionFunc(view, onMotion); @@ -184,6 +187,9 @@ main(int argc, char** argv) puglSetReshapeFunc(view, onReshape); puglSetCloseFunc(view, onClose); + puglCreateWindow(view, "Pugl Test"); + puglShowWindow(view); + while (!quit) { puglProcessEvents(view); } -- cgit v1.2.3