@@ -95,7 +95,7 @@ typedef enum { | |||
PUGL_CHAR_ESCAPE = 0x1B, | |||
PUGL_CHAR_DELETE = 0x7F | |||
} PuglChar; | |||
/** | |||
Special (non-Unicode) keyboard keys. | |||
*/ | |||
@@ -131,12 +131,12 @@ typedef enum { | |||
Keyboard modifier flags. | |||
*/ | |||
typedef enum { | |||
PUGL_MOD_SHIFT = 1, /**< Shift key */ | |||
PUGL_MOD_SHIFT = 1, /**< Shift key */ | |||
PUGL_MOD_CTRL = 1 << 1, /**< Control key */ | |||
PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */ | |||
PUGL_MOD_SUPER = 1 << 3 /**< Mod4/Command/Windows key */ | |||
} PuglMod; | |||
/** | |||
Handle for opaque user data. | |||
*/ | |||
@@ -205,7 +205,7 @@ typedef void (*PuglScrollFunc)(PuglView* view, float dx, float dy); | |||
A function called when a special key is pressed or released. | |||
This callback allows the use of keys that do not have unicode points. Note | |||
that some non-printable keys | |||
that some non-printable keys | |||
@param view The view the event occured in. | |||
@param press True if the key was pressed, false if released. | |||
@param key The key pressed. | |||
@@ -219,6 +219,7 @@ typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key); | |||
@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. | |||
*/ | |||
PUGL_API PuglView* | |||
puglCreate(PuglNativeWindow parent, | |||
@@ -226,7 +227,7 @@ puglCreate(PuglNativeWindow parent, | |||
int width, | |||
int height, | |||
bool resizable, | |||
bool addToDesktop); | |||
bool visible); | |||
/** | |||
Set the handle to be passed to all callbacks. | |||
@@ -75,9 +75,9 @@ | |||
void | |||
puglDisplay(PuglView* view) | |||
{ | |||
if (view->displayFunc) { | |||
view->displayFunc(view); | |||
} | |||
if (view->displayFunc) { | |||
view->displayFunc(view); | |||
} | |||
} | |||
@interface PuglOpenGLView : NSOpenGLView | |||
@@ -327,7 +327,7 @@ puglCreate(PuglNativeWindow parent, | |||
int width, | |||
int height, | |||
bool resizable, | |||
bool addToDesktop) | |||
bool visible) | |||
{ | |||
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); | |||
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); | |||
@@ -361,7 +361,7 @@ puglCreate(PuglNativeWindow parent, | |||
[window makeFirstResponder:impl->glview]; | |||
[window makeKeyAndOrderFront:window]; | |||
if (! addToDesktop) { | |||
if (! visible) { | |||
[window setIsVisible:NO]; | |||
} | |||
@@ -55,7 +55,7 @@ puglCreate(PuglNativeWindow parent, | |||
int width, | |||
int height, | |||
bool resizable, | |||
bool addToDesktop) | |||
bool visible) | |||
{ | |||
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); | |||
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); | |||
@@ -92,13 +92,12 @@ puglCreate(PuglNativeWindow parent, | |||
// Adjust the overall window size to accomodate our requested client size | |||
RECT wr = { 0, 0, width, height }; | |||
AdjustWindowRectEx( | |||
&wr, winFlags, FALSE, WS_EX_TOPMOST); | |||
AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST); | |||
impl->hwnd = CreateWindowEx( | |||
WS_EX_TOPMOST, | |||
classNameBuf, title, | |||
(addToDesktop ? WS_VISIBLE : 0) | (parent ? WS_CHILD : winFlags), | |||
(visible ? WS_VISIBLE : 0) | (parent ? WS_CHILD : winFlags), | |||
0, 0, wr.right-wr.left, wr.bottom-wr.top, | |||
(HWND)parent, NULL, NULL, NULL); | |||
@@ -107,7 +106,7 @@ puglCreate(PuglNativeWindow parent, | |||
free(view); | |||
return NULL; | |||
} | |||
SetWindowLongPtr(impl->hwnd, GWL_USERDATA, (LONG)view); | |||
impl->hdc = GetDC(impl->hwnd); | |||
@@ -1,6 +1,7 @@ | |||
/* | |||
Copyright 2012 David Robillard <http://drobilla.net> | |||
Copyright 2011-2012 Ben Loftis, Harrison Consoles | |||
Copyright 2013 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 | |||
@@ -31,6 +32,16 @@ | |||
#include "pugl_internal.h" | |||
/* 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 XKEYFOCUSGRAB | |||
/* show messages during initalization | |||
*/ | |||
//#define VERBOSE_PUGL | |||
struct PuglInternalsImpl { | |||
Display* display; | |||
int screen; | |||
@@ -71,7 +82,7 @@ puglCreate(PuglNativeWindow parent, | |||
int width, | |||
int height, | |||
bool resizable, | |||
bool addToDesktop) | |||
bool visible) | |||
{ | |||
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView)); | |||
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); | |||
@@ -90,15 +101,21 @@ puglCreate(PuglNativeWindow parent, | |||
if (!vi) { | |||
vi = glXChooseVisual(impl->display, impl->screen, attrListSgl); | |||
impl->doubleBuffered = False; | |||
printf("singlebuffered rendering will be used, no doublebuffering available\n"); | |||
#ifdef VERBOSE_PUGL | |||
printf("puGL: singlebuffered rendering will be used, no doublebuffering available\n"); | |||
#endif | |||
} else { | |||
impl->doubleBuffered = True; | |||
printf("doublebuffered rendering available\n"); | |||
#ifdef VERBOSE_PUGL | |||
printf("puGL: doublebuffered rendering available\n"); | |||
#endif | |||
} | |||
int glxMajor, glxMinor; | |||
glXQueryVersion(impl->display, &glxMajor, &glxMinor); | |||
printf("GLX-Version %d.%d\n", glxMajor, glxMinor); | |||
#ifdef VERBOSE_PUGL | |||
printf("puGL: GLX-Version : %d.%d\n", glxMajor, glxMinor); | |||
#endif | |||
impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); | |||
@@ -116,6 +133,9 @@ puglCreate(PuglNativeWindow parent, | |||
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | |||
| ButtonPressMask | ButtonReleaseMask | |||
#ifdef XKEYFOCUSGRAB | |||
| EnterWindowMask | |||
#endif | |||
| PointerMotionMask | StructureNotifyMask; | |||
impl->win = XCreateWindow( | |||
@@ -143,14 +163,18 @@ puglCreate(PuglNativeWindow parent, | |||
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1); | |||
} | |||
if (addToDesktop) { | |||
if (visible) { | |||
XMapRaised(impl->display, impl->win); | |||
} | |||
if (glXIsDirect(impl->display, impl->ctx)) { | |||
printf("DRI enabled\n"); | |||
#ifdef VERBOSE_PUGL | |||
printf("puGL: DRI enabled\n"); | |||
#endif | |||
} else { | |||
printf("No DRI available\n"); | |||
#ifdef VERBOSE_PUGL | |||
printf("puGL: No DRI available\n"); | |||
#endif | |||
} | |||
XFree(vi); | |||
@@ -191,8 +215,10 @@ static void | |||
puglDisplay(PuglView* view) | |||
{ | |||
glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx); | |||
#if 0 | |||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||
glLoadIdentity(); | |||
#endif | |||
if (view->displayFunc) { | |||
view->displayFunc(view); | |||
@@ -342,8 +368,7 @@ puglProcessEvents(PuglView* view) | |||
} | |||
if (!repeated && view->keyboardFunc) { | |||
KeySym sym = XKeycodeToKeysym( | |||
view->impl->display, event.xkey.keycode, 0); | |||
KeySym sym = XLookupKeysym(&event.xkey, 0); | |||
PuglKey special = keySymToSpecial(sym); | |||
if (!special) { | |||
view->keyboardFunc(view, false, sym); | |||
@@ -361,6 +386,11 @@ puglProcessEvents(PuglView* view) | |||
} | |||
} | |||
break; | |||
#ifdef XKEYFOCUSGRAB | |||
case EnterNotify: | |||
XSetInputFocus(view->impl->display, view->impl->win, RevertToPointerRoot, CurrentTime); | |||
break; | |||
#endif | |||
default: | |||
break; | |||
} | |||