summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfalkTX <falktx@gmail.com>2018-09-30 01:20:29 +0200
committerfalkTX <falktx@gmail.com>2018-09-30 01:20:29 +0200
commit72279b8e7c8d1a80132e42bcbc9761c3c8911190 (patch)
tree4b272f0c85e2297fead0f46afafafed7f2d5acd9
parentd2c6e7df2aec48d05cbb1289d803309c785cff69 (diff)
Update pugl base files and X11 code
-rw-r--r--dgl/src/Window.cpp6
-rw-r--r--dgl/src/pugl/pugl.h51
-rw-r--r--dgl/src/pugl/pugl_internal.h190
-rw-r--r--dgl/src/pugl/pugl_osx.m4
-rw-r--r--dgl/src/pugl/pugl_win.cpp4
-rw-r--r--dgl/src/pugl/pugl_x11.c335
6 files changed, 300 insertions, 290 deletions
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
index f809777b..6a221690 100644
--- a/dgl/src/Window.cpp
+++ b/dgl/src/Window.cpp
@@ -19,10 +19,6 @@
#include "../Base.hpp"
-#undef PUGL_HAVE_CAIRO
-#undef PUGL_HAVE_GL
-#define PUGL_HAVE_GL 1
-
#include "pugl/pugl.h"
#if defined(__GNUC__) && (__GNUC__ >= 7)
@@ -619,7 +615,7 @@ struct Window::PrivateData {
sizeHints.max_width = static_cast<int>(width);
sizeHints.max_height = static_cast<int>(height);
- XSetNormalHints(xDisplay, xWindow, &sizeHints);
+ XSetWMNormalHints(xDisplay, xWindow, &sizeHints);
}
if (! forced)
diff --git a/dgl/src/pugl/pugl.h b/dgl/src/pugl/pugl.h
index 09846463..32a10a2b 100644
--- a/dgl/src/pugl/pugl.h
+++ b/dgl/src/pugl/pugl.h
@@ -32,6 +32,7 @@
# include "OpenGL/gl.h"
#else
# ifdef _WIN32
+# include <winsock2.h>
# include <windows.h> /* Broken Windows GL headers require this */
# endif
# include "GL/gl.h"
@@ -178,6 +179,16 @@ typedef void (*PuglMouseFunc)(
typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height);
/**
+ A function called outside of gl-context when the plugin schedules a resize via puglPostResize.
+
+ @param view The view being resized.
+ @param width The new width to resize to (variable is initialized to current size)
+ @param height The new height to resize to (variable is initialized to current size)
+ @param set_hints If not null, set window-hints
+ */
+typedef void (*PuglResizeFunc)(PuglView* view, int *width, int *height, int *set_hints);
+
+/**
A function called on scrolling (e.g. mouse wheel or track pad).
The distances used here are in "lines", a single tick of a clicking mouse
@@ -281,13 +292,31 @@ PUGL_API int
puglCreateWindow(PuglView* view, const char* title);
/**
- Show the current window.
+ 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.
+*/
+PUGL_API PuglView*
+puglCreate(PuglNativeWindow parent,
+ const char* title,
+ int min_width,
+ int min_height,
+ int width,
+ int height,
+ bool resizable,
+ unsigned long transientId);
+
+/**
+ Show Window (external ui)
*/
PUGL_API void
puglShowWindow(PuglView* view);
/**
- Hide the current window.
+ Hide Window (external ui)
*/
PUGL_API void
puglHideWindow(PuglView* view);
@@ -395,6 +424,12 @@ PUGL_API void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
/**
+ Set callback function to change window size.
+*/
+PUGL_API void
+puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc);
+
+/**
Set the function to call on file-browser selections.
*/
PUGL_API void
@@ -405,6 +440,12 @@ puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
*/
/**
+ TODO document this.
+ */
+PUGL_API int
+puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect);
+
+/**
Grab the input focus.
*/
PUGL_API void
@@ -426,6 +467,12 @@ PUGL_API void
puglPostRedisplay(PuglView* view);
/**
+ Request a resize on the next call to puglProcessEvents().
+*/
+PUGL_API void
+puglPostResize(PuglView* view);
+
+/**
Destroy a GL window.
*/
PUGL_API void
diff --git a/dgl/src/pugl/pugl_internal.h b/dgl/src/pugl/pugl_internal.h
index c84d77bd..fa52df40 100644
--- a/dgl/src/pugl/pugl_internal.h
+++ b/dgl/src/pugl/pugl_internal.h
@@ -20,26 +20,9 @@
Note this file contains function definitions, so it must be compiled into
the final binary exactly once. Each platform specific implementation file
including it once should achieve this.
-
- If you are copying the pugl code into your source tree, the following
- symbols can be defined to tweak pugl behaviour:
-
- PUGL_HAVE_CAIRO: Include Cairo support code.
- PUGL_HAVE_GL: Include OpenGL support code.
- PUGL_GRAB_FOCUS: Work around reparent keyboard issues by grabbing focus.
- PUGL_VERBOSE: Print GL information to console.
*/
-#include "pugl/pugl.h"
-
-#ifdef PUGL_VERBOSE
-# include <stdio.h>
-# define PUGL_LOG(str) fprintf(stderr, "pugl: " str)
-# define PUGL_LOGF(fmt, ...) fprintf(stderr, "pugl: " fmt, __VA_ARGS__)
-#else
-# define PUGL_LOG(str)
-# define PUGL_LOGF(fmt, ...)
-#endif
+#include "pugl.h"
typedef struct PuglInternalsImpl PuglInternals;
@@ -51,12 +34,12 @@ struct PuglViewImpl {
PuglMotionFunc motionFunc;
PuglMouseFunc mouseFunc;
PuglReshapeFunc reshapeFunc;
+ PuglResizeFunc resizeFunc;
PuglScrollFunc scrollFunc;
PuglSpecialFunc specialFunc;
PuglFileSelectedFunc fileSelectedFunc;
- PuglInternals* impl;
-
+ PuglInternals* impl;
PuglNativeWindow parent;
uintptr_t transient_parent;
@@ -68,7 +51,8 @@ struct PuglViewImpl {
bool mouse_in_view;
bool ignoreKeyRepeat;
bool redisplay;
- bool resizable;
+ bool user_resizable;
+ bool pending_resize;
uint32_t event_timestamp_ms;
};
@@ -118,7 +102,7 @@ puglInitWindowParent(PuglView* view, PuglNativeWindow parent)
void
puglInitUserResizable(PuglView* view, bool resizable)
{
- view->resizable = resizable;
+ view->user_resizable = resizable;
}
void
@@ -127,6 +111,35 @@ puglInitTransientFor(PuglView* view, uintptr_t parent)
view->transient_parent = parent;
}
+PuglView*
+puglCreate(PuglNativeWindow parent,
+ const char* title,
+ int min_width,
+ int min_height,
+ int width,
+ int height,
+ bool resizable,
+ unsigned long transientId)
+{
+ PuglView* view = puglInit();
+ if (!view) {
+ return NULL;
+ }
+
+ puglInitWindowParent(view, parent);
+ puglInitWindowMinSize(view, min_width, min_height);
+ puglInitWindowSize(view, width, height);
+ puglInitUserResizable(view, resizable);
+ puglInitTransientFor(view, transientId);
+
+ if (!puglCreateWindow(view, title)) {
+ free(view);
+ return NULL;
+ }
+
+ return view;
+}
+
void
puglSetHandle(PuglView* view, PuglHandle handle)
{
@@ -194,6 +207,12 @@ puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc)
}
void
+puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc)
+{
+ view->resizeFunc = resizeFunc;
+}
+
+void
puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc)
{
view->scrollFunc = scrollFunc;
@@ -217,45 +236,19 @@ puglEnterContext(PuglView* view);
void
puglLeaveContext(PuglView* view, bool flush);
-#if 0
-/** Return the code point for buf, or the replacement character on error. */
-static uint32_t
-puglDecodeUTF8(const uint8_t* buf)
-{
-#define FAIL_IF(cond) { if (cond) return 0xFFFD; }
-
- /* 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] & 0xC0) != 0x80);
- return (buf[0] << 6) + buf[1] - 0x3080;
- } else if (buf[0] < 0xF0) {
- FAIL_IF((buf[1] & 0xC0) != 0x80);
- FAIL_IF(buf[0] == 0xE0 && buf[1] < 0xA0);
- FAIL_IF((buf[2] & 0xC0) != 0x80);
- return (buf[0] << 12) + (buf[1] << 6) + buf[2] - 0xE2080;
- } else if (buf[0] < 0xF5) {
- FAIL_IF((buf[1] & 0xC0) != 0x80);
- FAIL_IF(buf[0] == 0xF0 && buf[1] < 0x90);
- FAIL_IF(buf[0] == 0xF4 && buf[1] >= 0x90);
- FAIL_IF((buf[2] & 0xC0) != 0x80);
- FAIL_IF((buf[3] & 0xC0) != 0x80);
- return ((buf[0] << 18) +
- (buf[1] << 12) +
- (buf[2] << 6) +
- buf[3] - 0x3C82080);
- }
- return 0xFFFD;
-}
-#endif
-
static void
-puglDefaultReshape(PuglView* view, int width, int height)
+puglDefaultReshape(int width, int height)
{
+#ifdef ROBTK_HERE
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+#else
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
@@ -263,82 +256,5 @@ puglDefaultReshape(PuglView* view, int width, int height)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- return;
-
- // unused
- (void)view;
-}
-
-#if 0
-static void
-puglDispatchEvent(PuglView* view, const PuglEvent* event)
-{
- if (view->eventFunc) {
- view->eventFunc(view, event);
- }
-
- switch (event->type) {
- case PUGL_CONFIGURE:
- puglEnterContext(view);
- view->width = event->configure.width;
- view->height = event->configure.height;
- if (view->reshapeFunc) {
- view->reshapeFunc(view, view->width, view->height);
- }
- puglLeaveContext(view, false);
- break;
- case PUGL_EXPOSE:
- if (event->expose.count == 0) {
- puglEnterContext(view);
- if (view->displayFunc) {
- view->displayFunc(view);
- }
- view->redisplay = false;
- puglLeaveContext(view, true);
- }
- break;
- case PUGL_MOTION_NOTIFY:
- view->event_timestamp_ms = event->motion.time;
- view->mods = event->motion.state;
- if (view->motionFunc) {
- view->motionFunc(view, event->motion.x, event->motion.y);
- }
- break;
- case PUGL_SCROLL:
- if (view->scrollFunc) {
- view->scrollFunc(view,
- event->scroll.x, event->scroll.y,
- event->scroll.dx, event->scroll.dy);
- }
- break;
- case PUGL_BUTTON_PRESS:
- case PUGL_BUTTON_RELEASE:
- view->event_timestamp_ms = event->button.time;
- view->mods = event->button.state;
- if (view->mouseFunc) {
- view->mouseFunc(view,
- event->button.button,
- event->type == PUGL_BUTTON_PRESS,
- event->button.x,
- event->button.y);
- }
- break;
- case PUGL_KEY_PRESS:
- case PUGL_KEY_RELEASE:
- view->event_timestamp_ms = event->key.time;
- view->mods = event->key.state;
- if (event->key.special && view->specialFunc) {
- view->specialFunc(view,
- event->type == PUGL_KEY_PRESS,
- event->key.special);
- } else if (event->key.character && view->keyboardFunc) {
- view->keyboardFunc(view,
- event->type == PUGL_KEY_PRESS,
- event->key.character);
- }
- break;
- default:
- break;
- }
-}
#endif
+}
diff --git a/dgl/src/pugl/pugl_osx.m b/dgl/src/pugl/pugl_osx.m
index 82d68a0d..f9570333 100644
--- a/dgl/src/pugl/pugl_osx.m
+++ b/dgl/src/pugl/pugl_osx.m
@@ -218,7 +218,7 @@ puglDisplay(PuglView* view)
if (puglview->reshapeFunc) {
puglview->reshapeFunc(puglview, width, height);
} else {
- puglDefaultReshape(puglview, width, height);
+ puglDefaultReshape(width, height);
}
puglLeaveContext(puglview, false);
@@ -459,7 +459,7 @@ puglCreateWindow(PuglView* view, const char* title)
impl->glview->puglview = view;
- if (view->resizable) {
+ if (view->user_resizable) {
[impl->glview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
}
diff --git a/dgl/src/pugl/pugl_win.cpp b/dgl/src/pugl/pugl_win.cpp
index cc0cf9bb..5d0cd876 100644
--- a/dgl/src/pugl/pugl_win.cpp
+++ b/dgl/src/pugl/pugl_win.cpp
@@ -129,7 +129,7 @@ puglCreateWindow(PuglView* view, const char* title)
}
int winFlags = WS_POPUPWINDOW | WS_CAPTION;
- if (view->resizable) {
+ if (view->user_resizable) {
winFlags |= WS_SIZEBOX;
if (view->min_width > 0 && view->min_height > 0) {
// Adjust the minimum window size to accomodate requested view size
@@ -223,7 +223,7 @@ puglReshape(PuglView* view, int width, int height)
if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
} else {
- puglDefaultReshape(view, width, height);
+ puglDefaultReshape(width, height);
}
view->width = width;
diff --git a/dgl/src/pugl/pugl_x11.c b/dgl/src/pugl/pugl_x11.c
index d8b091bf..3f98a33e 100644
--- a/dgl/src/pugl/pugl_x11.c
+++ b/dgl/src/pugl/pugl_x11.c
@@ -1,7 +1,7 @@
/*
Copyright 2012-2014 David Robillard <http://drobilla.net>
- Copyright 2013 Robin Gareus <robin@gareus.org>
Copyright 2011-2012 Ben Loftis, Harrison Consoles
+ Copyright 2013,2015 Robin Gareus <robin@gareus.org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -24,15 +24,14 @@
#include <stdlib.h>
#include <string.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
-#include <GL/gl.h>
-#include <GL/glx.h>
-
-#include "pugl/pugl_internal.h"
+#include "pugl_internal.h"
#ifndef DGL_FILE_BROWSER_DISABLED
#define SOFD_HAVE_X11
@@ -40,108 +39,74 @@
#include "../sofd/libsofd.c"
#endif
+/* work around buggy re-parent & focus issues on some systems
+ * where no keyboard events are passed through even if the
+ * app has mouse-focus and all other events are working.
+ */
+//#define PUGL_GRAB_FOCUS
+
+/* show messages during initalization
+ */
+//#define PUGL_VERBOSE
+
struct PuglInternalsImpl {
Display* display;
int screen;
Window win;
- XIM xim;
- XIC xic;
GLXContext ctx;
Bool doubleBuffered;
};
-PuglInternals*
-puglInitInternals(void)
-{
- return (PuglInternals*)calloc(1, sizeof(PuglInternals));
-}
-
-static XVisualInfo*
-getVisual(PuglView* view)
-{
- PuglInternals* const impl = view->impl;
- XVisualInfo* vi = NULL;
-
- /**
- Attributes for single-buffered RGBA with at least
- 4 bits per color and a 16 bit depth buffer.
- */
- int attrListSgl[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- GLX_DEPTH_SIZE, 16,
- GLX_ARB_multisample, 1,
- None
- };
-
- /**
- Attributes for double-buffered RGBA with at least
- 4 bits per color and a 16 bit depth buffer.
- */
- int attrListDbl[] = {
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- GLX_DEPTH_SIZE, 16,
- GLX_ARB_multisample, 1,
- None
- };
-
- /**
- Attributes for double-buffered RGBA with multi-sampling
- (antialiasing)
- */
- int attrListDblMS[] = {
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- GLX_ALPHA_SIZE, 4,
- GLX_DEPTH_SIZE, 16,
- GLX_SAMPLE_BUFFERS, 1,
- GLX_SAMPLES, 4,
- None
- };
-
- impl->doubleBuffered = True;
-
- vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS);
-
- if (vi == NULL) {
- vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
- PUGL_LOG("multisampling (antialiasing) is not available\n");
- }
-
- if (vi == NULL) {
- vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
- impl->doubleBuffered = False;
- PUGL_LOG("singlebuffered rendering will be used, no doublebuffering available\n");
- }
-
- return vi;
-}
+/**
+ Attributes for single-buffered RGBA with at least
+ 4 bits per color and a 16 bit depth buffer.
+*/
+static int attrListSgl[] = {
+ GLX_RGBA,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ GLX_ARB_multisample, 1,
+ None
+};
-static bool
-createContext(PuglView* view, XVisualInfo* vi)
-{
- PuglInternals* const impl = view->impl;
+/**
+ Attributes for double-buffered RGBA with at least
+ 4 bits per color and a 16 bit depth buffer.
+*/
+static int attrListDbl[] = {
+ GLX_RGBA,
+ GLX_DOUBLEBUFFER, True,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ GLX_ARB_multisample, 1,
+ None
+};
- impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
- return (impl->ctx != NULL);
-}
+/**
+ Attributes for double-buffered RGBA with multi-sampling
+ (antialiasing)
+*/
+static int attrListDblMS[] = {
+ GLX_RGBA,
+ GLX_DOUBLEBUFFER, True,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ GLX_ALPHA_SIZE, 4,
+ GLX_DEPTH_SIZE, 16,
+ GLX_SAMPLE_BUFFERS, 1,
+ GLX_SAMPLES, 4,
+ None
+};
-static void
-destroyContext(PuglView* view)
+PuglInternals*
+puglInitInternals(void)
{
- PuglInternals* const impl = view->impl;
-
- glXDestroyContext(impl->display, impl->ctx);
- impl->ctx = NULL;
+ return (PuglInternals*)calloc(1, sizeof(PuglInternals));
}
void
@@ -165,21 +130,53 @@ puglLeaveContext(PuglView* view, bool flush)
int
puglCreateWindow(PuglView* view, const char* title)
{
- PuglInternals* const impl = view->impl;
+ PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
+ if (!impl) {
+ return 1;
+ }
+ view->impl = impl;
impl->display = XOpenDisplay(NULL);
- impl->screen = DefaultScreen(impl->display);
+ if (!impl->display) {
+ free(impl);
+ return 1;
+ }
+ impl->screen = DefaultScreen(impl->display);
+ impl->doubleBuffered = True;
+
+ XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS);
+
+ if (!vi) {
+ vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
+#ifdef PUGL_VERBOSE
+ printf("puGL: multisampling (antialiasing) is not available\n");
+#endif
+ }
+
+ if (!vi) {
+ vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
+ impl->doubleBuffered = False;
+ }
- XVisualInfo* const vi = getVisual(view);
if (!vi) {
XCloseDisplay(impl->display);
- impl->display = NULL;
+ free(impl);
return 1;
}
+#ifdef PUGL_VERBOSE
int glxMajor, glxMinor;
glXQueryVersion(impl->display, &glxMajor, &glxMinor);
- PUGL_LOGF("GLX Version %d.%d\n", glxMajor, glxMinor);
+ printf("puGL: GLX-Version : %d.%d\n", glxMajor, glxMinor);
+#endif
+
+ impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);
+
+ if (!impl->ctx) {
+ XCloseDisplay(impl->display);
+ free(impl);
+ return 1;
+ }
Window xParent = view->parent
? (Window)view->parent
@@ -204,62 +201,40 @@ puglCreateWindow(PuglView* view, const char* title)
0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual,
CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &attr);
- if (!createContext(view, vi)) {
- XDestroyWindow(impl->display, impl->win);
- impl->win = 0;
-
+ if (!impl->win) {
XCloseDisplay(impl->display);
- impl->display = NULL;
-
+ free(impl);
return 1;
}
- XSizeHints sizeHints;
- memset(&sizeHints, 0, sizeof(sizeHints));
- if (!view->resizable) {
- sizeHints.flags = PMinSize|PMaxSize;
- 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);
- } else if (view->min_width > 0 && view->min_height > 0) {
- sizeHints.flags = PMinSize;
- sizeHints.min_width = view->min_width;
- sizeHints.min_height = view->min_height;
- XSetNormalHints(impl->display, impl->win, &sizeHints);
- }
+ puglUpdateGeometryConstraints(view, view->min_width, view->min_height, view->min_width != view->width);
+ XResizeWindow(view->impl->display, view->impl->win, view->width, view->height);
if (title) {
XStoreName(impl->display, impl->win, title);
}
- if (!view->parent) {
+ if (view->transient_parent > 0) {
+ XSetTransientForHint(impl->display, impl->win, (Window)view->transient_parent);
+ }
+
+ if (view->parent) {
+ XMapRaised(impl->display, impl->win);
+ } else {
Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1);
}
+#ifdef PUGL_VERBOSE
if (glXIsDirect(impl->display, impl->ctx)) {
- PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n");
+ printf("puGL: DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n");
} else {
- PUGL_LOG("No DRI available\n");
+ printf("puGL: No DRI available\n");
}
+#endif
XFree(vi);
-
- return PUGL_SUCCESS;
-}
-
-void
-puglShowWindow(PuglView* view)
-{
- XMapRaised(view->impl->display, view->impl->win);
-}
-
-void
-puglHideWindow(PuglView* view)
-{
- XUnmapWindow(view->impl->display, view->impl->win);
+ return 0;
}
void
@@ -268,18 +243,29 @@ puglDestroy(PuglView* view)
if (!view) {
return;
}
-
#ifndef DGL_FILE_BROWSER_DISABLED
x_fib_close(view->impl->display);
#endif
- destroyContext(view);
+ glXDestroyContext(view->impl->display, view->impl->ctx);
XDestroyWindow(view->impl->display, view->impl->win);
XCloseDisplay(view->impl->display);
free(view->impl);
free(view);
}
+void
+puglShowWindow(PuglView* view)
+{
+ XMapRaised(view->impl->display, view->impl->win);
+}
+
+void
+puglHideWindow(PuglView* view)
+{
+ XUnmapWindow(view->impl->display, view->impl->win);
+}
+
static void
puglReshape(PuglView* view, int width, int height)
{
@@ -288,7 +274,7 @@ puglReshape(PuglView* view, int width, int height)
if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
} else {
- puglDefaultReshape(view, width, height);
+ puglDefaultReshape(width, height);
}
puglLeaveContext(view, false);
@@ -303,7 +289,6 @@ puglDisplay(PuglView* view)
puglEnterContext(view);
view->redisplay = false;
-
if (view->displayFunc) {
view->displayFunc(view);
}
@@ -311,6 +296,36 @@ puglDisplay(PuglView* view)
puglLeaveContext(view, true);
}
+static void
+puglResize(PuglView* view)
+{
+ int set_hints = 1;
+ view->pending_resize = false;
+ if (!view->resizeFunc) { return; }
+ /* ask the plugin about the new size */
+ view->resizeFunc(view, &view->width, &view->height, &set_hints);
+
+ if (set_hints) {
+ XSizeHints sizeHints;
+ memset(&sizeHints, 0, sizeof(sizeHints));
+ sizeHints.flags = PMinSize|PMaxSize;
+ sizeHints.min_width = view->width;
+ sizeHints.min_height = view->height;
+ sizeHints.max_width = view->user_resizable ? 4096 : view->width;
+ sizeHints.max_height = view->user_resizable ? 4096 : view->height;
+ XSetWMNormalHints(view->impl->display, view->impl->win, &sizeHints);
+ }
+ XResizeWindow(view->impl->display, view->impl->win, view->width, view->height);
+ XFlush(view->impl->display);
+
+#ifdef PUGL_VERBOSE
+ printf("puGL: window resize (%dx%d)\n", view->width, view->height);
+#endif
+
+ /* and call Reshape in glX context */
+ puglReshape(view, view->width, view->height);
+}
+
static PuglKey
keySymToSpecial(KeySym sym)
{
@@ -439,6 +454,11 @@ puglProcessEvents(PuglView* view)
}
switch (event.type) {
+ case UnmapNotify:
+ if (view->motionFunc) {
+ view->motionFunc(view, -1, -1);
+ }
+ break;
case MapNotify:
puglReshape(view, view->width, view->height);
break;
@@ -530,6 +550,10 @@ puglProcessEvents(PuglView* view)
}
}
+ if (view->pending_resize) {
+ puglResize(view);
+ }
+
if (view->redisplay) {
puglDisplay(view);
}
@@ -543,8 +567,35 @@ puglPostRedisplay(PuglView* view)
view->redisplay = true;
}
+void
+puglPostResize(PuglView* view)
+{
+ view->pending_resize = true;
+}
+
PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
return view->impl->win;
}
+
+int
+puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect)
+{
+ XSizeHints sizeHints;
+ memset(&sizeHints, 0, sizeof(sizeHints));
+ sizeHints.flags = PMinSize|PMaxSize;
+ sizeHints.min_width = min_width;
+ sizeHints.min_height = min_height;
+ sizeHints.max_width = view->user_resizable ? 4096 : min_width;
+ sizeHints.max_height = view->user_resizable ? 4096 : min_height;
+ if (aspect) {
+ sizeHints.flags |= PAspect;
+ sizeHints.min_aspect.x = min_width;
+ sizeHints.min_aspect.y = min_height;
+ sizeHints.max_aspect.x = min_width;
+ sizeHints.max_aspect.y = min_height;
+ }
+ XSetWMNormalHints(view->impl->display, view->impl->win, &sizeHints);
+ return 0;
+}