|
|
@@ -85,6 +85,7 @@ typedef struct lglw_int_s { |
|
|
|
Window xwnd; |
|
|
|
lglw_bool_t mapped; |
|
|
|
int32_t swap_interval; |
|
|
|
lglw_bool_t b_owner; |
|
|
|
} win; |
|
|
|
|
|
|
|
GLXContext ctx; |
|
|
@@ -351,28 +352,31 @@ static void loc_destroy_hidden_window(lglw_int_t *lglw) { |
|
|
|
|
|
|
|
// Very simple function to test _XEventProc is properly called |
|
|
|
void loc_eventProc(void *xevent) { |
|
|
|
// lglw_log("XEventProc"); |
|
|
|
printf("XEventProc\n"); |
|
|
|
lglw_log("XEventProc\n"); |
|
|
|
printf("vstgltest<lglw_linux>: XEventProc\n"); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef ARCH_X64 |
|
|
|
#if 0 |
|
|
|
// Pulled from the Renoise 64-bit callback example |
|
|
|
// Unsure what data was supposed to be, but swapping it to a function name did not work |
|
|
|
// This does nothing, no event proc found |
|
|
|
// TODO: 32-bit support |
|
|
|
// void loc_setEventProc (Display *display, Window window) { |
|
|
|
// size_t data = (size_t)loc_eventProc; |
|
|
|
// long temp[2]; |
|
|
|
void loc_setEventProc (Display *display, Window window) { |
|
|
|
size_t data = (size_t)loc_eventProc; |
|
|
|
long temp[2]; |
|
|
|
|
|
|
|
// // Split the 64 bit pointer into a little-endian long array |
|
|
|
// temp[0] = (long)(data & 0xffffffffUL); |
|
|
|
// temp[1] = (long)(data >> 32L); |
|
|
|
printf("vstgltest<lglw_linux>: setEventProc (2*32bit). window=%lu loc_eventProc=%p\n", window, &loc_eventProc); |
|
|
|
|
|
|
|
// Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
// XChangeProperty(display, window, atom, atom, 32, |
|
|
|
// PropModeReplace, (unsigned char*)temp, 2); |
|
|
|
// } |
|
|
|
// Split the 64 bit pointer into a little-endian long array |
|
|
|
temp[0] = (long)(data & 0xffffffffUL); |
|
|
|
temp[1] = (long)(data >> 32L); |
|
|
|
|
|
|
|
#ifdef ARCH_X64 |
|
|
|
Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
XChangeProperty(display, window, atom, atom, 32, |
|
|
|
PropModeReplace, (unsigned char*)temp, 2); |
|
|
|
} |
|
|
|
#else |
|
|
|
// GPL code pulled from the amsynth example <https://github.com/amsynth/amsynth/blob/4a87798e650c6d71d70274a961c9b8d98fc6da7e/src/amsynth_vst.cpp> |
|
|
|
// Simply swapped out the function names, crashes Ardour in the same was as the others |
|
|
|
void loc_setEventProc (Display *display, Window window) { |
|
|
@@ -404,6 +408,7 @@ void loc_setEventProc (Display *display, Window window) { |
|
|
|
memcpy(ptr, kJumpInstructions, sizeof(kJumpInstructions)); |
|
|
|
*((uint64_t *)(ptr + kJumpAddress)) = (uint64_t)(&loc_eventProc); |
|
|
|
msync(ptr, sizeof(kJumpInstructions), MS_INVALIDATE); |
|
|
|
printf("vstgltest<lglw_linux>: 64bit trampoline installed\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -411,6 +416,7 @@ void loc_setEventProc (Display *display, Window window) { |
|
|
|
Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 2); |
|
|
|
} |
|
|
|
#endif |
|
|
|
#else |
|
|
|
// Pulled from the eXT2 example |
|
|
|
// TODO: 32-bit support |
|
|
@@ -449,6 +455,7 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x, |
|
|
|
XEvent event; |
|
|
|
XSync(lglw->xdsp, False); |
|
|
|
|
|
|
|
#if 1 |
|
|
|
lglw_log("lglw:lglw_window_open: 5\n"); |
|
|
|
swa.border_pixel = 0; |
|
|
|
swa.colormap = lglw->cmap; |
|
|
@@ -460,23 +467,29 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x, |
|
|
|
lglw_log("lglw:lglw_window_open: 6\n"); |
|
|
|
XSetStandardProperties(lglw->xdsp, lglw->win.xwnd, "LGLW", "LGLW", None, NULL, 0, NULL); |
|
|
|
|
|
|
|
// Setup the event proc now, on the parent window as well just for the debug host |
|
|
|
// It was simpler to do this than check in the debug host for the reparent event |
|
|
|
lglw_log("lglw:lglw_window_open: 7\n"); |
|
|
|
loc_setEventProc(lglw->xdsp, lglw->win.xwnd); |
|
|
|
loc_setEventProc(lglw->xdsp, lglw->parent_xwnd); |
|
|
|
|
|
|
|
// Some hosts only check and store the callback when the Window is reparented |
|
|
|
// Since creating the Window with a Parent may or may not do that, but the callback is not set, |
|
|
|
// ... it's created as a root window, the callback is set, and then it's reparented |
|
|
|
if (0 != _parentHWNDOrNull) |
|
|
|
{ |
|
|
|
lglw_log("lglw:lglw_window_open: 8\n"); |
|
|
|
lglw_log("lglw:lglw_window_open: 7\n"); |
|
|
|
XReparentWindow(lglw->xdsp, lglw->win.xwnd, lglw->parent_xwnd, 0, 0); |
|
|
|
} |
|
|
|
lglw->win.b_owner = LGLW_TRUE; |
|
|
|
#else |
|
|
|
lglw->win.xwnd = (Window)_parentHWNDOrNull; |
|
|
|
lglw->win.b_owner = LGLW_FALSE; |
|
|
|
#endif |
|
|
|
|
|
|
|
// Setup the event proc now, on the parent window as well just for the debug host |
|
|
|
// It was simpler to do this than check in the debug host for the reparent event |
|
|
|
lglw_log("lglw:lglw_window_open: 8\n"); |
|
|
|
loc_setEventProc(lglw->xdsp, lglw->win.xwnd); |
|
|
|
loc_setEventProc(lglw->xdsp, lglw->parent_xwnd); |
|
|
|
|
|
|
|
lglw_log("lglw:lglw_window_open: 9\n"); |
|
|
|
XMapRaised(lglw->xdsp, lglw->win.xwnd); |
|
|
|
if(lglw->win.b_owner) |
|
|
|
XMapRaised(lglw->xdsp, lglw->win.xwnd); |
|
|
|
XSync(lglw->xdsp, False); |
|
|
|
lglw->win.mapped = LGLW_TRUE; |
|
|
|
|
|
|
@@ -572,7 +585,11 @@ void lglw_window_close (lglw_t _lglw) { |
|
|
|
glXMakeCurrent(lglw->xdsp, None, NULL); |
|
|
|
|
|
|
|
lglw_log("lglw:lglw_window_close: 4\n"); |
|
|
|
XDestroyWindow(lglw->xdsp, lglw->win.xwnd); |
|
|
|
if(lglw->win.b_owner) |
|
|
|
{ |
|
|
|
XDestroyWindow(lglw->xdsp, lglw->win.xwnd); |
|
|
|
lglw->win.b_owner = LGLW_FALSE; |
|
|
|
} |
|
|
|
XSync(lglw->xdsp, False); |
|
|
|
lglw->win.xwnd = 0; |
|
|
|
lglw->win.mapped = LGLW_FALSE; |
|
|
|