1 /**************************************************************************
3 * Copyright 2011 Jose Fonseca
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
28 #include "retrace.hpp"
29 #include "glretrace.hpp"
32 using namespace glretrace;
35 typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
36 typedef std::map<unsigned long long, Context *> ContextMap;
37 static DrawableMap drawable_map;
38 static DrawableMap pbuffer_map;
39 static ContextMap context_map;
42 static glws::Drawable *
43 getDrawable(unsigned long long hdc) {
48 DrawableMap::const_iterator it;
49 it = drawable_map.find(hdc);
50 if (it == drawable_map.end()) {
51 return (drawable_map[hdc] = glretrace::createDrawable());
57 static void retrace_wglCreateContext(trace::Call &call) {
58 unsigned long long orig_context = call.ret->toUIntPtr();
59 Context *context = glretrace::createContext();
60 context_map[orig_context] = context;
63 static void retrace_wglDeleteContext(trace::Call &call) {
64 unsigned long long hglrc = call.arg(0).toUIntPtr();
66 ContextMap::iterator it;
67 it = context_map.find(hglrc);
68 if (it == context_map.end()) {
74 context_map.erase(it);
77 static void retrace_wglMakeCurrent(trace::Call &call) {
78 glws::Drawable *new_drawable = getDrawable(call.arg(0).toUIntPtr());
79 Context *new_context = context_map[call.arg(1).toUIntPtr()];
81 glretrace::makeCurrent(call, new_drawable, new_context);
84 static void retrace_wglCopyContext(trace::Call &call) {
87 static void retrace_wglChoosePixelFormat(trace::Call &call) {
90 static void retrace_wglDescribePixelFormat(trace::Call &call) {
93 static void retrace_wglSetPixelFormat(trace::Call &call) {
96 static void retrace_wglSwapBuffers(trace::Call &call) {
97 glws::Drawable *drawable = getDrawable(call.arg(0).toUIntPtr());
100 if (retrace::doubleBuffer) {
102 drawable->swapBuffers();
103 } else if (currentContext) {
104 currentContext->drawable->swapBuffers();
111 static void retrace_wglShareLists(trace::Call &call) {
112 unsigned long long hglrc1 = call.arg(0).toUIntPtr();
113 unsigned long long hglrc2 = call.arg(1).toUIntPtr();
115 Context *share_context = context_map[hglrc1];
116 Context *old_context = context_map[hglrc2];
118 Context *new_context = glretrace::createContext(share_context);
120 if (currentContext == old_context) {
121 glretrace::makeCurrent(call, currentContext->drawable, new_context);
124 context_map[hglrc2] = new_context;
130 static void retrace_wglCreateLayerContext(trace::Call &call) {
131 retrace_wglCreateContext(call);
134 static void retrace_wglDescribeLayerPlane(trace::Call &call) {
137 static void retrace_wglSetLayerPaletteEntries(trace::Call &call) {
140 static void retrace_wglRealizeLayerPalette(trace::Call &call) {
143 static void retrace_wglSwapLayerBuffers(trace::Call &call) {
144 retrace_wglSwapBuffers(call);
147 static void retrace_wglUseFontBitmapsA(trace::Call &call) {
150 static void retrace_wglUseFontBitmapsW(trace::Call &call) {
153 static void retrace_wglSwapMultipleBuffers(trace::Call &call) {
156 static void retrace_wglUseFontOutlinesA(trace::Call &call) {
159 static void retrace_wglUseFontOutlinesW(trace::Call &call) {
162 static void retrace_wglCreateBufferRegionARB(trace::Call &call) {
165 static void retrace_wglDeleteBufferRegionARB(trace::Call &call) {
168 static void retrace_wglSaveBufferRegionARB(trace::Call &call) {
171 static void retrace_wglRestoreBufferRegionARB(trace::Call &call) {
174 static void retrace_wglChoosePixelFormatARB(trace::Call &call) {
177 static void retrace_wglMakeContextCurrentARB(trace::Call &call) {
180 static void retrace_wglCreatePbufferARB(trace::Call &call) {
181 int iWidth = call.arg(2).toUInt();
182 int iHeight = call.arg(3).toUInt();
184 unsigned long long orig_pbuffer = call.ret->toUIntPtr();
185 glws::Drawable *drawable = glretrace::createPbuffer(iWidth, iHeight);
187 pbuffer_map[orig_pbuffer] = drawable;
190 static void retrace_wglGetPbufferDCARB(trace::Call &call) {
191 glws::Drawable *pbuffer = pbuffer_map[call.arg(0).toUIntPtr()];
193 unsigned long long orig_hdc = call.ret->toUIntPtr();
195 drawable_map[orig_hdc] = pbuffer;
198 static void retrace_wglReleasePbufferDCARB(trace::Call &call) {
201 static void retrace_wglDestroyPbufferARB(trace::Call &call) {
204 static void retrace_wglQueryPbufferARB(trace::Call &call) {
207 static void retrace_wglBindTexImageARB(trace::Call &call) {
210 static void retrace_wglReleaseTexImageARB(trace::Call &call) {
213 static void retrace_wglSetPbufferAttribARB(trace::Call &call) {
216 static void retrace_wglCreateContextAttribsARB(trace::Call &call) {
217 unsigned long long orig_context = call.ret->toUIntPtr();
218 Context *share_context = NULL;
220 if (call.arg(1).toPointer()) {
221 share_context = context_map[call.arg(1).toUIntPtr()];
224 Context *context = glretrace::createContext(share_context);
225 context_map[orig_context] = context;
228 static void retrace_wglMakeContextCurrentEXT(trace::Call &call) {
231 static void retrace_wglChoosePixelFormatEXT(trace::Call &call) {
234 static void retrace_wglSwapIntervalEXT(trace::Call &call) {
237 static void retrace_wglAllocateMemoryNV(trace::Call &call) {
240 static void retrace_wglFreeMemoryNV(trace::Call &call) {
243 static void retrace_glAddSwapHintRectWIN(trace::Call &call) {
246 static void retrace_wglGetProcAddress(trace::Call &call) {
249 const retrace::Entry glretrace::wgl_callbacks[] = {
250 {"glAddSwapHintRectWIN", &retrace_glAddSwapHintRectWIN},
251 {"wglAllocateMemoryNV", &retrace_wglAllocateMemoryNV},
252 {"wglBindTexImageARB", &retrace_wglBindTexImageARB},
253 {"wglChoosePixelFormat", &retrace_wglChoosePixelFormat},
254 {"wglChoosePixelFormatARB", &retrace_wglChoosePixelFormatARB},
255 {"wglChoosePixelFormatEXT", &retrace_wglChoosePixelFormatEXT},
256 {"wglCopyContext", &retrace_wglCopyContext},
257 {"wglCreateBufferRegionARB", &retrace_wglCreateBufferRegionARB},
258 {"wglCreateContext", &retrace_wglCreateContext},
259 {"wglCreateContextAttribsARB", &retrace_wglCreateContextAttribsARB},
260 {"wglCreateLayerContext", &retrace_wglCreateLayerContext},
261 {"wglCreatePbufferARB", &retrace_wglCreatePbufferARB},
262 {"wglDeleteBufferRegionARB", &retrace_wglDeleteBufferRegionARB},
263 {"wglDeleteContext", &retrace_wglDeleteContext},
264 {"wglDescribeLayerPlane", &retrace_wglDescribeLayerPlane},
265 {"wglDescribePixelFormat", &retrace_wglDescribePixelFormat},
266 {"wglDestroyPbufferARB", &retrace_wglDestroyPbufferARB},
267 {"wglFreeMemoryNV", &retrace_wglFreeMemoryNV},
268 {"wglGetCurrentContext", &retrace::ignore},
269 {"wglGetCurrentDC", &retrace::ignore},
270 {"wglGetCurrentReadDCARB", &retrace::ignore},
271 {"wglGetCurrentReadDCEXT", &retrace::ignore},
272 {"wglGetDefaultProcAddress", &retrace::ignore},
273 {"wglGetExtensionsStringARB", &retrace::ignore},
274 {"wglGetExtensionsStringEXT", &retrace::ignore},
275 {"wglGetLayerPaletteEntries", &retrace::ignore},
276 {"wglGetPbufferDCARB", &retrace_wglGetPbufferDCARB},
277 {"wglGetPixelFormat", &retrace::ignore},
278 {"wglGetPixelFormatAttribfvARB", &retrace::ignore},
279 {"wglGetPixelFormatAttribfvEXT", &retrace::ignore},
280 {"wglGetPixelFormatAttribivARB", &retrace::ignore},
281 {"wglGetPixelFormatAttribivEXT", &retrace::ignore},
282 {"wglGetProcAddress", &retrace_wglGetProcAddress},
283 {"wglGetSwapIntervalEXT", &retrace::ignore},
284 {"wglMakeContextCurrentARB", &retrace_wglMakeContextCurrentARB},
285 {"wglMakeContextCurrentEXT", &retrace_wglMakeContextCurrentEXT},
286 {"wglMakeCurrent", &retrace_wglMakeCurrent},
287 {"wglQueryPbufferARB", &retrace_wglQueryPbufferARB},
288 {"wglRealizeLayerPalette", &retrace_wglRealizeLayerPalette},
289 {"wglReleasePbufferDCARB", &retrace_wglReleasePbufferDCARB},
290 {"wglReleaseTexImageARB", &retrace_wglReleaseTexImageARB},
291 {"wglRestoreBufferRegionARB", &retrace_wglRestoreBufferRegionARB},
292 {"wglSaveBufferRegionARB", &retrace_wglSaveBufferRegionARB},
293 {"wglSetLayerPaletteEntries", &retrace_wglSetLayerPaletteEntries},
294 {"wglSetPbufferAttribARB", &retrace_wglSetPbufferAttribARB},
295 {"wglSetPixelFormat", &retrace_wglSetPixelFormat},
296 {"wglShareLists", &retrace_wglShareLists},
297 {"wglSwapBuffers", &retrace_wglSwapBuffers},
298 {"wglSwapIntervalEXT", &retrace_wglSwapIntervalEXT},
299 {"wglSwapLayerBuffers", &retrace_wglSwapLayerBuffers},
300 {"wglSwapMultipleBuffers", &retrace_wglSwapMultipleBuffers},
301 {"wglUseFontBitmapsA", &retrace_wglUseFontBitmapsA},
302 {"wglUseFontBitmapsW", &retrace_wglUseFontBitmapsW},
303 {"wglUseFontOutlinesA", &retrace_wglUseFontOutlinesA},
304 {"wglUseFontOutlinesW", &retrace_wglUseFontOutlinesW},