| /* |
| * Copyright © 2014 Jon Turney |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| * IN THE SOFTWARE. |
| */ |
| |
| #include "windowsgl.h" |
| #include "windowsgl_internal.h" |
| #include "windowsdriconst.h" |
| #include "wgl.h" |
| |
| #include <stdio.h> |
| |
| /* |
| * Window drawable |
| */ |
| |
| static |
| HDC window_getdc(windowsDrawable *d) |
| { |
| return GetDC(d->hWnd); |
| } |
| |
| static |
| void window_releasedc(windowsDrawable *d, HDC dc) |
| { |
| ReleaseDC(d->hWnd, dc); |
| } |
| |
| static struct windowsdrawable_callbacks window_callbacks = { |
| .type = WindowsDRIDrawableWindow, |
| .getdc = window_getdc, |
| .releasedc = window_releasedc |
| }; |
| |
| /* |
| * Pixmap drawable |
| */ |
| |
| static |
| HDC pixmap_getdc(windowsDrawable *d) |
| { |
| return d->dibDC; |
| } |
| |
| static |
| void pixmap_releasedc(windowsDrawable *d, HDC dc) |
| { |
| GdiFlush(); |
| } |
| |
| static struct windowsdrawable_callbacks pixmap_callbacks = { |
| .type = WindowsDRIDrawablePixmap, |
| .getdc = pixmap_getdc, |
| .releasedc = pixmap_releasedc |
| }; |
| |
| /* |
| * Pbuffer drawable |
| */ |
| |
| static |
| HDC pbuffer_getdc(windowsDrawable *d) |
| { |
| return wglGetPbufferDCARB(d->hPbuffer); |
| } |
| |
| static |
| void pbuffer_releasedc(windowsDrawable *d, HDC dc) |
| { |
| wglReleasePbufferDCARB(d->hPbuffer, dc); |
| } |
| |
| static struct windowsdrawable_callbacks pbuffer_callbacks = { |
| .type = WindowsDRIDrawablePbuffer, |
| .getdc = pbuffer_getdc, |
| .releasedc = pbuffer_releasedc |
| }; |
| |
| /* |
| * |
| */ |
| |
| windowsDrawable * |
| windows_create_drawable(int type, void *handle) |
| { |
| windowsDrawable *d; |
| |
| d = calloc(1, sizeof *d); |
| if (d == NULL) |
| return NULL; |
| |
| switch (type) |
| { |
| case WindowsDRIDrawableWindow: |
| d->hWnd = handle; |
| d->callbacks = &window_callbacks; |
| break; |
| |
| case WindowsDRIDrawablePixmap: |
| { |
| BITMAPINFOHEADER *pBmpHeader; |
| void *pBits; |
| |
| char name[MAX_PATH]; |
| |
| d->callbacks = &pixmap_callbacks; |
| |
| // Access file mapping object by a name |
| snprintf(name, sizeof(name), "Local\\CYGWINX_WINDOWSDRI_%08x", (unsigned int)(uintptr_t)handle); |
| d->hSection = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name); |
| if (!d->hSection) |
| printf("OpenFileMapping failed %x\n", (int)GetLastError()); |
| |
| // Create a screen-compatible DC |
| d->dibDC = CreateCompatibleDC(NULL); |
| |
| // Map the shared memory section to access the BITMAPINFOHEADER |
| pBmpHeader = (BITMAPINFOHEADER *)MapViewOfFile(d->hSection, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BITMAPINFOHEADER)); |
| if (!pBmpHeader) |
| printf("MapViewOfFile failed %x\n", (int)GetLastError()); |
| |
| // Create a DIB using the file mapping |
| d->hDIB = CreateDIBSection(d->dibDC, (BITMAPINFO *) pBmpHeader, |
| DIB_RGB_COLORS, &pBits, d->hSection, |
| sizeof(BITMAPINFOHEADER)); |
| |
| // Done with the BITMAPINFOHEADER |
| UnmapViewOfFile(pBmpHeader); |
| |
| // Select the DIB into the DC |
| d->hOldDIB = SelectObject(d->dibDC, d->hDIB); |
| } |
| break; |
| |
| case WindowsDRIDrawablePbuffer: |
| d->hPbuffer = handle; |
| d->callbacks = &pbuffer_callbacks; |
| break; |
| } |
| |
| return d; |
| } |
| |
| void |
| windows_destroy_drawable(windowsDrawable *drawable) |
| { |
| switch (drawable->callbacks->type) |
| { |
| case WindowsDRIDrawableWindow: |
| break; |
| |
| case WindowsDRIDrawablePixmap: |
| { |
| // Select the default DIB into the DC |
| SelectObject(drawable->dibDC, drawable->hOldDIB); |
| |
| // delete the screen-compatible DC |
| DeleteDC(drawable->dibDC); |
| |
| // Delete the DIB |
| DeleteObject(drawable->hDIB); |
| |
| // Close the file mapping object |
| CloseHandle(drawable->hSection); |
| } |
| break; |
| |
| case WindowsDRIDrawablePbuffer: |
| |
| break; |
| } |
| |
| free(drawable); |
| } |