FreeRDP
shadow_screen.c
1 
19 #include <freerdp/config.h>
20 
21 #include <winpr/assert.h>
22 
23 #include "shadow_surface.h"
24 
25 #include "shadow_screen.h"
26 #include "shadow_lobby.h"
27 
28 rdpShadowScreen* shadow_screen_new(rdpShadowServer* server)
29 {
30  WINPR_ASSERT(server);
31  WINPR_ASSERT(server->subsystem);
32 
33  rdpShadowScreen* screen = (rdpShadowScreen*)calloc(1, sizeof(rdpShadowScreen));
34 
35  if (!screen)
36  goto fail;
37 
38  screen->server = server;
39  rdpShadowSubsystem* subsystem = server->subsystem;
40 
41  if (!InitializeCriticalSectionAndSpinCount(&(screen->lock), 4000))
42  goto fail;
43 
44  region16_init(&(screen->invalidRegion));
45 
46  WINPR_ASSERT(subsystem->selectedMonitor < ARRAYSIZE(subsystem->monitors));
47  const MONITOR_DEF* primary = &(subsystem->monitors[subsystem->selectedMonitor]);
48  WINPR_ASSERT(primary);
49 
50  INT64 x = primary->left;
51  INT64 y = primary->top;
52  INT64 width = primary->right - primary->left + 1;
53  INT64 height = primary->bottom - primary->top + 1;
54 
55  WINPR_ASSERT(x >= 0);
56  WINPR_ASSERT(x <= UINT16_MAX);
57  WINPR_ASSERT(y >= 0);
58  WINPR_ASSERT(y <= UINT16_MAX);
59  WINPR_ASSERT(width >= 0);
60  WINPR_ASSERT(width <= UINT16_MAX);
61  WINPR_ASSERT(height >= 0);
62  WINPR_ASSERT(height <= UINT16_MAX);
63 
64  screen->width = (UINT16)width;
65  screen->height = (UINT16)height;
66 
67  screen->primary =
68  shadow_surface_new(server, (UINT16)x, (UINT16)y, (UINT16)width, (UINT16)height);
69 
70  if (!screen->primary)
71  goto fail;
72 
73  server->surface = screen->primary;
74 
75  screen->lobby = shadow_surface_new(server, (UINT16)x, (UINT16)y, (UINT16)width, (UINT16)height);
76 
77  if (!screen->lobby)
78  goto fail;
79 
80  server->lobby = screen->lobby;
81 
82  if (!shadow_client_init_lobby(server))
83  goto fail;
84 
85  return screen;
86 
87 fail:
88  WINPR_PRAGMA_DIAG_PUSH
89  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
90  shadow_screen_free(screen);
91  WINPR_PRAGMA_DIAG_POP
92 
93  return NULL;
94 }
95 
96 void shadow_screen_free(rdpShadowScreen* screen)
97 {
98  if (!screen)
99  return;
100 
101  DeleteCriticalSection(&(screen->lock));
102 
103  region16_uninit(&(screen->invalidRegion));
104 
105  if (screen->primary)
106  {
107  shadow_surface_free(screen->primary);
108  screen->primary = NULL;
109  }
110 
111  if (screen->lobby)
112  {
113  shadow_surface_free(screen->lobby);
114  screen->lobby = NULL;
115  }
116 
117  free(screen);
118 }
119 
120 BOOL shadow_screen_resize(rdpShadowScreen* screen)
121 {
122  if (!screen)
123  return FALSE;
124 
125  WINPR_ASSERT(screen->server);
126 
127  rdpShadowSubsystem* subsystem = screen->server->subsystem;
128  WINPR_ASSERT(subsystem);
129  WINPR_ASSERT(subsystem->monitors);
130 
131  MONITOR_DEF* primary = &(subsystem->monitors[subsystem->selectedMonitor]);
132  WINPR_ASSERT(primary);
133 
134  const INT32 x = primary->left;
135  const INT32 y = primary->top;
136  const INT32 width = primary->right - primary->left + 1;
137  const INT32 height = primary->bottom - primary->top + 1;
138 
139  WINPR_ASSERT(x >= 0);
140  WINPR_ASSERT(x <= UINT16_MAX);
141  WINPR_ASSERT(y >= 0);
142  WINPR_ASSERT(y <= UINT16_MAX);
143  WINPR_ASSERT(width >= 0);
144  WINPR_ASSERT(width <= UINT16_MAX);
145  WINPR_ASSERT(height >= 0);
146  WINPR_ASSERT(height <= UINT16_MAX);
147 
148  if (shadow_surface_resize(screen->primary, (UINT16)x, (UINT16)y, (UINT16)width,
149  (UINT16)height) &&
150  shadow_surface_resize(screen->lobby, (UINT16)x, (UINT16)y, (UINT16)width, (UINT16)height))
151  {
152  if (((UINT32)width != screen->width) || ((UINT32)height != screen->height))
153  {
154  /* screen size is changed. Store new size and reinit lobby */
155  screen->width = (UINT32)width;
156  screen->height = (UINT32)height;
157  shadow_client_init_lobby(screen->server);
158  }
159  return TRUE;
160  }
161 
162  return FALSE;
163 }