1 /**
2  * FreeRDP: A Remote Desktop Protocol Implementation
3  * Graphical Objects
4  *
5  * Copyright 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 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <winpr/crt.h>
25 
26 #include <freerdp/graphics.h>
27 
28 #include "graphics.h"
29 
30 /* Bitmap Class */
31 
Bitmap_Alloc(rdpContext * context)32 rdpBitmap* Bitmap_Alloc(rdpContext* context)
33 {
34 	rdpBitmap* bitmap;
35 	rdpGraphics* graphics;
36 	graphics = context->graphics;
37 	bitmap = (rdpBitmap*)calloc(1, graphics->Bitmap_Prototype->size);
38 
39 	if (bitmap)
40 	{
41 		CopyMemory(bitmap, graphics->Bitmap_Prototype, sizeof(rdpBitmap));
42 		bitmap->data = NULL;
43 	}
44 
45 	return bitmap;
46 }
47 
Bitmap_New(rdpContext * context,rdpBitmap * bitmap)48 static BOOL Bitmap_New(rdpContext* context, rdpBitmap* bitmap)
49 {
50 	if (!bitmap || !context)
51 		return FALSE;
52 
53 	*bitmap = *context->graphics->Bitmap_Prototype;
54 	return TRUE;
55 }
56 
Bitmap_Free(rdpContext * context,rdpBitmap * bitmap)57 void Bitmap_Free(rdpContext* context, rdpBitmap* bitmap)
58 {
59 	if (bitmap)
60 		bitmap->Free(context, bitmap);
61 }
62 
Bitmap_SetRectangle(rdpBitmap * bitmap,UINT16 left,UINT16 top,UINT16 right,UINT16 bottom)63 BOOL Bitmap_SetRectangle(rdpBitmap* bitmap, UINT16 left, UINT16 top, UINT16 right, UINT16 bottom)
64 {
65 	if (!bitmap)
66 		return FALSE;
67 
68 	bitmap->left = left;
69 	bitmap->top = top;
70 	bitmap->right = right;
71 	bitmap->bottom = bottom;
72 	return TRUE;
73 }
74 
Bitmap_SetDimensions(rdpBitmap * bitmap,UINT16 width,UINT16 height)75 BOOL Bitmap_SetDimensions(rdpBitmap* bitmap, UINT16 width, UINT16 height)
76 {
77 	if (!bitmap)
78 		return FALSE;
79 
80 	bitmap->right = bitmap->left + width - 1;
81 	bitmap->bottom = bitmap->top + height - 1;
82 	bitmap->width = width;
83 	bitmap->height = height;
84 	return TRUE;
85 }
86 
graphics_register_bitmap(rdpGraphics * graphics,rdpBitmap * bitmap)87 void graphics_register_bitmap(rdpGraphics* graphics, rdpBitmap* bitmap)
88 {
89 	CopyMemory(graphics->Bitmap_Prototype, bitmap, sizeof(rdpBitmap));
90 }
91 
92 /* Pointer Class */
Pointer_Alloc(rdpContext * context)93 rdpPointer* Pointer_Alloc(rdpContext* context)
94 {
95 	rdpPointer* pointer;
96 	rdpGraphics* graphics;
97 	graphics = context->graphics;
98 	pointer = (rdpPointer*)calloc(1, graphics->Pointer_Prototype->size);
99 
100 	if (pointer)
101 	{
102 		CopyMemory(pointer, graphics->Pointer_Prototype, sizeof(rdpPointer));
103 	}
104 
105 	return pointer;
106 }
107 
Pointer_New(rdpContext * context,rdpPointer * pointer)108 static BOOL Pointer_New(rdpContext* context, rdpPointer* pointer)
109 {
110 	rdpPointer* proto;
111 
112 	if (!context || !context->graphics || !context->graphics->Pointer_Prototype)
113 		return FALSE;
114 
115 	proto = context->graphics->Pointer_Prototype;
116 	*pointer = *proto;
117 	return TRUE;
118 }
119 
120 /* static method */
graphics_register_pointer(rdpGraphics * graphics,rdpPointer * pointer)121 void graphics_register_pointer(rdpGraphics* graphics, rdpPointer* pointer)
122 {
123 	CopyMemory(graphics->Pointer_Prototype, pointer, sizeof(rdpPointer));
124 }
125 
126 /* Glyph Class */
127 
Glyph_Alloc(rdpContext * context,INT32 x,INT32 y,UINT32 cx,UINT32 cy,UINT32 cb,const BYTE * aj)128 rdpGlyph* Glyph_Alloc(rdpContext* context, INT32 x, INT32 y, UINT32 cx, UINT32 cy, UINT32 cb,
129                       const BYTE* aj)
130 {
131 	rdpGlyph* glyph;
132 	rdpGraphics* graphics;
133 
134 	if (!context || !context->graphics)
135 		return NULL;
136 
137 	graphics = context->graphics;
138 
139 	if (!graphics->Glyph_Prototype)
140 		return NULL;
141 
142 	glyph = (rdpGlyph*)calloc(1, graphics->Glyph_Prototype->size);
143 
144 	if (!glyph)
145 		return NULL;
146 
147 	*glyph = *graphics->Glyph_Prototype;
148 	glyph->cb = cb;
149 	glyph->cx = cx;
150 	glyph->cy = cy;
151 	glyph->x = x;
152 	glyph->y = y;
153 	glyph->aj = malloc(glyph->cb);
154 
155 	if (!glyph->aj)
156 	{
157 		free(glyph);
158 		return NULL;
159 	}
160 
161 	CopyMemory(glyph->aj, aj, cb);
162 
163 	if (!glyph->New(context, glyph))
164 	{
165 		free(glyph->aj);
166 		free(glyph);
167 		return NULL;
168 	}
169 
170 	return glyph;
171 }
172 
graphics_register_glyph(rdpGraphics * graphics,rdpGlyph * glyph)173 void graphics_register_glyph(rdpGraphics* graphics, rdpGlyph* glyph)
174 {
175 	CopyMemory(graphics->Glyph_Prototype, glyph, sizeof(rdpGlyph));
176 }
177 
178 /* Graphics Module */
179 
graphics_new(rdpContext * context)180 rdpGraphics* graphics_new(rdpContext* context)
181 {
182 	rdpGraphics* graphics;
183 	graphics = (rdpGraphics*)calloc(1, sizeof(rdpGraphics));
184 
185 	if (graphics)
186 	{
187 		graphics->context = context;
188 		graphics->Bitmap_Prototype = (rdpBitmap*)calloc(1, sizeof(rdpBitmap));
189 
190 		if (!graphics->Bitmap_Prototype)
191 		{
192 			free(graphics);
193 			return NULL;
194 		}
195 
196 		graphics->Bitmap_Prototype->size = sizeof(rdpBitmap);
197 		graphics->Bitmap_Prototype->New = Bitmap_New;
198 		graphics->Bitmap_Prototype->Free = NULL;
199 		graphics->Pointer_Prototype = (rdpPointer*)calloc(1, sizeof(rdpPointer));
200 
201 		if (!graphics->Pointer_Prototype)
202 		{
203 			free(graphics->Bitmap_Prototype);
204 			free(graphics);
205 			return NULL;
206 		}
207 
208 		graphics->Pointer_Prototype->size = sizeof(rdpPointer);
209 		graphics->Pointer_Prototype->New = Pointer_New;
210 		graphics->Pointer_Prototype->Free = NULL;
211 		graphics->Glyph_Prototype = (rdpGlyph*)calloc(1, sizeof(rdpGlyph));
212 
213 		if (!graphics->Glyph_Prototype)
214 		{
215 			free(graphics->Pointer_Prototype);
216 			free(graphics->Bitmap_Prototype);
217 			free(graphics);
218 			return NULL;
219 		}
220 
221 		graphics->Glyph_Prototype->size = sizeof(rdpGlyph);
222 	}
223 
224 	return graphics;
225 }
226 
graphics_free(rdpGraphics * graphics)227 void graphics_free(rdpGraphics* graphics)
228 {
229 	if (graphics)
230 	{
231 		free(graphics->Bitmap_Prototype);
232 		free(graphics->Pointer_Prototype);
233 		free(graphics->Glyph_Prototype);
234 		free(graphics);
235 	}
236 }
237