Fix changelog email address
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-rail / window.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * RAIL Windows
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 #include <freerdp/utils/stream.h>
21 #include <freerdp/utils/memory.h>
22 #include <freerdp/utils/hexdump.h>
23 #include <freerdp/utils/unicode.h>
24
25 #include "librail.h"
26
27 #include <freerdp/rail/window.h>
28
29 struct _WINDOW_STYLE
30 {
31         uint32 style;
32         const char* name;
33         boolean multi;
34 };
35 typedef struct _WINDOW_STYLE WINDOW_STYLE;
36
37 static const WINDOW_STYLE WINDOW_STYLES[] =
38 {
39         { WS_BORDER, "WS_BORDER", false },
40         { WS_CAPTION, "WS_CAPTION", false },
41         { WS_CHILD, "WS_CHILD", false },
42         { WS_CLIPCHILDREN, "WS_CLIPCHILDREN", false },
43         { WS_CLIPSIBLINGS, "WS_CLIPSIBLINGS", false },
44         { WS_DISABLED, "WS_DISABLED", false },
45         { WS_DLGFRAME, "WS_DLGFRAME", false },
46         { WS_GROUP, "WS_GROUP", false },
47         { WS_HSCROLL, "WS_HSCROLL", false },
48         { WS_ICONIC, "WS_ICONIC", false },
49         { WS_MAXIMIZE, "WS_MAXIMIZE", false },
50         { WS_MAXIMIZEBOX, "WS_MAXIMIZEBOX", false },
51         { WS_MINIMIZE, "WS_MINIMIZE", false },
52         { WS_MINIMIZEBOX, "WS_MINIMIZEBOX", false },
53         { WS_OVERLAPPED, "WS_OVERLAPPED", false },
54         { WS_OVERLAPPEDWINDOW, "WS_OVERLAPPEDWINDOW", true },
55         { WS_POPUP, "WS_POPUP", false },
56         { WS_POPUPWINDOW, "WS_POPUPWINDOW", true },
57         { WS_SIZEBOX, "WS_SIZEBOX", false },
58         { WS_SYSMENU, "WS_SYSMENU", false },
59         { WS_TABSTOP, "WS_TABSTOP", false },
60         { WS_THICKFRAME, "WS_THICKFRAME", false },
61         { WS_VISIBLE, "WS_VISIBLE", false }
62 };
63
64 static const WINDOW_STYLE EXTENDED_WINDOW_STYLES[] =
65 {
66         { WS_EX_ACCEPTFILES, "WS_EX_ACCEPTFILES", false },
67         { WS_EX_APPWINDOW, "WS_EX_APPWINDOW", false },
68         { WS_EX_CLIENTEDGE, "WS_EX_CLIENTEDGE", false },
69         { WS_EX_COMPOSITED, "WS_EX_COMPOSITED", false },
70         { WS_EX_CONTEXTHELP, "WS_EX_CONTEXTHELP", false },
71         { WS_EX_CONTROLPARENT, "WS_EX_CONTROLPARENT", false },
72         { WS_EX_DLGMODALFRAME, "WS_EX_DLGMODALFRAME", false },
73         { WS_EX_LAYERED, "WS_EX_LAYERED", false },
74         { WS_EX_LAYOUTRTL, "WS_EX_LAYOUTRTL", false },
75         { WS_EX_LEFT, "WS_EX_LEFT", false },
76         { WS_EX_LEFTSCROLLBAR, "WS_EX_LEFTSCROLLBAR", false },
77         { WS_EX_LTRREADING, "WS_EX_LTRREADING", false },
78         { WS_EX_MDICHILD, "WS_EX_MDICHILD", false },
79         { WS_EX_NOACTIVATE, "WS_EX_NOACTIVATE", false },
80         { WS_EX_NOINHERITLAYOUT, "WS_EX_NOINHERITLAYOUT", false },
81         { WS_EX_NOPARENTNOTIFY, "WS_EX_NOPARENTNOTIFY", false },
82         { WS_EX_OVERLAPPEDWINDOW, "WS_EX_OVERLAPPEDWINDOW", true },
83         { WS_EX_PALETTEWINDOW, "WS_EX_PALETTEWINDOW", true },
84         { WS_EX_RIGHT, "WS_EX_RIGHT", false },
85         { WS_EX_RIGHTSCROLLBAR, "WS_EX_RIGHTSCROLLBAR", false },
86         { WS_EX_RTLREADING, "WS_EX_RTLREADING", false },
87         { WS_EX_STATICEDGE, "WS_EX_STATICEDGE", false },
88         { WS_EX_TOOLWINDOW, "WS_EX_TOOLWINDOW", false },
89         { WS_EX_TOPMOST, "WS_EX_TOPMOST", false },
90         { WS_EX_TRANSPARENT, "WS_EX_TRANSPARENT", false },
91         { WS_EX_WINDOWEDGE, "WS_EX_WINDOWEDGE", false }
92 };
93
94 void print_window_styles(uint32 style)
95 {
96         int i;
97
98         printf("Window Styles:\n{\n");
99         for (i = 0; i < sizeof(WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++)
100         {
101                 if (style & WINDOW_STYLES[i].style)
102                 {
103                         if (WINDOW_STYLES[i].multi)
104                         {
105                                 if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style)
106                                                 continue;
107                         }
108
109                         printf("\t%s\n", WINDOW_STYLES[i].name);
110                 }
111         }
112         printf("}\n");
113 }
114
115 void print_extended_window_styles(uint32 style)
116 {
117         int i;
118
119         printf("Extended Window Styles:\n{\n");
120         for (i = 0; i < sizeof(EXTENDED_WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++)
121         {
122                 if (style & EXTENDED_WINDOW_STYLES[i].style)
123                 {
124                         if (EXTENDED_WINDOW_STYLES[i].multi)
125                         {
126                                 if ((style & EXTENDED_WINDOW_STYLES[i].style) != EXTENDED_WINDOW_STYLES[i].style)
127                                                 continue;
128                         }
129
130                         printf("\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
131                 }
132         }
133         printf("}\n");
134 }
135
136 void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
137 {
138         window->fieldFlags = orderInfo->fieldFlags;
139
140         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
141         {
142                 window->ownerWindowId = window_state->ownerWindowId;
143                 DEBUG_RAIL("ownerWindowId:0x%08X", window->ownerWindowId);
144         }
145
146         DEBUG_RAIL("windowId=0x%X ownerWindowId=0x%X",
147                         window->windowId, window->ownerWindowId);
148
149         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
150         {
151                 window->style = window_state->style;
152                 window->extendedStyle = window_state->extendedStyle;
153
154 #ifdef WITH_DEBUG_RAIL
155                 print_window_styles(window->style);
156                 print_extended_window_styles(window->extendedStyle);
157 #endif
158         }
159
160         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
161         {
162                 window->showState = window_state->showState;
163                 DEBUG_RAIL("ShowState:%d", window->showState);
164         }
165
166         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
167         {
168                 window->titleInfo.length = window_state->titleInfo.length;
169                 window->titleInfo.string = xmalloc(window_state->titleInfo.length);
170                 memcpy(window->titleInfo.string, window_state->titleInfo.string, window->titleInfo.length);
171
172 #ifdef WITH_DEBUG_RAIL
173                 freerdp_hexdump(window->titleInfo.string, window->titleInfo.length);
174 #endif
175         }
176
177         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
178         {
179                 window->clientOffsetX = window_state->clientOffsetX;
180                 window->clientOffsetY = window_state->clientOffsetY;
181
182                 DEBUG_RAIL("Client Area Offset: (%d, %d)",
183                                 window->clientOffsetX, window->clientOffsetY);
184         }
185
186         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
187         {
188                 window->clientAreaWidth = window_state->clientAreaWidth;
189                 window->clientAreaHeight = window_state->clientAreaHeight;
190
191                 DEBUG_RAIL("Client Area Size: (%d, %d)",
192                                 window->clientAreaWidth, window->clientAreaHeight);
193         }
194
195         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
196         {
197                 window->RPContent = window_state->RPContent;
198         }
199
200         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
201         {
202                 window->rootParentHandle = window_state->rootParentHandle;
203         }
204
205         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
206         {
207                 window->windowOffsetX = window_state->windowOffsetX;
208                 window->windowOffsetY = window_state->windowOffsetY;
209
210                 DEBUG_RAIL("Window Offset: (%d, %d)",
211                                 window->windowOffsetX, window->windowOffsetY);
212         }
213
214         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
215         {
216                 window->windowClientDeltaX = window_state->windowClientDeltaX;
217                 window->windowClientDeltaY = window_state->windowClientDeltaY;
218
219                 DEBUG_RAIL("Window Client Delta: (%d, %d)",
220                                 window->windowClientDeltaX, window->windowClientDeltaY);
221         }
222
223         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
224         {
225                 window->windowWidth = window_state->windowWidth;
226                 window->windowHeight = window_state->windowHeight;
227
228                 DEBUG_RAIL("Window Size: (%d, %d)",
229                                 window->windowWidth, window->windowHeight);
230         }
231
232         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
233         {
234                 int i;
235
236                 if (window->windowRects != NULL)
237                         xfree(window->windowRects);
238
239                 window->windowRects = window_state->windowRects;
240                 window->numWindowRects = window_state->numWindowRects;
241
242                 for (i = 0; i < (int) window_state->numWindowRects; i++)
243                 {
244                         DEBUG_RAIL("Window Rect #%d: left:%d top:%d right:%d bottom:%d", i,
245                                         window_state->windowRects[i].left, window_state->windowRects[i].top,
246                                         window_state->windowRects[i].right, window_state->windowRects[i].bottom);
247                 }
248         }
249
250         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
251         {
252                 window->visibleOffsetX = window_state->visibleOffsetX;
253                 window->visibleOffsetY = window_state->visibleOffsetY;
254
255                 DEBUG_RAIL("Window Visible Offset: (%d, %d)",
256                                 window->visibleOffsetX, window->visibleOffsetY);
257         }
258
259         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
260         {
261                 int i;
262
263                 if (window->visibilityRects != NULL)
264                         xfree(window->visibilityRects);
265
266                 window->visibilityRects = window_state->visibilityRects;
267                 window->numVisibilityRects = window_state->numVisibilityRects;
268
269                 for (i = 0; i < (int) window_state->numVisibilityRects; i++)
270                 {
271                         DEBUG_RAIL("Visibility Rect #%d: left:%d top:%d right:%d bottom:%d", i,
272                                         window_state->visibilityRects[i].left, window_state->visibilityRects[i].top,
273                                         window_state->visibilityRects[i].right, window_state->visibilityRects[i].bottom);
274                 }
275         }
276 }
277
278 void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
279 {
280         if (window->titleInfo.length > 0)
281         {
282                 window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length);
283         }
284         else
285         {
286                 window->title = (char*) xmalloc(sizeof("RAIL"));
287                 memcpy(window->title, "RAIL", sizeof("RAIL"));
288         }
289
290         IFCALL(rail->rail_CreateWindow, rail, window);
291
292         if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
293         {
294                 IFCALL(rail->rail_SetWindowRects, rail, window);
295         }
296         if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
297         {
298                 IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
299         }
300 }
301
302 void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
303 {
304         if (window->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
305         {
306
307         }
308
309         if (window->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
310         {
311
312         }
313
314         if (window->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
315         {
316                 IFCALL(rail->rail_ShowWindow, rail, window, window->showState);
317         }
318
319         if (window->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
320         {
321                 if (window->title != NULL)
322                         xfree(window->title);
323
324                 window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length);
325
326                 IFCALL(rail->rail_SetWindowText, rail, window);
327         }
328
329         if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
330         {
331
332         }
333
334         if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
335         {
336
337         }
338
339         if (window->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
340         {
341
342         }
343
344         if (window->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
345         {
346
347         }
348
349         if ((window->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
350                         (window->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
351         {
352                 IFCALL(rail->rail_MoveWindow, rail, window);
353         }
354
355         if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
356         {
357
358         }
359
360         if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
361         {
362                 IFCALL(rail->rail_SetWindowRects, rail, window);
363         }
364
365         if (window->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
366         {
367
368         }
369
370         if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
371         {
372                 IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
373         }
374 }
375
376 void rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
377 {
378         IFCALL(rail->rail_DestroyWindow, rail, window);
379
380         if (window != NULL)
381         {
382                 xfree(window);
383         }
384 }