]> git.cworth.org Git - apitrace/blob - glws_wgl.cpp
Implement glws for WGL.
[apitrace] / glws_wgl.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 WglDrawable : public Drawable
34 {
35 public:
36     DWORD dwExStyle;
37     DWORD dwStyle;
38     HWND hWnd;
39     HDC hDC;
40     PIXELFORMATDESCRIPTOR pfd;
41     int iPixelFormat;
42
43     WglDrawable(const Visual *vis) :
44         Drawable(vis)
45     {
46         static bool first = TRUE;
47         RECT rect;
48
49         if (first) {
50             WNDCLASS wc;
51             memset(&wc, 0, sizeof wc);
52             wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
53             wc.hCursor = LoadCursor(NULL, IDC_ARROW);
54             wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
55             wc.lpfnWndProc = DefWindowProc;
56             wc.lpszClassName = "glretrace";
57             wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
58             RegisterClass(&wc);
59             first = FALSE;
60         }
61
62         dwExStyle = 0;
63         dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | WS_OVERLAPPEDWINDOW;
64
65         int x = 0, y = 0, width = 256, height = 256;
66
67         rect.left = x;
68         rect.top = y;
69         rect.right = rect.left + width;
70         rect.bottom = rect.top + height;
71
72         AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
73
74         hWnd = CreateWindowEx(dwExStyle,
75                               "glretrace", /* wc.lpszClassName */
76                               NULL,
77                               dwStyle,
78                               CW_USEDEFAULT, /* x */
79                               CW_USEDEFAULT, /* y */
80                               rect.right - rect.left, /* width */
81                               rect.bottom - rect.top, /* height */
82                               NULL,
83                               NULL,
84                               NULL,
85                               NULL);
86         hDC = GetDC(hWnd);
87    
88         memset(&pfd, 0, sizeof pfd);
89         pfd.cColorBits = 3;
90         pfd.cRedBits = 1;
91         pfd.cGreenBits = 1;
92         pfd.cBlueBits = 1;
93         pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
94         pfd.iLayerType = PFD_MAIN_PLANE;
95         pfd.iPixelType = PFD_TYPE_RGBA;
96         pfd.nSize = sizeof(pfd);
97         pfd.nVersion = 1;
98
99         if (visual->doubleBuffer) {
100            pfd.dwFlags |= PFD_DOUBLEBUFFER;
101         }
102
103         iPixelFormat = ChoosePixelFormat(hDC, &pfd);
104
105         SetPixelFormat(hDC, iPixelFormat, &pfd);
106     }
107
108     ~WglDrawable() {
109         ReleaseDC(hWnd, hDC);
110         DestroyWindow(hWnd);
111     }
112     
113     void
114     resize(unsigned w, unsigned h) {
115         Drawable::resize(w, h);
116         RECT rClient, rWindow;
117         GetClientRect(hWnd, &rClient);
118         GetWindowRect(hWnd, &rWindow);
119         w += (rWindow.right  - rWindow.left) - rClient.right;
120         h += (rWindow.bottom - rWindow.top)  - rClient.bottom;
121         MoveWindow(hWnd, rWindow.left, rWindow.top, w, h, TRUE);
122     }
123
124     void swapBuffers(void) {
125         SwapBuffers(hDC);
126     }
127 };
128
129
130 class WglContext : public Context
131 {
132 public:
133     HGLRC hglrc;
134     
135     WglContext(const Visual *vis) :
136         Context(vis),
137         hglrc(0)
138     {}
139
140     ~WglContext() {
141         if (hglrc) {
142             wglDeleteContext(hglrc);
143         }
144     }
145 };
146
147
148 class WglWindowSystem : public WindowSystem
149 {
150 public:
151     Visual *
152     createVisual(bool doubleBuffer) {
153         Visual *visual = new Visual();
154
155         visual->doubleBuffer = doubleBuffer;
156
157         return visual;
158     }
159     
160     Drawable *
161     createDrawable(const Visual *visual)
162     {
163         return new WglDrawable(visual);
164     }
165
166     Context *
167     createContext(const Visual *visual)
168     {
169         return new WglContext(visual);
170     }
171
172     bool
173     makeCurrent(Drawable *drawable, Context *context)
174     {
175         if (!drawable || !context) {
176             return wglMakeCurrent(NULL, NULL);
177         } else {
178             WglDrawable *wglDrawable = dynamic_cast<WglDrawable *>(drawable);
179             WglContext *wglContext = dynamic_cast<WglContext *>(context);
180
181             if (!wglContext->hglrc) {
182                 wglContext->hglrc = wglCreateContext(wglDrawable->hDC);
183                 if (!wglContext->hglrc) {
184                     return false;
185                 }
186             }
187
188             return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);
189         }
190     }
191
192     bool
193     processEvents(void) {
194         // TODO
195         return true;
196     }
197 };
198
199
200 WindowSystem *createNativeWindowSystem(void) {
201     return new WglWindowSystem();
202 }
203
204
205 } /* namespace glretrace */