FreeRDP
shadow_subsystem.c
1 
19 #include <freerdp/config.h>
20 
21 #include "shadow.h"
22 
23 #include "shadow_subsystem.h"
24 
25 static pfnShadowSubsystemEntry pSubsystemEntry = NULL;
26 
27 void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry)
28 {
29  pSubsystemEntry = pEntry;
30 }
31 
32 static 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 
46 rdpShadowSubsystem* 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 
66 void shadow_subsystem_free(rdpShadowSubsystem* subsystem)
67 {
68  if (subsystem && subsystem->ep.Free)
69  subsystem->ep.Free(subsystem);
70 }
71 
72 int 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 
91 fail:
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 
107 static 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 
117 void 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 
149 int 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 
161 int 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 
173 UINT32 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 int shadow_subsystem_pointer_convert_alpha_pointer_data(
193  const BYTE* WINPR_RESTRICT pixels, BOOL premultiplied, UINT32 width, UINT32 height,
194  SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* WINPR_RESTRICT pointerColor)
195 {
196  return shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
197  pixels, PIXEL_FORMAT_BGRX32, premultiplied, width, height, pointerColor);
198 }
199 
200 int shadow_subsystem_pointer_convert_alpha_pointer_data_to_format(
201  const BYTE* pixels, UINT32 format, BOOL premultiplied, UINT32 width, UINT32 height,
203 {
204  UINT32 xorStep = 0;
205  UINT32 andStep = 0;
206  UINT32 andBit = 0;
207  BYTE* andBits = NULL;
208  UINT32 andPixel = 0;
209  const size_t bpp = FreeRDPGetBytesPerPixel(format);
210 
211  xorStep = (width * 3);
212  xorStep += (xorStep % 2);
213 
214  andStep = ((width + 7) / 8);
215  andStep += (andStep % 2);
216 
217  pointerColor->lengthXorMask = height * xorStep;
218  pointerColor->xorMaskData = (BYTE*)calloc(1, pointerColor->lengthXorMask);
219 
220  if (!pointerColor->xorMaskData)
221  return -1;
222 
223  pointerColor->lengthAndMask = height * andStep;
224  pointerColor->andMaskData = (BYTE*)calloc(1, pointerColor->lengthAndMask);
225 
226  if (!pointerColor->andMaskData)
227  {
228  free(pointerColor->xorMaskData);
229  pointerColor->xorMaskData = NULL;
230  return -1;
231  }
232 
233  for (size_t y = 0; y < height; y++)
234  {
235  const BYTE* pSrc8 = &pixels[(width * bpp) * (height - 1 - y)];
236  BYTE* pDst8 = &(pointerColor->xorMaskData[y * xorStep]);
237 
238  andBit = 0x80;
239  andBits = &(pointerColor->andMaskData[andStep * y]);
240 
241  for (size_t x = 0; x < width; x++)
242  {
243  BYTE B = 0;
244  BYTE G = 0;
245  BYTE R = 0;
246  BYTE A = 0;
247 
248  const UINT32 color = FreeRDPReadColor(&pSrc8[x * bpp], format);
249  FreeRDPSplitColor(color, format, &R, &G, &B, &A, NULL);
250 
251  andPixel = 0;
252 
253  if (A < 64)
254  A = 0; /* pixel cannot be partially transparent */
255 
256  if (!A)
257  {
258  /* transparent pixel: XOR = black, AND = 1 */
259  andPixel = 1;
260  B = G = R = 0;
261  }
262  else
263  {
264  if (premultiplied)
265  {
266  B = (B * 0xFF) / A;
267  G = (G * 0xFF) / A;
268  R = (R * 0xFF) / A;
269  }
270  }
271 
272  *pDst8++ = B;
273  *pDst8++ = G;
274  *pDst8++ = R;
275 
276  if (andPixel)
277  *andBits |= andBit;
278  if (!(andBit >>= 1))
279  {
280  andBits++;
281  andBit = 0x80;
282  }
283  }
284  }
285 
286  return 1;
287 }
288 
289 void shadow_subsystem_frame_update(rdpShadowSubsystem* subsystem)
290 {
291  shadow_multiclient_publish_and_wait(subsystem->updateEvent);
292 }
This struct contains function pointer to initialize/free objects.
Definition: collections.h:57