| @@ -36,31 +36,22 @@ | |||||
| typedef AEffect* (*PluginEntryProc) (audioMasterCallback audioMaster); | typedef AEffect* (*PluginEntryProc) (audioMasterCallback audioMaster); | ||||
| #ifndef YAC_WIN32 | #ifndef YAC_WIN32 | ||||
| // https://github.com/Ardour/ardour/blob/master/gtk2_ardour/linux_vst_gui_support.cc | |||||
| void *getXWindowProperty(Display* display, Window window, Atom atom) | |||||
| { | |||||
| static void *loc_getProperty(Display *_display, Window _window, const char *_name) { | |||||
| int userSize; | int userSize; | ||||
| unsigned long bytes; | unsigned long bytes; | ||||
| unsigned long userCount; | unsigned long userCount; | ||||
| unsigned char *data; | unsigned char *data; | ||||
| Atom userType; | Atom userType; | ||||
| // LXVST_xerror = false; | |||||
| Atom atom = XInternAtom(_display, _name, False); | |||||
| /*Use our own Xerror handler while we're in here - in an | |||||
| attempt to stop the brain dead default Xerror behaviour of | |||||
| qutting the entire application because of e.g. an invalid | |||||
| window ID*/ | |||||
| // XErrorHandler olderrorhandler = XSetErrorHandler(TempErrorHandler); | |||||
| printf("xxx getXWindowProperty: window=%lu\n", window); | |||||
| XGetWindowProperty(display, | |||||
| window, | |||||
| // (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, | atom, | ||||
| 0/*offset*/, | 0/*offset*/, | ||||
| 2/*length*/, | |||||
| false/*delete*/, | |||||
| 1/*length*/, | |||||
| False/*delete*/, | |||||
| AnyPropertyType, | AnyPropertyType, | ||||
| &userType/*actual_type_return*/, | &userType/*actual_type_return*/, | ||||
| &userSize/*actual_format_return*/, | &userSize/*actual_format_return*/, | ||||
| @@ -69,39 +60,63 @@ void *getXWindowProperty(Display* display, Window window, Atom atom) | |||||
| &data); | &data); | ||||
| union { | union { | ||||
| long l[2]; | |||||
| uint32_t ui[2]; | |||||
| void *any; | void *any; | ||||
| } uptr; | } uptr; | ||||
| uptr.any = 0; | uptr.any = 0; | ||||
| printf("xxx getXWindowProperty: userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data); | |||||
| printf("xxx debug_host: loc_getProperty: LOWER userSize=%d userCount=%lu bytes=%lu data=%p\n", userSize, userCount, bytes, data); | |||||
| if(NULL != data) | if(NULL != data) | ||||
| { | { | ||||
| if(userCount == 1) | |||||
| if(userCount >= 1) | |||||
| { | { | ||||
| // 32-bit | |||||
| uptr.l[0] = *(long*)data; | |||||
| uptr.l[1] = 0; | |||||
| } | |||||
| else if(2 == userCount) | |||||
| { | |||||
| // 64-bit | |||||
| uptr.l[0] = ((long*)data)[0]; | |||||
| uptr.l[1] = ((long*)data)[1]; | |||||
| } | |||||
| if(userCount >= 2) | |||||
| { | |||||
| printf("xxx debug_host: loc_getProperty: lo=0x%08x hi=0x%08x\n", ((uint32_t*)data)[0], ((uint32_t*)data)[1]); | |||||
| } | |||||
| XFree(data); | |||||
| } | |||||
| // 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); | |||||
| // XSetErrorHandler(olderrorhandler); | |||||
| // // 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); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /*Hopefully this will return zero if the property is not set*/ | |||||
| printf("xxx getXWindowProperty: return callback addr=%p\n", uptr.any); | |||||
| printf("xxx debug_host: loc_getProperty: return value=%p\n", uptr.any); | |||||
| return uptr.any; | return uptr.any; | ||||
| } | } | ||||
| #endif | |||||
| #endif // !YAC_WIN32 | |||||
| static VstIntPtr VSTCALLBACK HostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) { | static VstIntPtr VSTCALLBACK HostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) { | ||||
| @@ -208,6 +223,19 @@ void open_and_close(void) { | |||||
| XFlush(d); | XFlush(d); | ||||
| #endif | #endif | ||||
| #if 0 | |||||
| // Event test (=> keyboard events are working) | |||||
| { | |||||
| int evIdx = 0; | |||||
| for(;;) | |||||
| { | |||||
| XEvent xev; | |||||
| XNextEvent(d, &xev); | |||||
| printf("xxx XNextEvent[%d]\n", evIdx++); | |||||
| } | |||||
| } | |||||
| #endif | |||||
| printf("xxx calling effect->dispatcher<effOpen>\n"); | printf("xxx calling effect->dispatcher<effOpen>\n"); | ||||
| effect->dispatcher(effect, effOpen, 0, 0, NULL, 0.0f); | effect->dispatcher(effect, effOpen, 0, 0, NULL, 0.0f); | ||||
| printf("xxx effect->dispatcher<effOpen> returned\n"); | printf("xxx effect->dispatcher<effOpen> returned\n"); | ||||
| @@ -220,7 +248,7 @@ void open_and_close(void) { | |||||
| sleep(2); | sleep(2); | ||||
| #ifndef YAC_WIN32 | #ifndef YAC_WIN32 | ||||
| void *result = getXWindowProperty(d, w, XInternAtom(d, "_XEventProc", false)); | |||||
| void *result = loc_getProperty(d, w, "_XEventProc"); | |||||
| if(result == 0) | if(result == 0) | ||||
| { | { | ||||
| printf("xxx no XEventProc found\n"); | printf("xxx no XEventProc found\n"); | ||||