X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glws_glx.cpp;h=95cdab078951eef107b8936d8a56fa34f3df58b4;hb=ee2073911c1f76715427ef0c031bea7b8483ea97;hp=3e25dc3d6ec40a65c2cee8de71948a707c334176;hpb=ce6bcdd4395c9efec37a26f6c1caf8944d75f6d0;p=apitrace diff --git a/glws_glx.cpp b/glws_glx.cpp index 3e25dc3..95cdab0 100644 --- a/glws_glx.cpp +++ b/glws_glx.cpp @@ -23,48 +23,163 @@ * **************************************************************************/ -#include "glimports.hpp" +#include +#include + #include "glws.hpp" +#include +#include +#include + namespace glws { -class XlibVisual : public Visual +static Display *display = NULL; +static int screen = 0; + + +class GlxVisual : public Visual { public: XVisualInfo *visinfo; - XlibVisual(XVisualInfo *vi) : + GlxVisual(XVisualInfo *vi) : visinfo(vi) {} - ~XlibVisual() { + ~GlxVisual() { XFree(visinfo); } }; -class XlibDrawable : public Drawable +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: - Display *display; Window window; - XlibDrawable(const Visual *vis, Display *dpy, Window win) : - Drawable(vis), - display(dpy), - window(win) - {} + GlxDrawable(const Visual *vis, int w, int h) : + Drawable(vis, w, h) + { + XVisualInfo *visinfo = dynamic_cast(visual)->visinfo; + + Window root = RootWindow(display, screen); + + /* window attributes */ + XSetWindowAttributes attr; + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + + unsigned long mask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + int x = 0, y = 0; + + window = XCreateWindow( + display, root, + x, y, width, height, + 0, + visinfo->depth, + InputOutput, + visinfo->visual, + mask, + &attr); + + XSizeHints sizehints; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(display, window, &sizehints); + + const char *name = "glretrace"; + XSetStandardProperties( + display, window, name, name, + None, (char **)NULL, 0, &sizehints); + + glXWaitX(); + } - ~XlibDrawable() { + ~GlxDrawable() { XDestroyWindow(display, window); } - + void - resize(unsigned w, unsigned h) { + 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) { @@ -73,37 +188,37 @@ public: }; -class XlibContext : public Context +class GlxContext : public Context { public: - Display *display; GLXContext context; - - XlibContext(const Visual *vis, Display *dpy, GLXContext ctx) : + + GlxContext(const Visual *vis, GLXContext ctx) : Context(vis), - display(dpy), context(ctx) {} - ~XlibContext() { + ~GlxContext() { glXDestroyContext(display, context); } }; -class XlibWindowSystem : public WindowSystem +class GlxWindowSystem : public WindowSystem { -private: - Display *display; - int screen; - public: - XlibWindowSystem() { - display = XOpenDisplay(NULL); - screen = DefaultScreen(display); + GlxWindowSystem() { + if (!display) { + display = XOpenDisplay(NULL); + if (!display) { + std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n"; + exit(1); + } + screen = DefaultScreen(display); + } } - ~XlibWindowSystem() { + ~GlxWindowSystem() { XCloseDisplay(display); } @@ -114,7 +229,9 @@ 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 }; @@ -123,88 +240,62 @@ 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, None }; XVisualInfo *visinfo; - + visinfo = glXChooseVisual(display, screen, doubleBuffer ? double_attribs : single_attribs); - return new XlibVisual(visinfo); + return new GlxVisual(visinfo); } - + Drawable * - createDrawable(const Visual *visual) + createDrawable(const Visual *visual, int width, int height) { - XVisualInfo *visinfo = dynamic_cast(visual)->visinfo; - - Window root = RootWindow(display, screen); - - /* window attributes */ - XSetWindowAttributes attr; - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; - - unsigned long mask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - int x = 0, y = 0, width = 256, height = 256; - - Window window = XCreateWindow( - display, root, - x, y, width, height, - 0, - visinfo->depth, - InputOutput, - visinfo->visual, - mask, - &attr); - - XSizeHints sizehints; - sizehints.x = x; - sizehints.y = y; - sizehints.width = width; - sizehints.height = height; - sizehints.flags = USSize | USPosition; - XSetNormalHints(display, window, &sizehints); - - const char *name = "glretrace"; - XSetStandardProperties( - display, window, name, name, - None, (char **)NULL, 0, &sizehints); - - XMapWindow(display, window); - - return new XlibDrawable(visual, display, window); + return new GlxDrawable(visual, width, height); } Context * - createContext(const Visual *visual) + createContext(const Visual *visual, Context *shareContext) { - XVisualInfo *visinfo = dynamic_cast(visual)->visinfo; - GLXContext context = glXCreateContext(display, visinfo, NULL, True); - return new XlibContext(visual, display, context); + XVisualInfo *visinfo = dynamic_cast(visual)->visinfo; + 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); } bool makeCurrent(Drawable *drawable, Context *context) { - Window win = drawable ? dynamic_cast(drawable)->window : NULL; - GLXContext ctx = context ? dynamic_cast(context)->context : NULL; + if (!drawable || !context) { + return glXMakeCurrent(display, None, NULL); + } else { + GlxDrawable *glxDrawable = dynamic_cast(drawable); + GlxContext *glxContext = dynamic_cast(context); - return glXMakeCurrent(display, win, ctx); + return glXMakeCurrent(display, glxDrawable->window, glxContext->context); + } } bool processEvents(void) { + XFlush(display); while (XPending(display) > 0) { XEvent event; XNextEvent(display, &event); - // TODO + describeEvent(event); } return true; } @@ -212,7 +303,7 @@ public: WindowSystem *createNativeWindowSystem(void) { - return new XlibWindowSystem(); + return new GlxWindowSystem(); }