aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-05-13 15:30:36 +0000
committerDavid Robillard <d@drobilla.net>2014-05-13 15:30:36 +0000
commita739e6116f026e2fe334f447082616712a1cfd78 (patch)
tree8b6b3fb3bcfb9cd41dae872d5789a54fc5a4c3c5
parente86043f765dd18a51cb2450f45d1d204fd4cb4d9 (diff)
Fix non-extensible puglInit API.
Fix memory leak.
-rw-r--r--pugl/pugl.h61
-rw-r--r--pugl/pugl_internal.h48
-rw-r--r--pugl/pugl_win.cpp28
-rw-r--r--pugl/pugl_x11.c72
-rw-r--r--pugl_test.c8
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 <http://drobilla.net>
+ Copyright 2012-2014 David Robillard <http://drobilla.net>
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);
}