#include <stdlib.h>
#include <iostream>
-#include "glimports.hpp"
#include "glws.hpp"
+#include <X11/Xlib.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
namespace glws {
static Display *display = NULL;
static int screen = 0;
+
class GlxVisual : public Visual
{
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:
display, window, name, name,
None, (char **)NULL, 0, &sizehints);
- XMapWindow(display, window);
+ glXWaitX();
}
~GlxDrawable() {
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);
}
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
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,
}
Context *
- createContext(const Visual *visual)
+ createContext(const Visual *visual, Context *shareContext)
{
XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
- GLXContext context = glXCreateContext(display, visinfo, NULL, True);
+ GLXContext share_context = NULL;
+ GLXContext context;
+
+ if (shareContext) {
+ share_context = dynamic_cast<GlxContext*>(shareContext)->context;
+ }
+
+ context = glXCreateContext(display, visinfo,
+ share_context, True);
return new GlxContext(visual, context);
}
bool
processEvents(void) {
+ XFlush(display);
while (XPending(display) > 0) {
XEvent event;
XNextEvent(display, &event);
- // TODO
+ describeEvent(event);
}
return true;
}