FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
shadow_subsystem.c
1
19#include <freerdp/config.h>
20
21#include "shadow.h"
22
23#include "shadow_subsystem.h"
24
25static pfnShadowSubsystemEntry pSubsystemEntry = NULL;
26
27void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry)
28{
29 pSubsystemEntry = pEntry;
30}
31
32static int shadow_subsystem_load_entry_points(RDP_SHADOW_ENTRY_POINTS* pEntryPoints)
33{
34 WINPR_ASSERT(pEntryPoints);
35 ZeroMemory(pEntryPoints, sizeof(RDP_SHADOW_ENTRY_POINTS));
36
37 if (!pSubsystemEntry)
38 return -1;
39
40 if (pSubsystemEntry(pEntryPoints) < 0)
41 return -1;
42
43 return 1;
44}
45
46rdpShadowSubsystem* shadow_subsystem_new(void)
47{
48 RDP_SHADOW_ENTRY_POINTS ep;
49 rdpShadowSubsystem* subsystem = NULL;
50
51 shadow_subsystem_load_entry_points(&ep);
52
53 if (!ep.New)
54 return NULL;
55
56 subsystem = ep.New();
57
58 if (!subsystem)
59 return NULL;
60
61 CopyMemory(&(subsystem->ep), &ep, sizeof(RDP_SHADOW_ENTRY_POINTS));
62
63 return subsystem;
64}
65
66void shadow_subsystem_free(rdpShadowSubsystem* subsystem)
67{
68 if (subsystem && subsystem->ep.Free)
69 subsystem->ep.Free(subsystem);
70}
71
72int shadow_subsystem_init(rdpShadowSubsystem* subsystem, rdpShadowServer* server)
73{
74 int status = -1;
75
76 if (!subsystem || !subsystem->ep.Init)
77 return -1;
78
79 subsystem->server = server;
80 subsystem->selectedMonitor = server->selectedMonitor;
81
82 if (!(subsystem->MsgPipe = MessagePipe_New()))
83 goto fail;
84
85 if (!(subsystem->updateEvent = shadow_multiclient_new()))
86 goto fail;
87
88 if ((status = subsystem->ep.Init(subsystem)) >= 0)
89 return status;
90
91fail:
92 if (subsystem->MsgPipe)
93 {
94 MessagePipe_Free(subsystem->MsgPipe);
95 subsystem->MsgPipe = NULL;
96 }
97
98 if (subsystem->updateEvent)
99 {
100 shadow_multiclient_free(subsystem->updateEvent);
101 subsystem->updateEvent = NULL;
102 }
103
104 return status;
105}
106
107static void shadow_subsystem_free_queued_message(void* obj)
108{
109 wMessage* message = (wMessage*)obj;
110 if (message->Free)
111 {
112 message->Free(message);
113 message->Free = NULL;
114 }
115}
116
117void shadow_subsystem_uninit(rdpShadowSubsystem* subsystem)
118{
119 if (!subsystem)
120 return;
121
122 if (subsystem->ep.Uninit)
123 subsystem->ep.Uninit(subsystem);
124
125 if (subsystem->MsgPipe)
126 {
127 wObject* obj1 = NULL;
128 wObject* obj2 = NULL;
129 /* Release resource in messages before free */
130 obj1 = MessageQueue_Object(subsystem->MsgPipe->In);
131
132 obj1->fnObjectFree = shadow_subsystem_free_queued_message;
133 MessageQueue_Clear(subsystem->MsgPipe->In);
134
135 obj2 = MessageQueue_Object(subsystem->MsgPipe->Out);
136 obj2->fnObjectFree = shadow_subsystem_free_queued_message;
137 MessageQueue_Clear(subsystem->MsgPipe->Out);
138 MessagePipe_Free(subsystem->MsgPipe);
139 subsystem->MsgPipe = NULL;
140 }
141
142 if (subsystem->updateEvent)
143 {
144 shadow_multiclient_free(subsystem->updateEvent);
145 subsystem->updateEvent = NULL;
146 }
147}
148
149int shadow_subsystem_start(rdpShadowSubsystem* subsystem)
150{
151 int status = 0;
152
153 if (!subsystem || !subsystem->ep.Start)
154 return -1;
155
156 status = subsystem->ep.Start(subsystem);
157
158 return status;
159}
160
161int shadow_subsystem_stop(rdpShadowSubsystem* subsystem)
162{
163 int status = 0;
164
165 if (!subsystem || !subsystem->ep.Stop)
166 return -1;
167
168 status = subsystem->ep.Stop(subsystem);
169
170 return status;
171}
172
173UINT32 shadow_enum_monitors(MONITOR_DEF* monitors, UINT32 maxMonitors)
174{
175 UINT32 numMonitors = 0;
176 RDP_SHADOW_ENTRY_POINTS ep;
177
178 if (shadow_subsystem_load_entry_points(&ep) < 0)
179 return 0;
180
181 numMonitors = ep.EnumMonitors(monitors, maxMonitors);
182
183 return numMonitors;
184}
185
192#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
193int shadow_subsystem_pointer_convert_alpha_pointer_data(
194 const BYTE* WINPR_RESTRICT pixels, BOOL premultiplied, UINT32 width, UINT32 height,
195 SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* WINPR_RESTRICT pointerColor)
196{
197 return shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
198 pixels, PIXEL_FORMAT_BGRX32, premultiplied, width, height, pointerColor);
199}
200#endif
201
202int shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
203 const BYTE* pixels, UINT32 format, BOOL premultiplied, UINT32 width, UINT32 height,
205{
206 UINT32 xorStep = 0;
207 UINT32 andStep = 0;
208 UINT32 andBit = 0;
209 BYTE* andBits = NULL;
210 UINT32 andPixel = 0;
211 const size_t bpp = FreeRDPGetBytesPerPixel(format);
212
213 xorStep = (width * 3);
214 xorStep += (xorStep % 2);
215
216 andStep = ((width + 7) / 8);
217 andStep += (andStep % 2);
218
219 pointerColor->lengthXorMask = height * xorStep;
220 pointerColor->xorMaskData = (BYTE*)calloc(1, pointerColor->lengthXorMask);
221
222 if (!pointerColor->xorMaskData)
223 return -1;
224
225 pointerColor->lengthAndMask = height * andStep;
226 pointerColor->andMaskData = (BYTE*)calloc(1, pointerColor->lengthAndMask);
227
228 if (!pointerColor->andMaskData)
229 {
230 free(pointerColor->xorMaskData);
231 pointerColor->xorMaskData = NULL;
232 return -1;
233 }
234
235 for (size_t y = 0; y < height; y++)
236 {
237 const BYTE* pSrc8 = &pixels[(width * bpp) * (height - 1 - y)];
238 BYTE* pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
239
240 andBit = 0x80;
241 andBits = &(pointerColor->andMaskData[andStep * y]);
242
243 for (size_t x = 0; x < width; x++)
244 {
245 BYTE B = 0;
246 BYTE G = 0;
247 BYTE R = 0;
248 BYTE A = 0;
249
250 const UINT32 color = FreeRDPReadColor(&pSrc8[x * bpp], format);
251 FreeRDPSplitColor(color, format, &R, &G, &B, &A, NULL);
252
253 andPixel = 0;
254
255 if (A < 64)
256 A = 0; /* pixel cannot be partially transparent */
257
258 if (!A)
259 {
260 /* transparent pixel: XOR = black, AND = 1 */
261 andPixel = 1;
262 B = G = R = 0;
263 }
264 else
265 {
266 if (premultiplied)
267 {
268 B = (B * 0xFF) / A;
269 G = (G * 0xFF) / A;
270 R = (R * 0xFF) / A;
271 }
272 }
273
274 *pDst8++ = B;
275 *pDst8++ = G;
276 *pDst8++ = R;
277
278 if (andPixel)
279 *andBits |= andBit;
280 if (!(andBit >>= 1))
281 {
282 andBits++;
283 andBit = 0x80;
284 }
285 }
286 }
287
288 return 1;
289}
290
291void shadow_subsystem_frame_update(rdpShadowSubsystem* subsystem)
292{
293 shadow_multiclient_publish_and_wait(subsystem->updateEvent);
294}
This struct contains function pointer to initialize/free objects.
Definition collections.h:57