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