GLDisplayOptions::GLDisplayOptions():
alpha(false),
+ stencil(false),
doublebuffer(true),
multisample(0)
{ }
GLWindow::~GLWindow()
{
- glXMakeCurrent(display, 0, 0);
+ glXMakeContextCurrent(display, 0, 0, 0);
+ glXDestroyWindow(display, glx_wnd);
glXDestroyContext(display, context);
}
void GLWindow::swap_buffers()
{
- glXSwapBuffers(display, window);
+ glXSwapBuffers(display, glx_wnd);
}
void GLWindow::init()
prepare();
vector<int> attribs;
- attribs.push_back(GLX_RGBA);
- attribs.push_back(GLX_BUFFER_SIZE);
- attribs.push_back(24);
+
+ attribs.push_back(GLX_RENDER_TYPE);
+ attribs.push_back(GLX_RGBA_BIT);
+
+ attribs.push_back(GLX_DRAWABLE_TYPE);
+ attribs.push_back(GLX_WINDOW_BIT);
+
+ attribs.push_back(GLX_DEPTH_SIZE);
+ attribs.push_back(1);
+
if(gl_options.alpha)
{
attribs.push_back(GLX_ALPHA_SIZE);
attribs.push_back(1);
}
+
+ if(gl_options.stencil)
+ {
+ attribs.push_back(GLX_STENCIL_SIZE);
+ attribs.push_back(1);
+ }
+
if(gl_options.doublebuffer)
+ {
attribs.push_back(GLX_DOUBLEBUFFER);
+ attribs.push_back(true);
+ }
+
if(gl_options.multisample>0)
{
attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
attribs.push_back(gl_options.multisample);
}
- attribs.push_back(0);
+
+ attribs.push_back(None);
- XVisualInfo *visual=glXChooseVisual(display, DefaultScreen(display), &attribs.front());
- if(!visual)
- throw Exception("Couldn't get a matching GLX visual");
+ int count;
+ GLXFBConfig *config=glXChooseFBConfig(display, DefaultScreen(display), &attribs.front(), &count);
+ if(!config)
+ throw Exception("Couldn't get a GLX framebuffer configuration");
- context=glXCreateContext(display, visual, 0, true);
+ context=glXCreateNewContext(display, config[0], GLX_RGBA_TYPE, 0, true);
if(!context)
throw Exception("Couldn't create a GLX context");
- create();
+ XVisualInfo *vi=glXGetVisualFromFBConfig(display, config[0]);
+ Handle root=RootWindow(display, vi->screen);
+
+ Colormap cmap=XCreateColormap(display, root, vi->visual, AllocNone);
+ XSetWindowAttributes attr;
+ attr.colormap=cmap;
+
+ Handle wnd=XCreateWindow(display, root, 0, 0, options.width, options.height, 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
+ set_window(wnd);
+
+ glx_wnd=glXCreateWindow(display, config[0], wnd, 0);
+
+ glXMakeContextCurrent(display, glx_wnd, glx_wnd, context);
- glXMakeCurrent(display, window, context);
+ XFree(config);
}
-void GLWindow::on_resize()
+void GLWindow::on_event(const XEvent &event)
{
- glViewport(0, 0, options.width, options.height);
+ if(event.type==ConfigureNotify)
+ glViewport(0, 0, options.width, options.height);
}
} // namespace Msp
wm_delete_window=XInternAtom(display, "WM_DELETE_WINDOW", true);
+ /* Throwing from the error handler doesn't work too well and I don't know
+ how to dig up all the information that Xlib gives by default, so disable
+ custom error handling for now. */
//XSetErrorHandler(x_error_handler);
}
-void Window::create()
+void Window::set_window(Handle wnd)
{
- window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0);
- if(!window)
- throw Exception("Couldn't create a window");
+ window=wnd;
XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask);
void Window::init()
{
prepare();
- create();
+
+ Handle wnd=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0);
+ set_window(wnd);
}
void Window::process_event(const XEvent &event)
case ConfigureNotify:
options.width=event.xconfigure.width;
options.height=event.xconfigure.height;
- on_resize();
signal_resize.emit(options.width, options.height);
break;
case ClientMessage:
break;
default:;
}
+
+ on_event(event);
}
int Window::x_error_handler(Display *display, XErrorEvent *error)
Window();
public:
- Window(unsigned, unsigned);
- Window(const DisplayOptions &);
+ Window(unsigned w, unsigned h);
+ Window(const DisplayOptions &dopt);
virtual ~Window();
unsigned get_width() const { return options.width; }
void tick();
protected:
void prepare();
- void create();
+ void set_window(Handle wnd);
void init();
- void process_event(const XEvent &);
- virtual void on_resize() { }
+ void process_event(const XEvent &event);
+ virtual void on_event(const XEvent &event) { (void)event; }
static int x_error_handler(Display *, XErrorEvent *);
};