Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/libfreerdp/gdi/dc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * GDI Device Context Functions
4
 *
5
 * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
7
 * Copyright 2016 Thincast Technologies GmbH
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
/* Device Context Functions: http://msdn.microsoft.com/en-us/library/dd183554 */
23
24
#include <freerdp/config.h>
25
26
#include <stdio.h>
27
#include <stdlib.h>
28
29
#include <freerdp/freerdp.h>
30
#include <freerdp/gdi/gdi.h>
31
32
#include <freerdp/gdi/region.h>
33
34
#include <freerdp/gdi/dc.h>
35
36
/**
37
 * @brief Get the current device context (a new one is created each time).
38
 * msdn{dd144871}
39
 *
40
 * @return current device context
41
 */
42
43
HGDI_DC gdi_GetDC(void)
44
0
{
45
0
  HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
46
47
0
  if (!hDC)
48
0
    return NULL;
49
50
0
  hDC->format = PIXEL_FORMAT_XRGB32;
51
0
  hDC->drawMode = GDI_R2_BLACK;
52
0
  hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0);
53
54
0
  if (!hDC->clip)
55
0
  {
56
0
    free(hDC);
57
0
    return NULL;
58
0
  }
59
60
0
  hDC->clip->null = TRUE;
61
0
  hDC->hwnd = NULL;
62
0
  return hDC;
63
0
}
64
65
/**
66
 * @brief Create a device context.
67
 * msdn{dd144871}
68
 *
69
 * @return new device context
70
 */
71
72
HGDI_DC gdi_CreateDC(UINT32 format)
73
0
{
74
0
  HGDI_DC hDC = NULL;
75
76
0
  if (!(hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC))))
77
0
    return NULL;
78
79
0
  hDC->drawMode = GDI_R2_BLACK;
80
81
0
  if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
82
0
    goto fail;
83
84
0
  hDC->clip->null = TRUE;
85
0
  hDC->hwnd = NULL;
86
0
  hDC->format = format;
87
88
0
  if (!(hDC->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND))))
89
0
    goto fail;
90
91
0
  if (!(hDC->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0)))
92
0
    goto fail;
93
94
0
  hDC->hwnd->invalid->null = TRUE;
95
0
  hDC->hwnd->count = 32;
96
97
0
  if (!(hDC->hwnd->cinvalid = (GDI_RGN*)calloc(hDC->hwnd->count, sizeof(GDI_RGN))))
98
0
    goto fail;
99
100
0
  hDC->hwnd->ninvalid = 0;
101
0
  return hDC;
102
0
fail:
103
0
  gdi_DeleteDC(hDC);
104
0
  return NULL;
105
0
}
106
107
/**
108
 * @brief Create a new device context compatible with the given device context.
109
 * msdn{dd183489}
110
 * @param hdc device context
111
 * @return new compatible device context
112
 */
113
114
HGDI_DC gdi_CreateCompatibleDC(HGDI_DC hdc)
115
0
{
116
0
  HGDI_DC hDC = (HGDI_DC)calloc(1, sizeof(GDI_DC));
117
118
0
  if (!hDC)
119
0
    return NULL;
120
121
0
  if (!(hDC->clip = gdi_CreateRectRgn(0, 0, 0, 0)))
122
0
  {
123
0
    free(hDC);
124
0
    return NULL;
125
0
  }
126
127
0
  hDC->clip->null = TRUE;
128
0
  hDC->format = hdc->format;
129
0
  hDC->drawMode = hdc->drawMode;
130
0
  hDC->hwnd = NULL;
131
0
  return hDC;
132
0
}
133
134
/**
135
 * @brief Select a GDI object in the current device context.
136
 * msdn{dd162957}
137
 *
138
 * @param hdc device context
139
 * @param hgdiobject new selected GDI object
140
 * @return previous selected GDI object
141
 */
