1 /*
2 * Copyright © 2014 Jon Turney
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "windowsgl.h"
25 #include "windowsgl_internal.h"
26 #include "windowsdriconst.h"
27 #include "wgl.h"
28
29 #include <stdio.h>
30
31 /*
32 * Window drawable
33 */
34
35 static
window_getdc(windowsDrawable * d)36 HDC window_getdc(windowsDrawable *d)
37 {
38 return GetDC(d->hWnd);
39 }
40
41 static
window_releasedc(windowsDrawable * d,HDC dc)42 void window_releasedc(windowsDrawable *d, HDC dc)
43 {
44 ReleaseDC(d->hWnd, dc);
45 }
46
47 static struct windowsdrawable_callbacks window_callbacks = {
48 .type = WindowsDRIDrawableWindow,
49 .getdc = window_getdc,
50 .releasedc = window_releasedc
51 };
52
53 /*
54 * Pixmap drawable
55 */
56
57 static
pixmap_getdc(windowsDrawable * d)58 HDC pixmap_getdc(windowsDrawable *d)
59 {
60 return d->dibDC;
61 }
62
63 static
pixmap_releasedc(windowsDrawable * d,HDC dc)64 void pixmap_releasedc(windowsDrawable *d, HDC dc)
65 {
66 GdiFlush();
67 }
68
69 static struct windowsdrawable_callbacks pixmap_callbacks = {
70 .type = WindowsDRIDrawablePixmap,
71 .getdc = pixmap_getdc,
72 .releasedc = pixmap_releasedc
73 };
74
75 /*
76 * Pbuffer drawable
77 */
78
79 static
pbuffer_getdc(windowsDrawable * d)80 HDC pbuffer_getdc(windowsDrawable *d)
81 {
82 return wglGetPbufferDCARB(d->hPbuffer);
83 }
84
85 static
pbuffer_releasedc(windowsDrawable * d,HDC dc)86 void pbuffer_releasedc(windowsDrawable *d, HDC dc)
87 {
88 wglReleasePbufferDCARB(d->hPbuffer, dc);
89 }
90
91 static struct windowsdrawable_callbacks pbuffer_callbacks = {
92 .type = WindowsDRIDrawablePbuffer,
93 .getdc = pbuffer_getdc,
94 .releasedc = pbuffer_releasedc
95 };
96
97 /*
98 *
99 */
100
101 windowsDrawable *
windows_create_drawable(int type,void * handle)102 windows_create_drawable(int type, void *handle)
103 {
104 windowsDrawable *d;
105
106 d = calloc(1, sizeof *d);
107 if (d == NULL)
108 return NULL;
109
110 switch (type)
111 {
112 case WindowsDRIDrawableWindow:
113 d->hWnd = handle;
114 d->callbacks = &window_callbacks;
115 break;
116
117 case WindowsDRIDrawablePixmap:
118 {
119 BITMAPINFOHEADER *pBmpHeader;
120 void *pBits;
121
122 char name[MAX_PATH];
123
124 d->callbacks = &pixmap_callbacks;
125
126 // Access file mapping object by a name
127 snprintf(name, sizeof(name), "Local\\CYGWINX_WINDOWSDRI_%08lx", (uintptr_t)handle);
128 d->hSection = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
129 if (!d->hSection)
130 printf("OpenFileMapping failed %x\n", GetLastError());
131
132 // Create a screen-compatible DC
133 d->dibDC = CreateCompatibleDC(NULL);
134
135 // Map the shared memory section to access the BITMAPINFOHEADER
136 pBmpHeader = (BITMAPINFOHEADER *)MapViewOfFile(d->hSection, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BITMAPINFOHEADER));
137 if (!pBmpHeader)
138 printf("MapViewOfFile failed %x\n", GetLastError());
139
140 // Create a DIB using the file mapping
141 d->hDIB = CreateDIBSection(d->dibDC, (BITMAPINFO *) pBmpHeader,
142 DIB_RGB_COLORS, &pBits, d->hSection,
143 sizeof(BITMAPINFOHEADER));
144
145 // Done with the BITMAPINFOHEADER
146 UnmapViewOfFile(pBmpHeader);
147
148 // Select the DIB into the DC
149 d->hOldDIB = SelectObject(d->dibDC, d->hDIB);
150 }
151 break;
152
153 case WindowsDRIDrawablePbuffer:
154 d->hPbuffer = handle;
155 d->callbacks = &pbuffer_callbacks;
156 break;
157 }
158
159 return d;
160 }
161
162 void
windows_destroy_drawable(windowsDrawable * drawable)163 windows_destroy_drawable(windowsDrawable *drawable)
164 {
165 switch (drawable->callbacks->type)
166 {
167 case WindowsDRIDrawableWindow:
168 break;
169
170 case WindowsDRIDrawablePixmap:
171 {
172 // Select the default DIB into the DC
173 SelectObject(drawable->dibDC, drawable->hOldDIB);
174
175 // delete the screen-compatible DC
176 DeleteDC(drawable->dibDC);
177
178 // Delete the DIB
179 DeleteObject(drawable->hDIB);
180
181 // Close the file mapping object
182 CloseHandle(drawable->hSection);
183 }
184 break;
185
186 case WindowsDRIDrawablePbuffer:
187
188 break;
189 }
190
191 free(drawable);
192 }
193