Fix changelog email address
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / window.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Windowing Alternate Secondary Orders
4  *
5  * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  * Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <freerdp/utils/rail.h>
22 #include <freerdp/utils/memory.h>
23
24 #include "window.h"
25
26 void update_read_icon_info(STREAM* s, ICON_INFO* icon_info)
27 {
28         stream_read_uint16(s, icon_info->cacheEntry); /* cacheEntry (2 bytes) */
29         stream_read_uint8(s, icon_info->cacheId); /* cacheId (1 byte) */
30         stream_read_uint8(s, icon_info->bpp); /* bpp (1 byte) */
31         stream_read_uint16(s, icon_info->width); /* width (2 bytes) */
32         stream_read_uint16(s, icon_info->height); /* height (2 bytes) */
33
34         /* cbColorTable is only present when bpp is 1, 2 or 4 */
35         if (icon_info->bpp == 1 || icon_info->bpp == 2 || icon_info->bpp == 4)
36                 stream_read_uint16(s, icon_info->cbColorTable); /* cbColorTable (2 bytes) */
37         else
38                 icon_info->cbColorTable = 0;
39
40         stream_read_uint16(s, icon_info->cbBitsMask); /* cbBitsMask (2 bytes) */
41         stream_read_uint16(s, icon_info->cbBitsColor); /* cbBitsColor (2 bytes) */
42
43         /* bitsMask */
44         if (icon_info->bitsMask == NULL)
45                 icon_info->bitsMask = (uint8*) xmalloc(icon_info->cbBitsMask);
46         else
47                 icon_info->bitsMask = (uint8*) xrealloc(icon_info->bitsMask, icon_info->cbBitsMask);
48         stream_read(s, icon_info->bitsMask, icon_info->cbBitsMask);
49
50         /* colorTable */
51         if (icon_info->colorTable == NULL)
52                 icon_info->colorTable = (uint8*) xmalloc(icon_info->cbColorTable);
53         else
54                 icon_info->colorTable = (uint8*) xrealloc(icon_info->colorTable, icon_info->cbColorTable);
55         stream_read(s, icon_info->colorTable, icon_info->cbColorTable);
56
57         /* bitsColor */
58         if (icon_info->bitsColor == NULL)
59                 icon_info->bitsColor = (uint8*) xmalloc(icon_info->cbBitsColor);
60         else
61                 icon_info->bitsColor = (uint8*) xrealloc(icon_info->bitsColor, icon_info->cbBitsColor);
62         stream_read(s, icon_info->bitsColor, icon_info->cbBitsColor);
63 }
64
65 void update_read_cached_icon_info(STREAM* s, CACHED_ICON_INFO* cached_icon_info)
66 {
67         stream_read_uint16(s, cached_icon_info->cacheEntry); /* cacheEntry (2 bytes) */
68         stream_read_uint8(s, cached_icon_info->cacheId); /* cacheId (1 byte) */
69 }
70
71 void update_read_notify_icon_infotip(STREAM* s, NOTIFY_ICON_INFOTIP* notify_icon_infotip)
72 {
73         stream_read_uint32(s, notify_icon_infotip->timeout); /* timeout (4 bytes) */
74         stream_read_uint32(s, notify_icon_infotip->flags); /* infoFlags (4 bytes) */
75         rail_read_unicode_string(s, &notify_icon_infotip->text); /* infoTipText */
76         rail_read_unicode_string(s, &notify_icon_infotip->title); /* title */
77 }
78
79 void update_read_window_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* window_state)
80 {
81         int i;
82         int size;
83
84         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
85                 stream_read_uint32(s, window_state->ownerWindowId); /* ownerWindowId (4 bytes) */
86
87         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
88         {
89                 stream_read_uint32(s, window_state->style); /* style (4 bytes) */
90                 stream_read_uint32(s, window_state->extendedStyle); /* extendedStyle (4 bytes) */
91         }
92
93         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
94                 stream_read_uint8(s, window_state->showState); /* showState (1 byte) */
95
96         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
97                 rail_read_unicode_string(s, &window_state->titleInfo); /* titleInfo */
98
99         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
100         {
101                 stream_read_uint32(s, window_state->clientOffsetX); /* clientOffsetX (4 bytes) */
102                 stream_read_uint32(s, window_state->clientOffsetY); /* clientOffsetY (4 bytes) */
103         }
104
105         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
106         {
107                 stream_read_uint32(s, window_state->clientAreaWidth); /* clientAreaWidth (4 bytes) */
108                 stream_read_uint32(s, window_state->clientAreaHeight); /* clientAreaHeight (4 bytes) */
109         }
110
111         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
112                 stream_read_uint8(s, window_state->RPContent); /* RPContent (1 byte) */
113
114         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
115                 stream_read_uint32(s, window_state->rootParentHandle);/* rootParentHandle (4 bytes) */
116
117         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
118         {
119                 stream_read_uint32(s, window_state->windowOffsetX); /* windowOffsetX (4 bytes) */
120                 stream_read_uint32(s, window_state->windowOffsetY); /* windowOffsetY (4 bytes) */
121         }
122
123         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
124         {
125                 stream_read_uint32(s, window_state->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */
126                 stream_read_uint32(s, window_state->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */
127         }
128
129         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
130         {
131                 stream_read_uint32(s, window_state->windowWidth); /* windowWidth (4 bytes) */
132                 stream_read_uint32(s, window_state->windowHeight); /* windowHeight (4 bytes) */
133         }
134
135         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
136         {
137                 stream_read_uint16(s, window_state->numWindowRects); /* numWindowRects (2 bytes) */
138
139                 size = sizeof(RECTANGLE_16) * window_state->numWindowRects;
140                 window_state->windowRects = (RECTANGLE_16*) xmalloc(size);
141
142                 /* windowRects */
143                 for (i = 0; i < (int) window_state->numWindowRects; i++)
144                 {
145                         freerdp_read_rectangle_16(s, &window_state->windowRects[i]);
146                 }
147         }
148
149         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
150         {
151                 stream_read_uint32(s, window_state->visibleOffsetX); /* visibleOffsetX (4 bytes) */
152                 stream_read_uint32(s, window_state->visibleOffsetY); /* visibleOffsetY (4 bytes) */
153         }
154
155         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
156         {
157                 stream_read_uint16(s, window_state->numVisibilityRects); /* numVisibilityRects (2 bytes) */
158
159                 size = sizeof(RECTANGLE_16) * window_state->numVisibilityRects;
160                 window_state->visibilityRects = (RECTANGLE_16*) xmalloc(size);
161
162                 /* visibilityRects */
163                 for (i = 0; i < (int) window_state->numVisibilityRects; i++)
164                 {
165                         freerdp_read_rectangle_16(s, &window_state->visibilityRects[i]);
166                 }
167         }
168 }
169
170 void update_read_window_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* window_icon)
171 {
172         window_icon->iconInfo = (ICON_INFO*) xzalloc(sizeof(ICON_INFO));
173         update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */
174 }
175
176 void update_read_window_cached_icon_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* window_cached_icon)
177 {
178         update_read_cached_icon_info(s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */
179 }
180
181 void update_read_window_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo)
182 {
183         /* window deletion event */
184 }
185
186 void update_recv_window_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo)
187 {
188         rdpContext* context = update->context;
189         rdpWindowUpdate* window = update->window;
190
191         stream_read_uint32(s, orderInfo->windowId); /* windowId (4 bytes) */
192
193         if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
194         {
195                 DEBUG_WND("Window Icon Order");
196                 update_read_window_icon_order(s, orderInfo, &window->window_icon);
197                 IFCALL(window->WindowIcon, context, orderInfo, &window->window_icon);
198         }
199         else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
200         {
201                 DEBUG_WND("Window Cached Icon Order");
202                 update_read_window_cached_icon_order(s, orderInfo, &window->window_cached_icon);
203                 IFCALL(window->WindowCachedIcon, context, orderInfo, &window->window_cached_icon);
204         }
205         else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
206         {
207                 DEBUG_WND("Window Deleted Order");
208                 update_read_window_delete_order(s, orderInfo);
209                 IFCALL(window->WindowDelete, context, orderInfo);
210         }
211         else
212         {
213                 DEBUG_WND("Window State Order");
214                 update_read_window_state_order(s, orderInfo, &window->window_state);
215
216                 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
217                         IFCALL(window->WindowCreate, context, orderInfo, &window->window_state);
218                 else
219                         IFCALL(window->WindowUpdate, context, orderInfo, &window->window_state);
220         }
221 }
222
223 void update_read_notification_icon_state_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notify_icon_state)
224 {
225         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
226                 stream_read_uint32(s, notify_icon_state->version); /* version (4 bytes) */
227
228         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
229                 rail_read_unicode_string(s, &notify_icon_state->toolTip); /* toolTip (UNICODE_STRING) */
230
231         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
232                 update_read_notify_icon_infotip(s, &notify_icon_state->infoTip); /* infoTip (NOTIFY_ICON_INFOTIP) */
233
234         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
235                 stream_read_uint32(s, notify_icon_state->state); /* state (4 bytes) */
236
237         if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
238                 update_read_icon_info(s, &notify_icon_state->icon); /* icon (ICON_INFO) */
239
240         if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
241                 update_read_cached_icon_info(s, &notify_icon_state->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */
242 }
243
244 void update_read_notification_icon_delete_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo)
245 {
246         /* notification icon deletion event */
247 }
248
249 void update_recv_notification_icon_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo)
250 {
251         rdpContext* context = update->context;
252         rdpWindowUpdate* window = update->window;
253
254         stream_read_uint32(s, orderInfo->windowId); /* windowId (4 bytes) */
255         stream_read_uint32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */
256
257         if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
258         {
259                 DEBUG_WND("Delete Notification Icon Deleted Order");
260                 update_read_notification_icon_delete_order(s, orderInfo);
261                 IFCALL(window->NotifyIconDelete, context, orderInfo);
262         }
263         else
264         {
265                 DEBUG_WND("Notification Icon State Order");
266                 update_read_notification_icon_state_order(s, orderInfo, &window->notify_icon_state);
267
268                 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
269                         IFCALL(window->NotifyIconCreate, context, orderInfo, &window->notify_icon_state);
270                 else
271                         IFCALL(window->NotifyIconUpdate, context, orderInfo, &window->notify_icon_state);
272         }
273 }
274
275 void update_read_desktop_actively_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitored_desktop)
276 {
277         int i;
278         int size;
279
280         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
281                 stream_read_uint32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */
282
283         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
284         {
285                 stream_read_uint8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */
286
287                 size = sizeof(uint32) * monitored_desktop->numWindowIds;
288
289                 if (monitored_desktop->windowIds == NULL)
290                         monitored_desktop->windowIds = (uint32*) xmalloc(size);
291                 else
292                         monitored_desktop->windowIds = (uint32*) xrealloc(monitored_desktop->windowIds, size);
293
294                 /* windowIds */
295                 for (i = 0; i < (int) monitored_desktop->numWindowIds; i++)
296                 {
297                         stream_read_uint32(s, monitored_desktop->windowIds[i]);
298                 }
299         }
300 }
301
302 void update_read_desktop_non_monitored_order(STREAM* s, WINDOW_ORDER_INFO* orderInfo)
303 {
304         /* non-monitored desktop notification event */
305 }
306
307 void update_recv_desktop_info_order(rdpUpdate* update, STREAM* s, WINDOW_ORDER_INFO* orderInfo)
308 {
309         rdpContext* context = update->context;
310         rdpWindowUpdate* window = update->window;
311
312         if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
313         {
314                 DEBUG_WND("Non-Monitored Desktop Order");
315                 update_read_desktop_non_monitored_order(s, orderInfo);
316                 IFCALL(window->NonMonitoredDesktop, context, orderInfo);
317         }
318         else
319         {
320                 DEBUG_WND("Actively Monitored Desktop Order");
321                 update_read_desktop_actively_monitored_order(s, orderInfo, &window->monitored_desktop);
322                 IFCALL(window->MonitoredDesktop, context, orderInfo, &window->monitored_desktop);
323         }
324 }
325
326 void update_recv_altsec_window_order(rdpUpdate* update, STREAM* s)
327 {
328         uint16 orderSize;
329         rdpWindowUpdate* window = update->window;
330
331         stream_read_uint16(s, orderSize); /* orderSize (2 bytes) */
332         stream_read_uint32(s, window->orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */
333
334         if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
335                 update_recv_window_info_order(update, s, &window->orderInfo);
336         else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
337                 update_recv_notification_icon_info_order(update, s, &window->orderInfo);
338         else if (window->orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
339                 update_recv_desktop_info_order(update, s, &window->orderInfo);
340 }
341