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