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 35static 36HDC window_getdc(windowsDrawable *d) 37{ 38 return GetDC(d->hWnd); 39} 40 41static 42void window_releasedc(windowsDrawable *d, HDC dc) 43{ 44 ReleaseDC(d->hWnd, dc); 45} 46 47static struct windowsdrawable_callbacks window_callbacks = { 48 .type = WindowsDRIDrawableWindow, 49 .getdc = window_getdc, 50 .releasedc = window_releasedc 51}; 52 53/* 54 * Pixmap drawable 55 */ 56 57static 58HDC pixmap_getdc(windowsDrawable *d) 59{ 60 return d->dibDC; 61} 62 63static 64void pixmap_releasedc(windowsDrawable *d, HDC dc) 65{ 66 GdiFlush(); 67} 68 69static struct windowsdrawable_callbacks pixmap_callbacks = { 70 .type = WindowsDRIDrawablePixmap, 71 .getdc = pixmap_getdc, 72 .releasedc = pixmap_releasedc 73}; 74 75/* 76 * Pbuffer drawable 77 */ 78 79static 80HDC pbuffer_getdc(windowsDrawable *d) 81{ 82 return wglGetPbufferDCARB(d->hPbuffer); 83} 84 85static 86void pbuffer_releasedc(windowsDrawable *d, HDC dc) 87{ 88 wglReleasePbufferDCARB(d->hPbuffer, dc); 89} 90 91static struct windowsdrawable_callbacks pbuffer_callbacks = { 92 .type = WindowsDRIDrawablePbuffer, 93 .getdc = pbuffer_getdc, 94 .releasedc = pbuffer_releasedc 95}; 96 97/* 98 * 99 */ 100 101windowsDrawable * 102windows_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_%08x", (unsigned int)(uintptr_t)handle); 128 d->hSection = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name); 129 if (!d->hSection) 130 printf("OpenFileMapping failed %x\n", (int)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", (int)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 162void 163windows_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