Browse Source

Update pugl base files and X11 code

pull/83/head
falkTX 6 years ago
parent
commit
72279b8e7c
6 changed files with 300 additions and 290 deletions
  1. +1
    -5
      dgl/src/Window.cpp
  2. +49
    -2
      dgl/src/pugl/pugl.h
  3. +53
    -137
      dgl/src/pugl/pugl_internal.h
  4. +2
    -2
      dgl/src/pugl/pugl_osx.m
  5. +2
    -2
      dgl/src/pugl/pugl_win.cpp
  6. +193
    -142
      dgl/src/pugl/pugl_x11.c

+ 1
- 5
dgl/src/Window.cpp View File

@@ -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)


+ 49
- 2
dgl/src/pugl/pugl.h View File

@@ -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"
@@ -177,6 +178,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).

@@ -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);
@@ -394,6 +423,12 @@ puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);
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.
*/
@@ -404,6 +439,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.
*/
@@ -425,6 +466,12 @@ puglProcessEvents(PuglView* view);
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.
*/


+ 53
- 137
dgl/src/pugl/pugl_internal.h View File

@@ -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)
{
@@ -193,6 +206,12 @@ puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc)
view->reshapeFunc = reshapeFunc;
}

void
puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc)
{
view->resizeFunc = resizeFunc;
}

void
puglSetScrollFunc(PuglView* view, PuglScrollFunc 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
}

+ 2
- 2
dgl/src/pugl/pugl_osx.m View File

@@ -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];
}



+ 2
- 2
dgl/src/pugl/pugl_win.cpp View File

@@ -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;


+ 193
- 142
dgl/src/pugl/pugl_x11.c View File

@@ -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;
}

Loading…
Cancel
Save