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