|
@@ -65,23 +65,16 @@ static int attrListDbl[] = { |
|
|
None |
|
|
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->display = XOpenDisplay(0); |
|
|
impl->screen = DefaultScreen(impl->display); |
|
|
impl->screen = DefaultScreen(impl->display); |
|
@@ -102,8 +95,8 @@ puglCreate(PuglNativeWindow parent, |
|
|
|
|
|
|
|
|
impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); |
|
|
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); |
|
|
: RootWindow(impl->display, impl->screen); |
|
|
|
|
|
|
|
|
Colormap cmap = XCreateColormap( |
|
|
Colormap cmap = XCreateColormap( |
|
@@ -116,24 +109,24 @@ puglCreate(PuglNativeWindow parent, |
|
|
|
|
|
|
|
|
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
|
|
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
|
|
| ButtonPressMask | ButtonReleaseMask |
|
|
| ButtonPressMask | ButtonReleaseMask |
|
|
#ifdef XKEYFOCUSGRAB |
|
|
|
|
|
|
|
|
#ifdef PUGL_GRAB_FOCUS |
|
|
| EnterWindowMask |
|
|
| EnterWindowMask |
|
|
#endif |
|
|
#endif |
|
|
| PointerMotionMask | StructureNotifyMask; |
|
|
| PointerMotionMask | StructureNotifyMask; |
|
|
|
|
|
|
|
|
impl->win = XCreateWindow( |
|
|
impl->win = XCreateWindow( |
|
|
impl->display, xParent, |
|
|
impl->display, xParent, |
|
|
0, 0, (unsigned int)view->width, (unsigned int)view->height, 0, vi->depth, InputOutput, vi->visual, |
|
|
|
|
|
|
|
|
0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual, |
|
|
CWBorderPixel | CWColormap | CWEventMask, &attr); |
|
|
CWBorderPixel | CWColormap | CWEventMask, &attr); |
|
|
|
|
|
|
|
|
XSizeHints sizeHints; |
|
|
XSizeHints sizeHints; |
|
|
memset(&sizeHints, 0, sizeof(sizeHints)); |
|
|
memset(&sizeHints, 0, sizeof(sizeHints)); |
|
|
if (!resizable) { |
|
|
|
|
|
|
|
|
if (!view->resizable) { |
|
|
sizeHints.flags = PMinSize|PMaxSize; |
|
|
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); |
|
|
XSetNormalHints(impl->display, impl->win, &sizeHints); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -141,15 +134,11 @@ puglCreate(PuglNativeWindow parent, |
|
|
XStoreName(impl->display, impl->win, title); |
|
|
XStoreName(impl->display, impl->win, title); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!parent) { |
|
|
|
|
|
|
|
|
if (!view->parent) { |
|
|
Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True); |
|
|
Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True); |
|
|
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1); |
|
|
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (visible) { |
|
|
|
|
|
XMapRaised(impl->display, impl->win); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (glXIsDirect(impl->display, impl->ctx)) { |
|
|
if (glXIsDirect(impl->display, impl->ctx)) { |
|
|
PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n"); |
|
|
PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n"); |
|
|
} else { |
|
|
} else { |
|
@@ -158,7 +147,23 @@ puglCreate(PuglNativeWindow parent, |
|
|
|
|
|
|
|
|
XFree(vi); |
|
|
XFree(vi); |
|
|
|
|
|
|
|
|
return view; |
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
void |
|
@@ -245,9 +250,9 @@ keySymToSpecial(KeySym sym) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
setModifiers(PuglView* view, unsigned xstate, unsigned long xtime) |
|
|
|
|
|
|
|
|
setModifiers(PuglView* view, unsigned xstate, unsigned xtime) |
|
|
{ |
|
|
{ |
|
|
view->event_timestamp_ms = (uint32_t)xtime; |
|
|
|
|
|
|
|
|
view->event_timestamp_ms = xtime; |
|
|
|
|
|
|
|
|
view->mods = 0; |
|
|
view->mods = 0; |
|
|
view->mods |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0; |
|
|
view->mods |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0; |
|
@@ -273,7 +278,7 @@ dispatchKey(PuglView* view, XEvent* event, bool press) |
|
|
if (special && view->specialFunc) { |
|
|
if (special && view->specialFunc) { |
|
|
view->specialFunc(view, press, special); |
|
|
view->specialFunc(view, press, special); |
|
|
} else if (!special && view->keyboardFunc) { |
|
|
} else if (!special && view->keyboardFunc) { |
|
|
view->keyboardFunc(view, press, (uint32_t)str[0]); |
|
|
|
|
|
|
|
|
view->keyboardFunc(view, press, str[0]); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -330,7 +335,7 @@ puglProcessEvents(PuglView* view) |
|
|
if (view->mouseFunc && |
|
|
if (view->mouseFunc && |
|
|
(event.xbutton.button < 4 || event.xbutton.button > 7)) { |
|
|
(event.xbutton.button < 4 || event.xbutton.button > 7)) { |
|
|
view->mouseFunc(view, |
|
|
view->mouseFunc(view, |
|
|
(int)event.xbutton.button, event.type == ButtonPress, |
|
|
|
|
|
|
|
|
event.xbutton.button, event.type == ButtonPress, |
|
|
event.xbutton.x, event.xbutton.y); |
|
|
event.xbutton.x, event.xbutton.y); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
@@ -354,15 +359,16 @@ puglProcessEvents(PuglView* view) |
|
|
dispatchKey(view, &event, false); |
|
|
dispatchKey(view, &event, false); |
|
|
break; |
|
|
break; |
|
|
case ClientMessage: { |
|
|
case ClientMessage: { |
|
|
char* name = XGetAtomName(view->impl->display, event.xclient.message_type); |
|
|
|
|
|
if (!strcmp(name, "WM_PROTOCOLS")) { |
|
|
|
|
|
|
|
|
char* type = XGetAtomName(view->impl->display, |
|
|
|
|
|
event.xclient.message_type); |
|
|
|
|
|
if (!strcmp(type, "WM_PROTOCOLS")) { |
|
|
if (view->closeFunc) { |
|
|
if (view->closeFunc) { |
|
|
view->closeFunc(view); |
|
|
view->closeFunc(view); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
XFree(name); |
|
|
|
|
|
} break; |
|
|
|
|
|
#ifdef XKEYFOCUSGRAB |
|
|
|
|
|
|
|
|
XFree(type); |
|
|
|
|
|
} break; |
|
|
|
|
|
#ifdef PUGL_GRAB_FOCUS |
|
|
case EnterNotify: |
|
|
case EnterNotify: |
|
|
XSetInputFocus(view->impl->display, |
|
|
XSetInputFocus(view->impl->display, |
|
|
view->impl->win, |
|
|
view->impl->win, |
|
@@ -391,5 +397,5 @@ puglPostRedisplay(PuglView* view) |
|
|
PuglNativeWindow |
|
|
PuglNativeWindow |
|
|
puglGetNativeWindow(PuglView* view) |
|
|
puglGetNativeWindow(PuglView* view) |
|
|
{ |
|
|
{ |
|
|
return (PuglNativeWindow)view->impl->win; |
|
|
|
|
|
|
|
|
return view->impl->win; |
|
|
} |
|
|
} |