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.
22 #include <X11/Xutil.h>
30 XDestroyWindow(display, window);
31 XCloseDisplay(display);
34 void GLWindow::create(unsigned int width, unsigned int height)
37 // get visual from backend
38 XVisualInfo vinfo_template;
39 vinfo_template.visualid = backend->initialize(display);
41 XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask, &vinfo_template, &num_vinfo);
42 assert(num_vinfo == 1 && vi != NULL);
44 XSetWindowAttributes winAttr;
45 winAttr.colormap = XCreateColormap(display, RootWindow(display, vi->screen), vi->visual, AllocNone);
46 winAttr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
47 winAttr.border_pixel = 0;
49 printf("Initial window size: %dx%d\n", width, height);
50 // create a window in window mode
51 window = XCreateWindow(display, RootWindow(display, vi->screen),
52 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
53 CWBorderPixel | CWColormap | CWEventMask, &winAttr);
54 /* handle wm_delete_events */
55 Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
56 XMapRaised(display, window);
57 XSetWMProtocols(display, window, &wmDelete, 1);
59 this->fullscreen = false;
61 this->height = height;
62 backend->createContext(window);
64 resizeGL(width, height);
67 void GLWindow::close()
71 memset(&ev, 0, sizeof (ev));
72 ev.xclient.type = ClientMessage;
73 ev.xclient.window = window;
74 ev.xclient.message_type = XInternAtom(display, "WM_PROTOCOLS", true);
75 ev.xclient.format = 32;
76 ev.xclient.data.l[0] = XInternAtom(display, "WM_DELETE_WINDOW", false);
77 ev.xclient.data.l[1] = CurrentTime;
78 XSendEvent(display, window, False, NoEventMask, &ev);
81 void GLWindow::setFullscreen(bool fullscreen)
84 // set fullscreen property
86 e.xclient.type = ClientMessage;
87 e.xclient.window = window;
88 e.xclient.message_type = XInternAtom(display, "_NET_WM_STATE", true);
89 e.xclient.format = 32;
90 e.xclient.data.l[0] = 2; // _NET_WM_STATE_TOGGLE
91 e.xclient.data.l[1] = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", fullscreen);
92 e.xclient.data.l[2] = 0; // no second property to toggle
93 e.xclient.data.l[3] = 1;
94 e.xclient.data.l[4] = 0;
95 XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &e);
102 /* handle the events in the queue */
103 while (XPending(display) > 0)
106 XNextEvent(display, &event);
112 case ConfigureNotify:
113 if (event.xconfigure.width != this->width || event.xconfigure.height != this->height) {
114 printf("Window resized to: %dx%d\n", event.xconfigure.width, event.xconfigure.height);
115 this->width = event.xconfigure.width;
116 this->height = event.xconfigure.height;
117 resizeGL(this->width, this->height);
121 handleKeyPress(XLookupKeysym(&event.xkey, 0));
124 if (strcmp(XGetAtomName(display, event.xclient.message_type), "WM_PROTOCOLS") == 0 &&
125 strcmp(XGetAtomName(display, event.xclient.data.l[0]), "WM_DELETE_WINDOW") == 0)