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