Browse Source

Add WIP _XEventProc code

pull/1639/head
Cameron Leger 6 years ago
parent
commit
0634fe6b2b
1 changed files with 104 additions and 2 deletions
  1. +104
    -2
      dep/lglw/lglw_linux.c

+ 104
- 2
dep/lglw/lglw_linux.c View File

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


Loading…
Cancel
Save