Blame libfreerdp/gdi/dc.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * GDI Device Context Functions
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
Packit 1fb8d4
 * Copyright 2016 Thincast Technologies GmbH
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
/* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <stdlib.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/freerdp.h>
Packit 1fb8d4
#include <freerdp/gdi/gdi.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/gdi/region.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/gdi/dc.h>
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Get the current device context (a new one is created each time).\n
Packit 1fb8d4
 * @msdn{dd144871}
Packit 1fb8d4
 * @return current device context
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
HGDI_DC gdi_GetDC(void)
Packit 1fb8d4
{
Packit Service 5a9772
	HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
Packit 1fb8d4
Packit 1fb8d4
	if (!hDC)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	hDC->format = PIXEL_FORMAT_XRGB32;
Packit 1fb8d4
	hDC->drawMode = GDI_R2_BLACK;
Packit 1fb8d4
	hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0);
Packit 1fb8d4
Packit 1fb8d4
	if (!hDC->clip)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(hDC);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	hDC->clip->null = TRUE;
Packit 1fb8d4
	hDC->hwnd = NULL;
Packit 1fb8d4
	return hDC;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Create a device context.\n
Packit 1fb8d4
 * @msdn{dd144871}
Packit 1fb8d4
 * @return new device context
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
HGDI_DC gdi_CreateDC(UINT32 format)
Packit 1fb8d4
{
Packit 1fb8d4
	HGDI_DC hDC;
Packit 1fb8d4
Packit Service 5a9772
	if (!(hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC))))
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	hDC->drawMode = GDI_R2_BLACK;
Packit 1fb8d4
Packit 1fb8d4
	if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	hDC->clip->null = TRUE;
Packit 1fb8d4
	hDC->hwnd = NULL;
Packit 1fb8d4
	hDC->format = format;
Packit 1fb8d4
Packit Service 5a9772
	if (!(hDC->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND))))
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	if (!(hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0)))
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	hDC->hwnd->invalid->null = TRUE;
Packit 1fb8d4
	hDC->hwnd->count = 32;
Packit 1fb8d4
Packit Service 5a9772
	if (!(hDC->hwnd->cinvalid = (HGDI_RGN)calloc(hDC->hwnd->count, sizeof(GDI_RGN))))
Packit 1fb8d4
		goto fail;
Packit 1fb8d4
Packit 1fb8d4
	hDC->hwnd->ninvalid = 0;
Packit 1fb8d4
	return hDC;
Packit 1fb8d4
fail:
Packit 1fb8d4
	gdi_DeleteDC(hDC);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Create a new device context compatible with the given device context.\n
Packit 1fb8d4
 * @msdn{dd183489}
Packit 1fb8d4
 * @param hdc device context
Packit 1fb8d4
 * @return new compatible device context
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc)
Packit 1fb8d4
{
Packit Service 5a9772
	HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
Packit 1fb8d4
Packit 1fb8d4
	if (!hDC)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
Packit 1fb8d4
	{
Packit 1fb8d4
		free(hDC);
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	hDC->clip->null = TRUE;
Packit 1fb8d4
	hDC->format = hdc->format;
Packit 1fb8d4
	hDC->drawMode = hdc->drawMode;
Packit 1fb8d4
	hDC->hwnd = NULL;
Packit 1fb8d4
	return hDC;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Select a GDI object in the current device context.\n
Packit 1fb8d4
 * @msdn{dd162957}
Packit 1fb8d4
 * @param hdc device context
Packit 1fb8d4
 * @param hgdiobject new selected GDI object
Packit 1fb8d4
 * @return previous selected GDI object
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject)
Packit 1fb8d4
{
Packit 1fb8d4
	HGDIOBJECT previousSelectedObject = hdc->selectedObject;
Packit 1fb8d4
Packit 1fb8d4
	if (hgdiobject == NULL)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (hgdiobject->objectType == GDIOBJECT_BITMAP)
Packit 1fb8d4
	{
Packit 1fb8d4
		hdc->selectedObject = hgdiobject;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_PEN)
Packit 1fb8d4
	{
Packit Service 5a9772
		previousSelectedObject = (HGDIOBJECT)hdc->pen;
Packit Service 5a9772
		hdc->pen = (HGDI_PEN)hgdiobject;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
Packit 1fb8d4
	{
Packit Service 5a9772
		previousSelectedObject = (HGDIOBJECT)hdc->brush;
Packit Service 5a9772
		hdc->brush = (HGDI_BRUSH)hgdiobject;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_REGION)
Packit 1fb8d4
	{
Packit 1fb8d4
		hdc->selectedObject = hgdiobject;
Packit Service 5a9772
		previousSelectedObject = (HGDIOBJECT)COMPLEXREGION;
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_RECT)
Packit 1fb8d4
	{
Packit 1fb8d4
		hdc->selectedObject = hgdiobject;
Packit Service 5a9772
		previousSelectedObject = (HGDIOBJECT)SIMPLEREGION;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		/* Unknown GDI Object Type */
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return previousSelectedObject;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Delete a GDI object.\n
Packit 1fb8d4
 * @msdn{dd183539}
Packit 1fb8d4
 * @param hgdiobject GDI object
Packit 1fb8d4
 * @return nonzero if successful, 0 otherwise
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
BOOL gdi_DeleteObject(HGDIOBJECT hgdiobject)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!hgdiobject)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (hgdiobject->objectType == GDIOBJECT_BITMAP)
Packit 1fb8d4
	{
Packit Service 5a9772
		HGDI_BITMAP hBitmap = (HGDI_BITMAP)hgdiobject;
Packit 1fb8d4
Packit 1fb8d4
		if (hBitmap->data && hBitmap->free)
Packit 1fb8d4
		{
Packit 1fb8d4
			hBitmap->free(hBitmap->data);
Packit 1fb8d4
			hBitmap->data = NULL;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		free(hBitmap);
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_PEN)
Packit 1fb8d4
	{
Packit Service 5a9772
		HGDI_PEN hPen = (HGDI_PEN)hgdiobject;
Packit 1fb8d4
		free(hPen);
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
Packit 1fb8d4
	{
Packit Service 5a9772
		HGDI_BRUSH hBrush = (HGDI_BRUSH)hgdiobject;
Packit 1fb8d4
		free(hBrush);
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_REGION)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(hgdiobject);
Packit 1fb8d4
	}
Packit 1fb8d4
	else if (hgdiobject->objectType == GDIOBJECT_RECT)
Packit 1fb8d4
	{
Packit 1fb8d4
		free(hgdiobject);
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		/* Unknown GDI Object Type */
Packit 1fb8d4
		free(hgdiobject);
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Delete device context.\n
Packit 1fb8d4
 * @msdn{dd183533}
Packit 1fb8d4
 * @param hdc device context
Packit 1fb8d4
 * @return nonzero if successful, 0 otherwise
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
BOOL gdi_DeleteDC(HGDI_DC hdc)
Packit 1fb8d4
{
Packit 1fb8d4
	if (hdc)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (hdc->hwnd)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(hdc->hwnd->cinvalid);
Packit 1fb8d4
			free(hdc->hwnd->invalid);
Packit 1fb8d4
			free(hdc->hwnd);
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		free(hdc->clip);
Packit 1fb8d4
		free(hdc);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}