]> git.cworth.org Git - apitrace/blob - glws_glx.cpp
Print an error message when not able to open X display.
[apitrace] / glws_glx.cpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include <stdlib.h>
27 #include <iostream>
28
29 #include "glimports.hpp"
30 #include "glws.hpp"
31
32
33 namespace glws {
34
35
36 class GlxVisual : public Visual
37 {
38 public:
39     XVisualInfo *visinfo;
40
41     GlxVisual(XVisualInfo *vi) :
42         visinfo(vi)
43     {}
44
45     ~GlxVisual() {
46         XFree(visinfo);
47     }
48 };
49
50
51 class GlxDrawable : public Drawable
52 {
53 public:
54     Display *display;
55     Window window;
56
57     GlxDrawable(const Visual *vis, Display *dpy, Window win) :
58         Drawable(vis),
59         display(dpy), 
60         window(win)
61     {}
62
63     ~GlxDrawable() {
64         XDestroyWindow(display, window);
65     }
66     
67     void
68     resize(unsigned w, unsigned h) {
69         glXWaitGL();
70         Drawable::resize(w, h);
71         XResizeWindow(display, window, w, h);
72         glXWaitX();
73     }
74
75     void swapBuffers(void) {
76         glXSwapBuffers(display, window);
77     }
78 };
79
80
81 class GlxContext : public Context
82 {
83 public:
84     Display *display;
85     GLXContext context;
86     
87     GlxContext(const Visual *vis, Display *dpy, GLXContext ctx) :
88         Context(vis),
89         display(dpy), 
90         context(ctx)
91     {}
92
93     ~GlxContext() {
94         glXDestroyContext(display, context);
95     }
96 };
97
98
99 class GlxWindowSystem : public WindowSystem
100 {
101 private:
102     Display *display;
103     int screen;
104
105 public:
106     GlxWindowSystem() {
107         display = XOpenDisplay(NULL);
108         if (!display) {
109             std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
110             exit(1);
111         }
112         screen = DefaultScreen(display);
113     }
114
115     ~GlxWindowSystem() {
116         XCloseDisplay(display);
117     }
118
119     Visual *
120     createVisual(bool doubleBuffer) {
121         int single_attribs[] = {
122             GLX_RGBA,
123             GLX_RED_SIZE, 1,
124             GLX_GREEN_SIZE, 1,
125             GLX_BLUE_SIZE, 1,
126             GLX_DEPTH_SIZE, 1,
127             GLX_STENCIL_SIZE, 1,
128             None
129         };
130
131         int double_attribs[] = {
132             GLX_RGBA,
133             GLX_RED_SIZE, 1,
134             GLX_GREEN_SIZE, 1,
135             GLX_BLUE_SIZE, 1,
136             GLX_DOUBLEBUFFER,
137             GLX_DEPTH_SIZE, 1,
138             GLX_STENCIL_SIZE, 1,
139             None
140         };
141
142         XVisualInfo *visinfo;
143         
144         visinfo = glXChooseVisual(display, screen, doubleBuffer ? double_attribs : single_attribs);
145
146         return new GlxVisual(visinfo);
147     }
148     
149     Drawable *
150     createDrawable(const Visual *visual)
151     {
152         XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
153
154         Window root = RootWindow(display, screen);
155
156         /* window attributes */
157         XSetWindowAttributes attr;
158         attr.background_pixel = 0;
159         attr.border_pixel = 0;
160         attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
161         attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
162         
163         unsigned long mask;
164         mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
165
166         int x = 0, y = 0, width = 256, height = 256;
167
168         Window window = XCreateWindow(
169             display, root, 
170             x, y, width, height,
171             0, 
172             visinfo->depth, 
173             InputOutput,
174             visinfo->visual, 
175             mask, 
176             &attr);
177
178         XSizeHints sizehints;
179         sizehints.x = x;
180         sizehints.y = y;
181         sizehints.width  = width;
182         sizehints.height = height;
183         sizehints.flags = USSize | USPosition;
184         XSetNormalHints(display, window, &sizehints);
185         
186         const char *name = "glretrace";
187         XSetStandardProperties(
188             display, window, name, name,
189             None, (char **)NULL, 0, &sizehints);
190
191         XMapWindow(display, window);
192         
193         return new GlxDrawable(visual, display, window);
194     }
195
196     Context *
197     createContext(const Visual *visual)
198     {
199         XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
200         GLXContext context = glXCreateContext(display, visinfo, NULL, True);
201         return new GlxContext(visual, display, context);
202     }
203
204     bool
205     makeCurrent(Drawable *drawable, Context *context)
206     {
207         if (!drawable || !context) {
208             return glXMakeCurrent(display, None, NULL);
209         } else {
210             GlxDrawable *glxDrawable = dynamic_cast<GlxDrawable *>(drawable);
211             GlxContext *glxContext = dynamic_cast<GlxContext *>(context);
212
213             return glXMakeCurrent(display, glxDrawable->window, glxContext->context);
214         }
215     }
216
217     bool
218     processEvents(void) {
219         while (XPending(display) > 0) {
220             XEvent event;
221             XNextEvent(display, &event);
222             // TODO
223         }
224         return true;
225     }
226 };
227
228
229 WindowSystem *createNativeWindowSystem(void) {
230     return new GlxWindowSystem();
231 }
232
233
234 } /* namespace glretrace */