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