2 * FreeRDP: A Remote Desktop Protocol Client
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <freerdp/utils/stream.h>
21 #include <freerdp/utils/memory.h>
22 #include <freerdp/utils/hexdump.h>
23 #include <freerdp/utils/unicode.h>
27 #include <freerdp/rail/window.h>
35 typedef struct _WINDOW_STYLE WINDOW_STYLE;
37 static const WINDOW_STYLE WINDOW_STYLES[] =
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 }
64 static const WINDOW_STYLE EXTENDED_WINDOW_STYLES[] =
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 }
94 void print_window_styles(uint32 style)
98 printf("Window Styles:\n{\n");
99 for (i = 0; i < sizeof(WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++)
101 if (style & WINDOW_STYLES[i].style)
103 if (WINDOW_STYLES[i].multi)
105 if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style)
109 printf("\t%s\n", WINDOW_STYLES[i].name);
115 void print_extended_window_styles(uint32 style)
119 printf("Extended Window Styles:\n{\n");
120 for (i = 0; i < sizeof(EXTENDED_WINDOW_STYLES) / sizeof(WINDOW_STYLE); i++)
122 if (style & EXTENDED_WINDOW_STYLES[i].style)
124 if (EXTENDED_WINDOW_STYLES[i].multi)
126 if ((style & EXTENDED_WINDOW_STYLES[i].style) != EXTENDED_WINDOW_STYLES[i].style)
130 printf("\t%s\n", EXTENDED_WINDOW_STYLES[i].name);
136 void window_state_update(rdpWindow* window, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
138 window->fieldFlags = orderInfo->fieldFlags;
140 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
142 window->ownerWindowId = window_state->ownerWindowId;
143 DEBUG_RAIL("ownerWindowId:0x%08X", window->ownerWindowId);
146 DEBUG_RAIL("windowId=0x%X ownerWindowId=0x%X",
147 window->windowId, window->ownerWindowId);
149 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
151 window->style = window_state->style;
152 window->extendedStyle = window_state->extendedStyle;
154 #ifdef WITH_DEBUG_RAIL
155 print_window_styles(window->style);
156 print_extended_window_styles(window->extendedStyle);
160 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
162 window->showState = window_state->showState;
163 DEBUG_RAIL("ShowState:%d", window->showState);
166 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
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);
172 #ifdef WITH_DEBUG_RAIL
173 freerdp_hexdump(window->titleInfo.string, window->titleInfo.length);
177 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
179 window->clientOffsetX = window_state->clientOffsetX;
180 window->clientOffsetY = window_state->clientOffsetY;
182 DEBUG_RAIL("Client Area Offset: (%d, %d)",
183 window->clientOffsetX, window->clientOffsetY);
186 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
188 window->clientAreaWidth = window_state->clientAreaWidth;
189 window->clientAreaHeight = window_state->clientAreaHeight;
191 DEBUG_RAIL("Client Area Size: (%d, %d)",
192 window->clientAreaWidth, window->clientAreaHeight);
195 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
197 window->RPContent = window_state->RPContent;
200 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
202 window->rootParentHandle = window_state->rootParentHandle;
205 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
207 window->windowOffsetX = window_state->windowOffsetX;
208 window->windowOffsetY = window_state->windowOffsetY;
210 DEBUG_RAIL("Window Offset: (%d, %d)",
211 window->windowOffsetX, window->windowOffsetY);
214 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
216 window->windowClientDeltaX = window_state->windowClientDeltaX;
217 window->windowClientDeltaY = window_state->windowClientDeltaY;
219 DEBUG_RAIL("Window Client Delta: (%d, %d)",
220 window->windowClientDeltaX, window->windowClientDeltaY);
223 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
225 window->windowWidth = window_state->windowWidth;
226 window->windowHeight = window_state->windowHeight;
228 DEBUG_RAIL("Window Size: (%d, %d)",
229 window->windowWidth, window->windowHeight);
232 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
236 if (window->windowRects != NULL)
237 xfree(window->windowRects);
239 window->windowRects = window_state->windowRects;
240 window->numWindowRects = window_state->numWindowRects;
242 for (i = 0; i < (int) window_state->numWindowRects; i++)
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);
250 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
252 window->visibleOffsetX = window_state->visibleOffsetX;
253 window->visibleOffsetY = window_state->visibleOffsetY;
255 DEBUG_RAIL("Window Visible Offset: (%d, %d)",
256 window->visibleOffsetX, window->visibleOffsetY);
259 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
263 if (window->visibilityRects != NULL)
264 xfree(window->visibilityRects);
266 window->visibilityRects = window_state->visibilityRects;
267 window->numVisibilityRects = window_state->numVisibilityRects;
269 for (i = 0; i < (int) window_state->numVisibilityRects; i++)
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);
278 void rail_CreateWindow(rdpRail* rail, rdpWindow* window)
280 if (window->titleInfo.length > 0)
282 window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length);
286 window->title = (char*) xmalloc(sizeof("RAIL"));
287 memcpy(window->title, "RAIL", sizeof("RAIL"));
290 IFCALL(rail->rail_CreateWindow, rail, window);
292 if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
294 IFCALL(rail->rail_SetWindowRects, rail, window);
296 if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
298 IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
302 void rail_UpdateWindow(rdpRail* rail, rdpWindow* window)
304 if (window->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
309 if (window->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
314 if (window->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
316 IFCALL(rail->rail_ShowWindow, rail, window, window->showState);
319 if (window->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
321 if (window->title != NULL)
322 xfree(window->title);
324 window->title = freerdp_uniconv_in(rail->uniconv, window->titleInfo.string, window->titleInfo.length);
326 IFCALL(rail->rail_SetWindowText, rail, window);
329 if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
334 if (window->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
339 if (window->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
344 if (window->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
349 if ((window->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
350 (window->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
352 IFCALL(rail->rail_MoveWindow, rail, window);
355 if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
360 if (window->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
362 IFCALL(rail->rail_SetWindowRects, rail, window);
365 if (window->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
370 if (window->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
372 IFCALL(rail->rail_SetWindowVisibilityRects, rail, window);
376 void rail_DestroyWindow(rdpRail* rail, rdpWindow* window)
378 IFCALL(rail->rail_DestroyWindow, rail, window);