1 /* gltest - small OpenGL tearing test program
2 * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <X11/Xutil.h>
31 XDestroyWindow(display, window);
32 XCloseDisplay(display);
35 void GLWindow::create(unsigned int width, unsigned int height)
38 // get visual from backend
39 XVisualInfo vinfo_template;
40 vinfo_template.visualid = backend->initialize(display);
42 XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask, &vinfo_template, &num_vinfo);
43 assert(num_vinfo == 1 && vi != NULL);
45 XSetWindowAttributes winAttr;
46 winAttr.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone);
47 winAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
48 winAttr.border_pixel = 0;
50 printf("Initial window size: %dx%d\n", width, height);
51 // create a window in window mode
52 window = XCreateWindow(display, RootWindow(display, vi->screen),
53 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
54 CWBorderPixel | CWColormap | CWEventMask, &winAttr);
55 /* handle wm_delete_events */
56 Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
57 XMapRaised(display, window);
58 XSetWMProtocols(display, window, &wmDelete, 1);
60 this->fullscreen = false;
62 this->height = height;
63 backend->createContext(window);
64 printf("Using GL version: %s\n", glGetString(GL_VERSION));
66 resizeGL(width, height);
69 void GLWindow::close()
73 memset(&ev, 0, sizeof (ev));
74 ev.xclient.type = ClientMessage;
75 ev.xclient.window = window;
76 ev.xclient.message_type = XInternAtom(display, "WM_PROTOCOLS", true);
77 ev.xclient.format = 32;
78 ev.xclient.data.l[0] = XInternAtom(display, "WM_DELETE_WINDOW", false);
79 ev.xclient.data.l[1] = CurrentTime;
80 XSendEvent(display, window, False, NoEventMask, &ev);
83 void GLWindow::setFullscreen(bool fullscreen)
86 // set fullscreen property
88 e.xclient.type = ClientMessage;
89 e.xclient.window = window;
90 e.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", true);
91 e.xclient.format = 32;
92 e.xclient.data.l[0] = 2; // _NET_WM_STATE_TOGGLE
93 e.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", fullscreen);
94 e.xclient.data.l[2] = 0; // no second property to toggle
95 e.xclient.data.l[3] = 1;
96 e.xclient.data.l[4] = 0;
97 XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &e);
100 void GLWindow::exec()
104 /* handle the events in the queue */
105 while (XPending(display) > 0)
108 XNextEvent(display, &event);
114 case ConfigureNotify:
115 if (event.xconfigure.width != this->width || event.xconfigure.height != this->height) {
116 printf("Window resized to: %dx%d\n", event.xconfigure.width, event.xconfigure.height);
117 this->width = event.xconfigure.width;
118 this->height = event.xconfigure.height;
119 resizeGL(this->width, this->height);
123 handleKeyPress(XLookupKeysym(&event.xkey, 0));
126 if (strcmp(XGetAtomName(display, event.xclient.message_type), "WM_PROTOCOLS") == 0 &&
127 strcmp(XGetAtomName(display, event.xclient.data.l[0]), "WM_DELETE_WINDOW") == 0)