Browse Source

add "_lglw" instance property; implement basic X11 event dispatcher; implement lglw_redraw(); fix warnings

pull/1639/head
bsp2 6 years ago
parent
commit
f2032646b0
1 changed files with 218 additions and 21 deletions
  1. +218
    -21
      dep/lglw/lglw_linux.c

+ 218
- 21
dep/lglw/lglw_linux.c View File

@@ -161,6 +161,11 @@ static void loc_touchinput_update (lglw_int_t *lglw);

static void loc_enable_dropfiles (lglw_int_t *lglw, lglw_bool_t _bEnable);

static void loc_eventProc (void *_xevent);
static void loc_setProperty (Display *_display, Window _window, const char *_name, void *_value);
static void *loc_getProperty (Display *_display, Window _window, const char *_name);
static void loc_setEventProc (Display *display, Window window);


// ---------------------------------------------------------------------------- module vars
static lglw_int_t *khook_lglw = NULL; // currently key-hooked lglw instance (one at a time)
@@ -173,6 +178,7 @@ static FILE *logfile;
void lglw_log(const char *logData, ...) {
fprintf(logfile, logData);
fflush(logfile);
printf(logData);
}


@@ -190,6 +196,8 @@ static int xerror_handler(Display *display, XErrorEvent *error) {
lglw_t lglw_init(int32_t _w, int32_t _h) {
lglw_int_t *lglw = malloc(sizeof(lglw_int_t));

printf("xxx lglw_init: sizeof(uint32_t)=%u sizeof(long)=%u sizeof(void*)=%u\n", sizeof(uint32_t), sizeof(long), sizeof(void*));

// TODO: remove/improve
logfile = fopen("/tmp/lglw_log.txt", "w");
XSetErrorHandler(xerror_handler);
@@ -351,9 +359,153 @@ static void loc_destroy_hidden_window(lglw_int_t *lglw) {
// 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) {
static void loc_eventProc(void *_xevent) {
XEvent *xev = (XEvent*)_xevent;

lglw_log("XEventProc\n");
printf("vstgltest<lglw_linux>: XEventProc\n");
printf("vstgltest<lglw_linux>: XEventProc, xev=%p\n", xev);

if(NULL != xev)
{
LGLW(loc_getProperty(xev->xany.display, xev->xany.window, "_lglw")); // get instance pointer

printf("vstgltest<lglw_linux>: XEventProc, type=%d serial=%lu send_event=%d lglw=%p\n", xev->xany.type, xev->xany.serial, xev->xany.send_event, lglw);

if(NULL != lglw)
{
switch(xev->type)
{
default:
printf("vstgltest<lglw_linux>: unhandled X11 event type=%d\n", xev->type);
break;

case Expose:
printf("vstgltest<lglw_linux>: xev Expose\n");
if(NULL != lglw->redraw.cbk)
{
lglw->redraw.cbk(lglw);
}
break;

case MotionNotify:
printf("vstgltest<lglw_linux>: xev MotionNotify\n");
break;

case KeyPress:
printf("vstgltest<lglw_linux>: xev KeyPress\n");
lglw_redraw(lglw);
break;

case KeyRelease:
printf("vstgltest<lglw_linux>: xev KeyRelease\n");
break;
}
}
}
}

static void loc_setProperty(Display *_display, Window _window, const char *_name, void *_value) {
size_t data = (size_t)_value;
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("xxx lglw_linux:loc_setProperty: name=\"%s\" value=%p temp[0]=%08x temp[1]=%08x\n", _name, _value, temp[0], temp[1]);

Atom atom = XInternAtom(_display, _name, False/*only_if_exists*/);

// (note) what's quite weird here is that we're writing an array of 32bit values, yet the element format must be 64bit (long)
XChangeProperty(_display, _window,
atom/*property*/,
atom/*type*/,
32/*format*/,
PropModeReplace/*mode*/,
(unsigned char*)temp/*data*/,
2/*nelements*/
);
}

static void *loc_getProperty(Display *_display, Window _window, const char *_name) {
int userSize;
unsigned long bytes;
unsigned long userCount;
unsigned char *data;
Atom userType;
Atom atom = XInternAtom(_display, _name, False);

// (note) 64bit properties need to be read with two XGetWindowProperty() calls.
// When using just one call and setting the 'length' to 2, the upper 32bit (second array element) will be 0xFFFFffff.
XGetWindowProperty(_display,
_window,
atom,
0/*offset*/,
1/*length*/,
False/*delete*/,
AnyPropertyType,
&userType/*actual_type_return*/,
&userSize/*actual_format_return*/,
&userCount/*nitems_return*/,
&bytes/*bytes_after_return / partial reads*/,
&data);

union {
uint32_t ui[2];
void *any;
} uptr;
uptr.any = 0;

printf("xxx lglw_linux: loc_getProperty: LOWER userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data);

if(NULL != data)
{
if(userCount >= 1)
{
if(userCount >= 2)
{
printf("xxx loc_getProperty: lo=0x%08x hi=0x%08x\n", ((uint32_t*)data)[0], ((uint32_t*)data)[1]);
}

// lower 32-bit
uptr.ui[0] = *(long*)data;
uptr.ui[1] = 0;

printf("xxx lower=0x%08x\n", uptr.ui[0]);
// // printf("xxx upper=0x%08x\n", uptr.ui[1]);

XFree(data);

// // if(userCount >= 2)
{
XGetWindowProperty(_display,
_window,
atom,
1/*offset*/,
1/*length*/,
False/*delete*/,
AnyPropertyType,
&userType/*actual_type_return*/,
&userSize/*actual_format_return*/,
&userCount/*nitems_return*/,
&bytes/*bytes_after_return / partial reads*/,
&data);

printf("xxx lglw_linux: loc_getProperty: UPPER userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data);
if(NULL != data)
{
// upper 32-bit
uptr.ui[1] = *(long*)data;
printf("xxx upper=0x%08x\n", uptr.ui[1]);
XFree(data);
}
}
}
}

printf("xxx lglw_linux: loc_getProperty: return value=%p\n", uptr.any);

return uptr.any;
}


@@ -362,24 +514,30 @@ void loc_eventProc(void *xevent) {
// 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
void loc_setEventProc (Display *display, Window window) {
static void loc_setEventProc (Display *display, Window window) {
size_t data = (size_t)loc_eventProc;
long temp[2];

printf("vstgltest<lglw_linux>: setEventProc (2*32bit). window=%lu loc_eventProc=%p\n", window, &loc_eventProc);

// Split the 64 bit pointer into a little-endian long array
temp[0] = (long)(data & 0xffffffffUL);
temp[1] = (long)(data >> 32L);
// Split the 64 bit pointer into a little-endian unsigned int array
temp[0] = (uint32_t)(data & 0xffffffffUL);
temp[1] = (uint32_t)(data >> 32L);

Atom atom = XInternAtom(display, "_XEventProc", False);
XChangeProperty(display, window, atom, atom, 32,
PropModeReplace, (unsigned char*)temp, 2);
XChangeProperty(display, window,
atom/*property*/,
atom/*type*/,
32/*format*/,
PropModeReplace/*mode*/,
(unsigned char*)temp/*data*/,
2/*nelements*/
);
}
#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) {
static void loc_setEventProc (Display *display, Window window) {
//
// 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.
@@ -412,20 +570,33 @@ void loc_setEventProc (Display *display, Window window) {
}
}

long temp[2] = {(long)ptr, 0};
long temp[2] = {(uint32_t)(((size_t)ptr)&0xFFFFfffful), 0};
Atom atom = XInternAtom(display, "_XEventProc", False);
XChangeProperty(display, window, atom, atom, 32, PropModeReplace, (unsigned char *)temp, 2);
XChangeProperty(display, window,
atom/*property*/,
atom/*type*/,
32/*format*/,
PropModeReplace/*mode*/,
(unsigned char *)temp/*data*/,
2/*nelements*/
);
}
#endif
#else
// Pulled from the eXT2 example
// TODO: 32-bit support
void loc_setEventProc (Display *display, Window window) {
static void loc_setEventProc (Display *display, Window window) {
void* data = (void*)&loc_eventProc; // swapped the function name here

// (note) 32-bit only
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
XChangeProperty(display, window,
atom/*property*/,
atom/*type*/,
32/*format*/,
PropModeReplace/*mode*/,
(unsigned char*)&data/*data*/,
1/*nelements*/
);
}
#endif // ARCH_X64

@@ -437,10 +608,10 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x,

if(NULL != lglw)
{
lglw_log("lglw:lglw_window_open: 1, %p, %i\n", (Window)_parentHWNDOrNull, (Window)_parentHWNDOrNull);
lglw_log("lglw:lglw_window_open: 1, %p, %i \n", (Window)_parentHWNDOrNull, (Window)_parentHWNDOrNull);
lglw->parent_xwnd = (0 == _parentHWNDOrNull) ? DefaultRootWindow(lglw->xdsp) : (Window)_parentHWNDOrNull;

lglw_log("lglw:lglw_window_open: 2\n");
lglw_log("lglw:lglw_window_open: 2 lglw=%p\n", lglw);
if(_w <= 16)
_w = lglw->hidden.size.x;

@@ -452,7 +623,7 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x,

lglw_log("lglw:lglw_window_open: 4\n");
XSetWindowAttributes swa;
XEvent event;
// // XEvent event;
XSync(lglw->xdsp, False);

#if 1
@@ -508,7 +679,13 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x,
// 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);

if(NULL != _parentHWNDOrNull)
{
loc_setEventProc(lglw->xdsp, lglw->parent_xwnd);
loc_setProperty(lglw->xdsp, lglw->parent_xwnd, "_lglw", (void*)lglw); // set instance pointer
}
loc_setProperty(lglw->xdsp, lglw->win.xwnd, "_lglw", (void*)lglw); // set instance pointer

lglw_log("lglw:lglw_window_open: 9\n");
if(lglw->win.b_owner)
@@ -548,6 +725,8 @@ lglw_bool_t lglw_window_open (lglw_t _lglw, void *_parentHWNDOrNull, int32_t _x,
loc_enable_dropfiles(lglw, (NULL != lglw->dropfiles.cbk));

lglw_log("lglw:lglw_window_open: EXIT\n");

r = LGLW_TRUE;
}
return r;
}
@@ -725,7 +904,23 @@ void lglw_redraw(lglw_t _lglw) {
{
// TODO Event Loop
lglw_log("lglw:lglw_redraw: 1\n");
XClearArea(lglw->xdsp, lglw->win.xwnd, 0, 0, 1, 1, True); // clear tiny area for exposing
// XClearArea(lglw->xdsp, lglw->win.xwnd, 0, 0, 1, 1, True); // clear tiny area for exposing
XEvent xev;
xev.xany.type = Expose;
xev.xany.serial = 0;
xev.xany.send_event = True;
xev.xany.display = lglw->xdsp;
xev.xany.window = lglw->win.xwnd;
xev.xexpose.x = 0;
xev.xexpose.y = 0;
xev.xexpose.width = lglw->win.size.x;
xev.xexpose.height = lglw->win.size.y;
xev.xexpose.count = 0;
XSendEvent(lglw->xdsp, lglw->win.xwnd,
True/*propagate*/,
ExposureMask/*event_mask*/,
&xev
);
XFlush(lglw->xdsp);
}
}
@@ -802,7 +997,7 @@ void lglw_swap_interval_set(lglw_t _lglw, int32_t _ival) {
{
lglw_log("lglw:lglw_swap_interval_set: 1\n");
PFNWGLEXTSWAPINTERVALPROC glXSwapIntervalEXT;
glXSwapIntervalEXT = (PFNWGLEXTSWAPINTERVALPROC) glXGetProcAddress("glXSwapIntervalEXT");
glXSwapIntervalEXT = (PFNWGLEXTSWAPINTERVALPROC) glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
if(NULL != glXSwapIntervalEXT)
{
lglw_log("lglw:lglw_swap_interval_set: 2\n");
@@ -1199,6 +1394,7 @@ void lglw_clipboard_text_set(lglw_t _lglw, const uint32_t _numChars, const char

if(NULL != _text)
{
(void)lglw;
}
}

@@ -1218,6 +1414,7 @@ void lglw_clipboard_text_get(lglw_t _lglw, uint32_t _maxChars, uint32_t *_retNum
if(NULL != _lglw)
{
// (todo) implement me
(void)lglw;
}
}
}

Loading…
Cancel
Save