diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 8e571651c4..506127304b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -112,22 +112,28 @@ void CreateXWindow (void) { Atom wmProtocols[1]; + // use evdpy to create the window, so that connection gets the events + // the colormap needs to be created on the same display, because it + // is a client side structure, as well as wmProtocols(or so it seems) + // GLWin.win is a xserver global window handle, so it can be used by both + // display connections + // Setup window attributes - GLWin.attr.colormap = XCreateColormap(GLWin.dpy, + GLWin.attr.colormap = XCreateColormap(GLWin.evdpy, GLWin.parent, GLWin.vi->visual, AllocNone); GLWin.attr.event_mask = KeyPressMask | StructureNotifyMask | FocusChangeMask; - GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen); + GLWin.attr.background_pixel = BlackPixel(GLWin.evdpy, GLWin.screen); GLWin.attr.border_pixel = 0; // Create the window - GLWin.win = XCreateWindow(GLWin.dpy, GLWin.parent, + GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent, GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual, CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr); - wmProtocols[0] = XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", True); - XSetWMProtocols(GLWin.dpy, GLWin.win, wmProtocols, 1); - XSetStandardProperties(GLWin.dpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); - XMapRaised(GLWin.dpy, GLWin.win); - XSync(GLWin.dpy, True); + wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True); + XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1); + XSetStandardProperties(GLWin.evdpy, GLWin.win, "GPU", "GPU", None, NULL, 0, NULL); + XMapRaised(GLWin.evdpy, GLWin.win); + XSync(GLWin.evdpy, True); GLWin.xEventThread = new Common::Thread(XEventThread, NULL); } @@ -136,10 +142,10 @@ void DestroyXWindow(void) { XUnmapWindow(GLWin.dpy, GLWin.win); GLWin.win = 0; - XFreeColormap(GLWin.dpy, GLWin.attr.colormap); if (GLWin.xEventThread) GLWin.xEventThread->WaitForDeath(); GLWin.xEventThread = NULL; + XFreeColormap(GLWin.evdpy, GLWin.attr.colormap); } THREAD_RETURN XEventThread(void *pArg) @@ -148,8 +154,8 @@ THREAD_RETURN XEventThread(void *pArg) { XEvent event; KeySym key; - for (int num_events = XPending(GLWin.dpy); num_events > 0; num_events--) { - XNextEvent(GLWin.dpy, &event); + for (int num_events = XPending(GLWin.evdpy); num_events > 0; num_events--) { + XNextEvent(GLWin.evdpy, &event); switch(event.type) { case KeyPress: key = XLookupKeysym((XKeyEvent*)&event, 0); @@ -202,16 +208,16 @@ THREAD_RETURN XEventThread(void *pArg) case ConfigureNotify: Window winDummy; unsigned int borderDummy, depthDummy; - XGetGeometry(GLWin.dpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, + XGetGeometry(GLWin.evdpy, GLWin.win, &winDummy, &GLWin.x, &GLWin.y, &GLWin.width, &GLWin.height, &borderDummy, &depthDummy); s_backbuffer_width = GLWin.width; s_backbuffer_height = GLWin.height; break; case ClientMessage: - if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "WM_DELETE_WINDOW", False)) + if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) g_VideoInitialize.pCoreMessage(WM_USER_STOP); - if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.dpy, "RESIZE", False)) - XMoveResizeWindow(GLWin.dpy, GLWin.win, event.xclient.data.l[1], + if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False)) + XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1], event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); break; default: @@ -343,6 +349,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight None }; GLWin.dpy = XOpenDisplay(0); + GLWin.evdpy = XOpenDisplay(0); GLWin.parent = (Window)g_VideoInitialize.pWindowHandle; GLWin.screen = DefaultScreen(GLWin.dpy); if (GLWin.parent == 0) @@ -492,6 +499,7 @@ void OpenGL_Shutdown() { glXDestroyContext(GLWin.dpy, GLWin.ctx); XCloseDisplay(GLWin.dpy); + XCloseDisplay(GLWin.evdpy); GLWin.ctx = NULL; } #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h index e87d557548..c0fb1a55f3 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h @@ -78,7 +78,10 @@ typedef struct { int screen; Window win; Window parent; - Display *dpy; + // dpy (mainly) used for glx stuff, evdpy for window events etc. + // used to keep the two threads from eating each others events + // evdpy is to be used by XEventThread only (when it is running) + Display *dpy, *evdpy; XVisualInfo *vi; GLXContext ctx; XSetWindowAttributes attr;