101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2014 Jon Turney
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#include "windowsgl.h"
2501e04c3fSmrg#include "windowsgl_internal.h"
2601e04c3fSmrg#include "windowsdriconst.h"
2701e04c3fSmrg#include "wgl.h"
2801e04c3fSmrg
2901e04c3fSmrg#include <stdio.h>
3001e04c3fSmrg
3101e04c3fSmrg/*
3201e04c3fSmrg * Window drawable
3301e04c3fSmrg */
3401e04c3fSmrg
3501e04c3fSmrgstatic
3601e04c3fSmrgHDC window_getdc(windowsDrawable *d)
3701e04c3fSmrg{
3801e04c3fSmrg   return GetDC(d->hWnd);
3901e04c3fSmrg}
4001e04c3fSmrg
4101e04c3fSmrgstatic
4201e04c3fSmrgvoid window_releasedc(windowsDrawable *d, HDC dc)
4301e04c3fSmrg{
4401e04c3fSmrg   ReleaseDC(d->hWnd, dc);
4501e04c3fSmrg}
4601e04c3fSmrg
4701e04c3fSmrgstatic struct windowsdrawable_callbacks window_callbacks = {
4801e04c3fSmrg   .type = WindowsDRIDrawableWindow,
4901e04c3fSmrg   .getdc = window_getdc,
5001e04c3fSmrg   .releasedc = window_releasedc
5101e04c3fSmrg};
5201e04c3fSmrg
5301e04c3fSmrg/*
5401e04c3fSmrg * Pixmap drawable
5501e04c3fSmrg */
5601e04c3fSmrg
5701e04c3fSmrgstatic
5801e04c3fSmrgHDC pixmap_getdc(windowsDrawable *d)
5901e04c3fSmrg{
6001e04c3fSmrg   return d->dibDC;
6101e04c3fSmrg}
6201e04c3fSmrg
6301e04c3fSmrgstatic
6401e04c3fSmrgvoid pixmap_releasedc(windowsDrawable *d, HDC dc)
6501e04c3fSmrg{
6601e04c3fSmrg   GdiFlush();
6701e04c3fSmrg}
6801e04c3fSmrg
6901e04c3fSmrgstatic struct windowsdrawable_callbacks pixmap_callbacks = {
7001e04c3fSmrg   .type = WindowsDRIDrawablePixmap,
7101e04c3fSmrg   .getdc = pixmap_getdc,
7201e04c3fSmrg   .releasedc = pixmap_releasedc
7301e04c3fSmrg};
7401e04c3fSmrg
7501e04c3fSmrg/*
7601e04c3fSmrg * Pbuffer drawable
7701e04c3fSmrg */
7801e04c3fSmrg
7901e04c3fSmrgstatic
8001e04c3fSmrgHDC pbuffer_getdc(windowsDrawable *d)
8101e04c3fSmrg{
8201e04c3fSmrg   return wglGetPbufferDCARB(d->hPbuffer);
8301e04c3fSmrg}
8401e04c3fSmrg
8501e04c3fSmrgstatic
8601e04c3fSmrgvoid pbuffer_releasedc(windowsDrawable *d, HDC dc)
8701e04c3fSmrg{
8801e04c3fSmrg   wglReleasePbufferDCARB(d->hPbuffer, dc);
8901e04c3fSmrg}
9001e04c3fSmrg
9101e04c3fSmrgstatic struct windowsdrawable_callbacks pbuffer_callbacks = {
9201e04c3fSmrg   .type = WindowsDRIDrawablePbuffer,
9301e04c3fSmrg   .getdc = pbuffer_getdc,
9401e04c3fSmrg   .releasedc = pbuffer_releasedc
9501e04c3fSmrg};
9601e04c3fSmrg
9701e04c3fSmrg/*
9801e04c3fSmrg *
9901e04c3fSmrg */
10001e04c3fSmrg
10101e04c3fSmrgwindowsDrawable *
10201e04c3fSmrgwindows_create_drawable(int type, void *handle)
10301e04c3fSmrg{
10401e04c3fSmrg   windowsDrawable *d;
10501e04c3fSmrg
10601e04c3fSmrg   d = calloc(1, sizeof *d);
10701e04c3fSmrg   if (d == NULL)
10801e04c3fSmrg      return NULL;
10901e04c3fSmrg
11001e04c3fSmrg   switch (type)
11101e04c3fSmrg   {
11201e04c3fSmrg   case WindowsDRIDrawableWindow:
11301e04c3fSmrg      d->hWnd = handle;
11401e04c3fSmrg      d->callbacks = &window_callbacks;
11501e04c3fSmrg      break;
11601e04c3fSmrg
11701e04c3fSmrg   case WindowsDRIDrawablePixmap:
11801e04c3fSmrg   {
11901e04c3fSmrg      BITMAPINFOHEADER *pBmpHeader;
12001e04c3fSmrg      void *pBits;
12101e04c3fSmrg
12201e04c3fSmrg      char name[MAX_PATH];
12301e04c3fSmrg
12401e04c3fSmrg      d->callbacks = &pixmap_callbacks;
12501e04c3fSmrg
12601e04c3fSmrg      // Access file mapping object by a name
1277ec681f3Smrg      snprintf(name, sizeof(name), "Local\\CYGWINX_WINDOWSDRI_%08x", (unsigned int)(uintptr_t)handle);
12801e04c3fSmrg      d->hSection = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
12901e04c3fSmrg      if (!d->hSection)
1307ec681f3Smrg         printf("OpenFileMapping failed %x\n", (int)GetLastError());
13101e04c3fSmrg
13201e04c3fSmrg      // Create a screen-compatible DC
13301e04c3fSmrg      d->dibDC = CreateCompatibleDC(NULL);
13401e04c3fSmrg
13501e04c3fSmrg      // Map the shared memory section to access the BITMAPINFOHEADER
13601e04c3fSmrg      pBmpHeader = (BITMAPINFOHEADER *)MapViewOfFile(d->hSection, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BITMAPINFOHEADER));
13701e04c3fSmrg      if (!pBmpHeader)
1387ec681f3Smrg         printf("MapViewOfFile failed %x\n", (int)GetLastError());
13901e04c3fSmrg
14001e04c3fSmrg      // Create a DIB using the file mapping
14101e04c3fSmrg      d->hDIB = CreateDIBSection(d->dibDC, (BITMAPINFO *) pBmpHeader,
14201e04c3fSmrg                                 DIB_RGB_COLORS, &pBits, d->hSection,
14301e04c3fSmrg                                 sizeof(BITMAPINFOHEADER));
14401e04c3fSmrg
14501e04c3fSmrg      // Done with the BITMAPINFOHEADER
14601e04c3fSmrg      UnmapViewOfFile(pBmpHeader);
14701e04c3fSmrg
14801e04c3fSmrg      // Select the DIB into the DC
14901e04c3fSmrg      d->hOldDIB = SelectObject(d->dibDC, d->hDIB);
15001e04c3fSmrg   }
15101e04c3fSmrg   break;
15201e04c3fSmrg
15301e04c3fSmrg   case WindowsDRIDrawablePbuffer:
15401e04c3fSmrg      d->hPbuffer = handle;
15501e04c3fSmrg      d->callbacks = &pbuffer_callbacks;
15601e04c3fSmrg      break;
15701e04c3fSmrg   }
15801e04c3fSmrg
15901e04c3fSmrg   return d;
16001e04c3fSmrg}
16101e04c3fSmrg
16201e04c3fSmrgvoid
16301e04c3fSmrgwindows_destroy_drawable(windowsDrawable *drawable)
16401e04c3fSmrg{
16501e04c3fSmrg   switch (drawable->callbacks->type)
16601e04c3fSmrg   {
16701e04c3fSmrg   case WindowsDRIDrawableWindow:
16801e04c3fSmrg      break;
16901e04c3fSmrg
17001e04c3fSmrg   case WindowsDRIDrawablePixmap:
17101e04c3fSmrg   {
17201e04c3fSmrg      // Select the default DIB into the DC
17301e04c3fSmrg      SelectObject(drawable->dibDC, drawable->hOldDIB);
17401e04c3fSmrg
17501e04c3fSmrg      // delete the screen-compatible DC
17601e04c3fSmrg      DeleteDC(drawable->dibDC);
17701e04c3fSmrg
17801e04c3fSmrg      // Delete the DIB
17901e04c3fSmrg      DeleteObject(drawable->hDIB);
18001e04c3fSmrg
18101e04c3fSmrg      // Close the file mapping object
18201e04c3fSmrg      CloseHandle(drawable->hSection);
18301e04c3fSmrg   }
18401e04c3fSmrg   break;
18501e04c3fSmrg
18601e04c3fSmrg   case WindowsDRIDrawablePbuffer:
18701e04c3fSmrg
18801e04c3fSmrg      break;
18901e04c3fSmrg   }
19001e04c3fSmrg
19101e04c3fSmrg   free(drawable);
19201e04c3fSmrg}
193