|
|
@@ -335,6 +335,93 @@ static void loc_destroy_hidden_window(lglw_int_t *lglw) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------- loc_setEventProc |
|
|
|
// https://www.kvraudio.com/forum/viewtopic.php?t=387924 |
|
|
|
// https://github.com/Ardour/ardour/blob/master/gtk2_ardour/linux_vst_gui_support.cc |
|
|
|
// https://discourse.ardour.org/t/overtonedsp-plugins/90115/22 |
|
|
|
// https://github.com/amsynth/amsynth/blob/4a87798e650c6d71d70274a961c9b8d98fc6da7e/src/amsynth_vst.cpp |
|
|
|
// https://github.com/rsenn/eXT2/blob/7f00a09561ded8175ffed2f4912dad74e466a1c7/vstplugins/vstgui/vstgui.cpp |
|
|
|
// https://github.com/COx2/DistortionFilter/blob/c6a34fb56b503a6e95bf0975e00f438bbf4ff52a/juce/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp |
|
|
|
|
|
|
|
// Very simple function to test _XEventProc is properly called |
|
|
|
void loc_eventProc(void *xevent) { |
|
|
|
// lglw_log("XEventProc"); |
|
|
|
printf("XEventProc\n"); |
|
|
|
} |
|
|
|
|
|
|
|
// 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]; |
|
|
|
|
|
|
|
// // Split the 64 bit pointer into a little-endian long array |
|
|
|
// temp[0] = (long)(data & 0xffffffffUL); |
|
|
|
// temp[1] = (long)(data >> 32L); |
|
|
|
|
|
|
|
// Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
// XChangeProperty(display, window, atom, atom, 32, |
|
|
|
// PropModeReplace, (unsigned char*)temp, 2); |
|
|
|
// } |
|
|
|
|
|
|
|
// Pulled from the eXT2 example |
|
|
|
// TODO: 32-bit support |
|
|
|
void loc_setEventProc (Display *display, Window window) { |
|
|
|
void* data = (void*)&loc_eventProc; // swapped the function name here |
|
|
|
|
|
|
|
Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
XChangeProperty(display, window, atom, atom, 32, |
|
|
|
PropModeReplace, (unsigned char*)&data, 1); // 1 instead of 2 will crash Ardour, 2 will not do anything |
|
|
|
} |
|
|
|
|
|
|
|
// Pulled from the amsynth example |
|
|
|
// Simply swapped out the function names, crashes Ardour in the same was as the others |
|
|
|
// void loc_setEventProc (Display *display, Window window) { |
|
|
|
// #ifdef BUILD_64 |
|
|
|
// // |
|
|
|
// // JUCE calls XGetWindowProperty with long_length = 1 which means it only fetches the lower 32 bits of the address. |
|
|
|
// // Therefore we need to ensure we return an address in the lower 32-bits of address space. |
|
|
|
// // |
|
|
|
|
|
|
|
// // based on mach_override |
|
|
|
// static const unsigned char kJumpInstructions[] = { |
|
|
|
// 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, |
|
|
|
// 0x00, 0x00, 0x00, 0x00, |
|
|
|
// 0x00, 0x00, 0x00, 0x00 |
|
|
|
// }; |
|
|
|
// static const int kJumpAddress = 6; |
|
|
|
|
|
|
|
// static char *ptr; |
|
|
|
// if (!ptr) { |
|
|
|
// ptr = (char *)mmap(0, |
|
|
|
// PAGE_SIZE, |
|
|
|
// PROT_READ | PROT_WRITE | PROT_EXEC, |
|
|
|
// MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, |
|
|
|
// 0, 0); |
|
|
|
// if (ptr == MAP_FAILED) { |
|
|
|
// perror("mmap"); |
|
|
|
// ptr = 0; |
|
|
|
// return; |
|
|
|
// } else { |
|
|
|
// memcpy(ptr, kJumpInstructions, sizeof(kJumpInstructions)); |
|
|
|
// *((uint64_t *)(ptr + kJumpAddress)) = (uint64_t)(&loc_eventProc); |
|
|
|
// msync(ptr, sizeof(kJumpInstructions), MS_INVALIDATE); |
|
|
|
// } |
|
|
|
// } |
|
|
|
|
|
|
|
// long temp[2] = {(long)ptr, 0}; |
|
|
|
// Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
// XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 2); |
|
|
|
// #else |
|
|
|
// long temp[1] = {(long)(void *)(&loc_eventProc)}; |
|
|
|
// Atom atom = XInternAtom(display, "_XEventProc", False); |
|
|
|
// XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 1); |
|
|
|
// #endif |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------- lglw_window_open |
|
|
|
lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x, int32_t _y, int32_t _w, int32_t _h) { |
|
|
|
lglw_bool_t r = LGLW_FALSE; |
|
|
@@ -363,14 +450,29 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x, |
|
|
|
lglw_log("lglw:lglw_window_open: 5\n"); |
|
|
|
swa.border_pixel = 0; |
|
|
|
swa.colormap = lglw->cmap; |
|
|
|
swa.event_mask = EnterWindowMask | LeaveWindowMask; |
|
|
|
lglw->win.xwnd = XCreateWindow(lglw->xdsp, lglw->parent_xwnd, |
|
|
|
swa.event_mask = EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask; |
|
|
|
lglw->win.xwnd = XCreateWindow(lglw->xdsp, DefaultRootWindow(lglw->xdsp), |
|
|
|
0, 0, _w, _h, 0, CopyFromParent, InputOutput, |
|
|
|
lglw->vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); |
|
|
|
|
|
|
|
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"); |
|
|
|
XReparentWindow(lglw->xdsp, lglw->win.xwnd, lglw->parent_xwnd, 0, 0); |
|
|
|
} |
|
|
|
|
|
|
|
lglw_log("lglw:lglw_window_open: 9\n"); |
|
|
|
XMapRaised(lglw->xdsp, lglw->win.xwnd); |
|
|
|
XSync(lglw->xdsp, False); |
|
|
|