X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glws_glx.cpp;h=95cdab078951eef107b8936d8a56fa34f3df58b4;hb=35c2793ac758997a0a1c2e558d384ab94754987d;hp=39e0c4682ddbf0498e45bbed8b7956e405d2e549;hpb=7497c130f98f33f41437678835f4b2eb2abce750;p=apitrace diff --git a/glws_glx.cpp b/glws_glx.cpp index 39e0c46..95cdab0 100644 --- a/glws_glx.cpp +++ b/glws_glx.cpp @@ -26,9 +26,12 @@ #include #include -#include "glimports.hpp" #include "glws.hpp" +#include +#include +#include + namespace glws { @@ -36,6 +39,7 @@ namespace glws { static Display *display = NULL; static int screen = 0; + class GlxVisual : public Visual { public: @@ -51,6 +55,42 @@ public: }; +static void describeEvent(const XEvent &event) { + if (0) { + switch (event.type) { + case ConfigureNotify: + std::cerr << "ConfigureNotify"; + break; + case Expose: + std::cerr << "Expose"; + break; + case KeyPress: + std::cerr << "KeyPress"; + break; + case MapNotify: + std::cerr << "MapNotify"; + break; + case ReparentNotify: + std::cerr << "ReparentNotify"; + break; + default: + std::cerr << "Event " << event.type; + } + std::cerr << " " << event.xany.window << "\n"; + } +} + +static void waitForEvent(Window window, int type) { + XFlush(display); + XEvent event; + do { + XNextEvent(display, &event); + describeEvent(event); + } while (event.type != type || + event.xany.window != window); +} + + class GlxDrawable : public Drawable { public: @@ -98,7 +138,7 @@ public: display, window, name, name, None, (char **)NULL, 0, &sizehints); - XMapWindow(display, window); + glXWaitX(); } ~GlxDrawable() { @@ -108,11 +148,40 @@ public: void resize(int w, int h) { glXWaitGL(); + + // We need to ensure that pending events are processed here, and XSync + // with discard = True guarantees that, but it appears the limited + // event processing we do so far is sufficient + //XSync(display, True); + Drawable::resize(w, h); + XResizeWindow(display, window, w, h); + + // Tell the window manager to respect the requested size + XSizeHints *size_hints; + size_hints = XAllocSizeHints(); + size_hints->max_width = size_hints->min_width = w; + size_hints->max_height = size_hints->min_height = h; + size_hints->flags = PMinSize | PMaxSize; + XSetWMNormalHints(display, window, size_hints); + XFree(size_hints); + + waitForEvent(window, ConfigureNotify); + glXWaitX(); } + void show(void) { + if (!visible) { + XMapWindow(display, window); + + waitForEvent(window, Expose); + + Drawable::show(); + } + } + void swapBuffers(void) { glXSwapBuffers(display, window); } @@ -160,6 +229,7 @@ public: GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 1, GLX_DEPTH_SIZE, 1, GLX_STENCIL_SIZE, 1, None @@ -170,6 +240,7 @@ public: GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, GLX_STENCIL_SIZE, 1, @@ -190,10 +261,18 @@ public: } Context * - createContext(const Visual *visual) + createContext(const Visual *visual, Context *shareContext) { XVisualInfo *visinfo = dynamic_cast(visual)->visinfo; - GLXContext context = glXCreateContext(display, visinfo, NULL, True); + GLXContext share_context = NULL; + GLXContext context; + + if (shareContext) { + share_context = dynamic_cast(shareContext)->context; + } + + context = glXCreateContext(display, visinfo, + share_context, True); return new GlxContext(visual, context); } @@ -212,10 +291,11 @@ public: bool processEvents(void) { + XFlush(display); while (XPending(display) > 0) { XEvent event; XNextEvent(display, &event); - // TODO + describeEvent(event); } return true; }