142
143
HGDIOBJECT gdi_SelectObject(HGDI_DC hdc, HGDIOBJECT hgdiobject)
144
0
{
145
0
  HGDIOBJECT previousSelectedObject = hdc->selectedObject;
146
147
0
  if (hgdiobject == NULL)
148
0
    return NULL;
149
150
0
  if (hgdiobject->objectType == GDIOBJECT_BITMAP)
151
0
  {
152
0
    hdc->selectedObject = hgdiobject;
153
0
  }
154
0
  else if (hgdiobject->objectType == GDIOBJECT_PEN)
155
0
  {
156
0
    previousSelectedObject = (HGDIOBJECT)hdc->pen;
157
0
    hdc->pen = (HGDI_PEN)hgdiobject;
158
0
  }
159
0
  else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
160
0
  {
161
0
    previousSelectedObject = (HGDIOBJECT)hdc->brush;
162
0
    hdc->brush = (HGDI_BRUSH)hgdiobject;
163
0
  }
164
0
  else if (hgdiobject->objectType == GDIOBJECT_REGION)
165
0
  {
166
0
    hdc->selectedObject = hgdiobject;
167
0
    previousSelectedObject = (HGDIOBJECT)COMPLEXREGION;
168
0
  }
169
0
  else if (hgdiobject->objectType == GDIOBJECT_RECT)
170
0
  {
171
0
    hdc->selectedObject = hgdiobject;
172
0
    previousSelectedObject = (HGDIOBJECT)SIMPLEREGION;
173
0
  }
174
0
  else
175
0
  {
176
    /* Unknown GDI Object Type */
177
0
    return NULL;
178
0
  }
179
180
0
  return previousSelectedObject;
181
0
}
182
183
/**
184
 * @brief Delete a GDI object.
185
 * msdn{dd183539}
186
 * @param hgdiobject GDI object
187
 * @return nonzero if successful, 0 otherwise
188
 */
189
190
BOOL gdi_DeleteObject(HGDIOBJECT hgdiobject)
191
0
{
192
0
  if (!hgdiobject)
193
0
    return FALSE;
194
195
0
  if (hgdiobject->objectType == GDIOBJECT_BITMAP)
196
0
  {
197
0
    HGDI_BITMAP hBitmap = (HGDI_BITMAP)hgdiobject;
198
199
0
    if (hBitmap->data && hBitmap->free)
200
0
    {
201
0
      hBitmap->free(hBitmap->data);
202
0
      hBitmap->data = NULL;
203
0
    }
204
205
0
    free(hBitmap);
206
0
  }
207
0
  else if (hgdiobject->objectType == GDIOBJECT_PEN)
208
0
  {
209
0
    HGDI_PEN hPen = (HGDI_PEN)hgdiobject;
210
0
    free(hPen);
211
0
  }
212
0
  else if (hgdiobject->objectType == GDIOBJECT_BRUSH)
213
0
  {
214
0
    HGDI_BRUSH hBrush = (HGDI_BRUSH)hgdiobject;
215
0
    free(hBrush);
216
0
  }
217
0
  else if (hgdiobject->objectType == GDIOBJECT_REGION)
218
0
  {
219
0
    free(hgdiobject);
220
0
  }
221
0
  else if (hgdiobject->objectType == GDIOBJECT_RECT)
222
0
  {
223
0
    free(hgdiobject);
224
0
  }
225
0
  else
226
0
  {
227
    /* Unknown GDI Object Type */
228
0
    free(hgdiobject);
229
0
    return FALSE;
230
0
  }
231
232
0
  return TRUE;
233
0
}
234
235
/**
236
 * @brief Delete device context.
237
 * msdn{dd183533}
238
 * @param hdc device context
239
 * @return nonzero if successful, 0 otherwise
240
 */
241
242
BOOL gdi_DeleteDC(HGDI_DC hdc)
243
0
{
244
0
  if (hdc)
245
0
  {
246
0
    if (hdc->hwnd)
247
0
    {
248
0
      free(hdc->hwnd->cinvalid);
249
0
      free(hdc->hwnd->invalid);
250
0
      free(hdc->hwnd);
251
0
    }
252
253
0
    free(hdc->clip);
254
0
    free(hdc);
255
0
  }
256
257
0
  return TRUE;
258
0
}