]> git.cworth.org Git - apitrace/blob - glws_glx.cpp
Merge branch 'trace-editing'
[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 "glimports.hpp"
27 #include "glws.hpp"
28
29
30 namespace glws {
31
32
33 class GlxVisual : public Visual
34 {
35 public:
36     XVisualInfo *visinfo;
37
38     GlxVisual(XVisualInfo *vi) :
39         visinfo(vi)
40     {}
41
42     ~GlxVisual() {
43         XFree(visinfo);
44     }
45 };
46
47
48 class GlxDrawable : public Drawable
49 {
50 public:
51     Display *display;
52     Window window;
53
54     GlxDrawable(const Visual *vis, Display *dpy, Window win) :
55         Drawable(vis),
56         display(dpy), 
57         window(win)
58     {}
59
60     ~GlxDrawable() {
61         XDestroyWindow(display, window);
62     }
63     
64     void
65     resize(unsigned w, unsigned h) {
66         glXWaitGL();
67         Drawable::resize(w, h);
68         XResizeWindow(display, window, w, h);
69         glXWaitX();
70     }
71
72     void swapBuffers(void) {
73         glXSwapBuffers(display, window);
74     }
75 };
76
77
78 class GlxContext : public Context
79 {
80 public:
81     Display *display;
82     GLXContext context;
83     
84     GlxContext(const Visual *vis, Display *dpy, GLXContext ctx) :
85         Context(vis),
86         display(dpy), 
87         context(ctx)
88     {}
89
90     ~GlxContext() {
91         glXDestroyContext(display, context);
92     }
93 };
94
95
96 class GlxWindowSystem : public WindowSystem
97 {
98 private:
99     Display *display;
100     int screen;
101
102 public:
103     GlxWindowSystem() {
104         display = XOpenDisplay(NULL);
105         screen = DefaultScreen(display);
106     }
107
108     ~GlxWindowSystem() {
109         XCloseDisplay(display);
110     }
111
112     Visual *
113     createVisual(bool doubleBuffer) {
114         int single_attribs[] = {
115             GLX_RGBA,
116             GLX_RED_SIZE, 1,
117             GLX_GREEN_SIZE, 1,
118             GLX_BLUE_SIZE, 1,
119             GLX_DEPTH_SIZE, 1,
120             GLX_STENCIL_SIZE, 1,
121             None
122         };
123
124         int double_attribs[] = {
125             GLX_RGBA,
126             GLX_RED_SIZE, 1,
127             GLX_GREEN_SIZE, 1,
128             GLX_BLUE_SIZE, 1,
129             GLX_DOUBLEBUFFER,
130             GLX_DEPTH_SIZE, 1,
131             GLX_STENCIL_SIZE, 1,
132             None
133         };
134
135         XVisualInfo *visinfo;
136         
137         visinfo = glXChooseVisual(display, screen, doubleBuffer ? double_attribs : single_attribs);
138
139         return new GlxVisual(visinfo);
140     }
141     
142     Drawable *
143     createDrawable(const Visual *visual)
144     {
145         XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
146
147         Window root = RootWindow(display, screen);
148
149         /* window attributes */
150         XSetWindowAttributes attr;
151         attr.background_pixel = 0;
152         attr.border_pixel = 0;
153         attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
154         attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
155         
156         unsigned long mask;
157         mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
158
159         int x = 0, y = 0, width = 256, height = 256;
160
161         Window window = XCreateWindow(
162             display, root, 
163             x, y, width, height,
164             0, 
165             visinfo->depth, 
166             InputOutput,
167             visinfo->visual, 
168             mask, 
169             &attr);
170
171         XSizeHints sizehints;
172         sizehints.x = x;
173         sizehints.y = y;
174         sizehints.width  = width;
175         sizehints.height = height;
176         sizehints.flags = USSize | USPosition;
177         XSetNormalHints(display, window, &sizehints);
178         
179         const char *name = "glretrace";
180         XSetStandardProperties(
181             display, window, name, name,
182             None, (char **)NULL, 0, &sizehints);
183
184         XMapWindow(display, window);
185         
186         return new GlxDrawable(visual, display, window);
187     }
188
189     Context *
190     createContext(const Visual *visual)
191     {
192         XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
193         GLXContext context = glXCreateContext(display, visinfo, NULL, True);
194         return new GlxContext(visual, display, context);
195     }
196
197     bool
198     makeCurrent(Drawable *drawable, Context *context)
199     {
200         if (!drawable || !context) {
201             return glXMakeCurrent(display, None, NULL);
202         } else {
203             GlxDrawable *glxDrawable = dynamic_cast<GlxDrawable *>(drawable);
204             GlxContext *glxContext = dynamic_cast<GlxContext *>(context);
205
206             return glXMakeCurrent(display, glxDrawable->window, glxContext->context);
207         }
208     }
209
210     bool
211     processEvents(void) {
212         while (XPending(display) > 0) {
213             XEvent event;
214             XNextEvent(display, &event);
215             // TODO
216         }
217         return true;
218     }
219 };
220
221
222 WindowSystem *createNativeWindowSystem(void) {
223     return new GlxWindowSystem();
224 }
225
226
227 } /* namespace glretrace */