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 36 HDC window_getdc(windowsDrawable *d) 37 { 38 return GetDC(d->hWnd); 39 } 40 41 static 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 58 HDC pixmap_getdc(windowsDrawable *d) 59 { 60 return d->dibDC; 61 } 62 63 static 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 80 HDC pbuffer_getdc(windowsDrawable *d) 81 { 82 return wglGetPbufferDCARB(d->hPbuffer); 83 } 84 85 static 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 * 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 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