/*
* 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_%08lx", (uintptr_t)handle);
d->hSection = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
if (!d->hSection)
printf("OpenFileMapping failed %x\n", 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", 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);
}