Home | History | Annotate | Download | only in windows
      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