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.
22 #include <freerdp/utils/rect.h>
23 #include <freerdp/codec/bitmap.h>
26 static const char* const UPDATE_TYPE_STRINGS[] =
35 void update_recv_orders(rdpUpdate* update, STREAM* s)
39 stream_seek_uint16(s); /* pad2OctetsA (2 bytes) */
40 stream_read_uint16(s, numberOrders); /* numberOrders (2 bytes) */
41 stream_seek_uint16(s); /* pad2OctetsB (2 bytes) */
43 while (numberOrders > 0)
45 update_recv_order(update, s);
50 void update_read_bitmap_data(STREAM* s, BITMAP_DATA* bitmap_data)
52 stream_read_uint16(s, bitmap_data->destLeft);
53 stream_read_uint16(s, bitmap_data->destTop);
54 stream_read_uint16(s, bitmap_data->destRight);
55 stream_read_uint16(s, bitmap_data->destBottom);
56 stream_read_uint16(s, bitmap_data->width);
57 stream_read_uint16(s, bitmap_data->height);
58 stream_read_uint16(s, bitmap_data->bitsPerPixel);
59 stream_read_uint16(s, bitmap_data->flags);
60 stream_read_uint16(s, bitmap_data->bitmapLength);
62 if (bitmap_data->flags & BITMAP_COMPRESSION)
64 if (!(bitmap_data->flags & NO_BITMAP_COMPRESSION_HDR))
66 stream_read_uint16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
67 stream_read_uint16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
68 stream_read_uint16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */
69 stream_read_uint16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
70 bitmap_data->bitmapLength = bitmap_data->cbCompMainBodySize;
73 bitmap_data->compressed = true;
74 stream_get_mark(s, bitmap_data->bitmapDataStream);
75 stream_seek(s, bitmap_data->bitmapLength);
79 bitmap_data->compressed = false;
80 stream_get_mark(s, bitmap_data->bitmapDataStream);
81 stream_seek(s, bitmap_data->bitmapLength);
85 void update_read_bitmap(rdpUpdate* update, STREAM* s, BITMAP_UPDATE* bitmap_update)
89 stream_read_uint16(s, bitmap_update->number); /* numberRectangles (2 bytes) */
91 if (bitmap_update->number > bitmap_update->count)
95 count = bitmap_update->number * 2;
97 bitmap_update->rectangles = (BITMAP_DATA*) xrealloc(bitmap_update->rectangles,
98 sizeof(BITMAP_DATA) * count);
100 memset(&bitmap_update->rectangles[bitmap_update->count], 0,
101 sizeof(BITMAP_DATA) * (count - bitmap_update->count));
103 bitmap_update->count = count;
107 for (i = 0; i < (int) bitmap_update->number; i++)
109 update_read_bitmap_data(s, &bitmap_update->rectangles[i]);
113 void update_read_palette(rdpUpdate* update, STREAM* s, PALETTE_UPDATE* palette_update)
116 PALETTE_ENTRY* entry;
118 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
119 stream_read_uint32(s, palette_update->number); /* numberColors (4 bytes), must be set to 256 */
121 if (palette_update->number > 256)
122 palette_update->number = 256;
125 for (i = 0; i < (int) palette_update->number; i++)
127 entry = &palette_update->entries[i];
129 stream_read_uint8(s, entry->blue);
130 stream_read_uint8(s, entry->green);
131 stream_read_uint8(s, entry->red);
135 void update_read_synchronize(rdpUpdate* update, STREAM* s)
137 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
140 * The Synchronize Update is an artifact from the
141 * T.128 protocol and should be ignored.
145 void update_read_play_sound(STREAM* s, PLAY_SOUND_UPDATE* play_sound)
147 stream_read_uint32(s, play_sound->duration); /* duration (4 bytes) */
148 stream_read_uint32(s, play_sound->frequency); /* frequency (4 bytes) */
151 void update_recv_play_sound(rdpUpdate* update, STREAM* s)
153 update_read_play_sound(s, &update->play_sound);
154 IFCALL(update->PlaySound, update->context, &update->play_sound);
157 void update_read_pointer_position(STREAM* s, POINTER_POSITION_UPDATE* pointer_position)
159 stream_read_uint16(s, pointer_position->xPos); /* xPos (2 bytes) */
160 stream_read_uint16(s, pointer_position->yPos); /* yPos (2 bytes) */
163 void update_read_pointer_system(STREAM* s, POINTER_SYSTEM_UPDATE* pointer_system)
165 stream_read_uint32(s, pointer_system->type); /* systemPointerType (4 bytes) */
168 void update_read_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
170 stream_read_uint16(s, pointer_color->cacheIndex); /* cacheIndex (2 bytes) */
171 stream_read_uint16(s, pointer_color->xPos); /* xPos (2 bytes) */
172 stream_read_uint16(s, pointer_color->yPos); /* yPos (2 bytes) */
173 stream_read_uint16(s, pointer_color->width); /* width (2 bytes) */
174 stream_read_uint16(s, pointer_color->height); /* height (2 bytes) */
175 stream_read_uint16(s, pointer_color->lengthAndMask); /* lengthAndMask (2 bytes) */
176 stream_read_uint16(s, pointer_color->lengthXorMask); /* lengthXorMask (2 bytes) */
178 if (pointer_color->lengthXorMask > 0)
180 pointer_color->xorMaskData = (uint8*) xmalloc(pointer_color->lengthXorMask);
181 stream_read(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
184 if (pointer_color->lengthAndMask > 0)
186 pointer_color->andMaskData = (uint8*) xmalloc(pointer_color->lengthAndMask);
187 stream_read(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
190 if (stream_get_left(s) > 0)
191 stream_seek_uint8(s); /* pad (1 byte) */
194 void update_read_pointer_new(STREAM* s, POINTER_NEW_UPDATE* pointer_new)
196 stream_read_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
197 update_read_pointer_color(s, &pointer_new->colorPtrAttr); /* colorPtrAttr */
200 void update_read_pointer_cached(STREAM* s, POINTER_CACHED_UPDATE* pointer_cached)
202 stream_read_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
205 void update_recv_pointer(rdpUpdate* update, STREAM* s)
208 rdpContext* context = update->context;
209 rdpPointerUpdate* pointer = update->pointer;
211 stream_read_uint16(s, messageType); /* messageType (2 bytes) */
212 stream_seek_uint16(s); /* pad2Octets (2 bytes) */
216 case PTR_MSG_TYPE_POSITION:
217 update_read_pointer_position(s, &pointer->pointer_position);
218 IFCALL(pointer->PointerPosition, context, &pointer->pointer_position);
221 case PTR_MSG_TYPE_SYSTEM:
222 update_read_pointer_system(s, &pointer->pointer_system);
223 IFCALL(pointer->PointerSystem, context, &pointer->pointer_system);
226 case PTR_MSG_TYPE_COLOR:
227 update_read_pointer_color(s, &pointer->pointer_color);
228 IFCALL(pointer->PointerColor, context, &pointer->pointer_color);
231 case PTR_MSG_TYPE_POINTER:
232 update_read_pointer_new(s, &pointer->pointer_new);
233 IFCALL(pointer->PointerNew, context, &pointer->pointer_new);
236 case PTR_MSG_TYPE_CACHED:
237 update_read_pointer_cached(s, &pointer->pointer_cached);
238 IFCALL(pointer->PointerCached, context, &pointer->pointer_cached);
246 void update_recv(rdpUpdate* update, STREAM* s)
249 rdpContext* context = update->context;
251 stream_read_uint16(s, updateType); /* updateType (2 bytes) */
253 //printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
255 IFCALL(update->BeginPaint, context);
259 case UPDATE_TYPE_ORDERS:
260 update_recv_orders(update, s);
263 case UPDATE_TYPE_BITMAP:
264 update_read_bitmap(update, s, &update->bitmap_update);
265 IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
268 case UPDATE_TYPE_PALETTE:
269 update_read_palette(update, s, &update->palette_update);
270 IFCALL(update->Palette, context, &update->palette_update);
273 case UPDATE_TYPE_SYNCHRONIZE:
274 update_read_synchronize(update, s);
275 IFCALL(update->Synchronize, context);
279 IFCALL(update->EndPaint, context);
281 if (stream_get_left(s) > RDP_SHARE_DATA_HEADER_LENGTH)
287 rdp_read_share_control_header(s, &length, &pduType, &source);
289 if (pduType != PDU_TYPE_DATA)
292 rdp_recv_data_pdu(update->context->rdp, s);
296 void update_reset_state(rdpUpdate* update)
298 rdpPrimaryUpdate* primary = update->primary;
299 rdpAltSecUpdate* altsec = update->altsec;
301 memset(&primary->order_info, 0, sizeof(ORDER_INFO));
302 memset(&primary->dstblt, 0, sizeof(DSTBLT_ORDER));
303 memset(&primary->patblt, 0, sizeof(PATBLT_ORDER));
304 memset(&primary->scrblt, 0, sizeof(SCRBLT_ORDER));
305 memset(&primary->opaque_rect, 0, sizeof(OPAQUE_RECT_ORDER));
306 memset(&primary->draw_nine_grid, 0, sizeof(DRAW_NINE_GRID_ORDER));
307 memset(&primary->multi_dstblt, 0, sizeof(MULTI_DSTBLT_ORDER));
308 memset(&primary->multi_patblt, 0, sizeof(MULTI_PATBLT_ORDER));
309 memset(&primary->multi_scrblt, 0, sizeof(MULTI_SCRBLT_ORDER));
310 memset(&primary->multi_opaque_rect, 0, sizeof(MULTI_OPAQUE_RECT_ORDER));
311 memset(&primary->multi_draw_nine_grid, 0, sizeof(MULTI_DRAW_NINE_GRID_ORDER));
312 memset(&primary->line_to, 0, sizeof(LINE_TO_ORDER));
313 memset(&primary->polyline, 0, sizeof(POLYLINE_ORDER));
314 memset(&primary->memblt, 0, sizeof(MEMBLT_ORDER));
315 memset(&primary->mem3blt, 0, sizeof(MEM3BLT_ORDER));
316 memset(&primary->save_bitmap, 0, sizeof(SAVE_BITMAP_ORDER));
317 memset(&primary->glyph_index, 0, sizeof(GLYPH_INDEX_ORDER));
318 memset(&primary->fast_index, 0, sizeof(FAST_INDEX_ORDER));
319 memset(&primary->fast_glyph, 0, sizeof(FAST_GLYPH_ORDER));
320 memset(&primary->polygon_sc, 0, sizeof(POLYGON_SC_ORDER));
321 memset(&primary->polygon_cb, 0, sizeof(POLYGON_CB_ORDER));
322 memset(&primary->ellipse_sc, 0, sizeof(ELLIPSE_SC_ORDER));
323 memset(&primary->ellipse_cb, 0, sizeof(ELLIPSE_CB_ORDER));
325 primary->order_info.orderType = ORDER_TYPE_PATBLT;
326 altsec->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE;
327 IFCALL(altsec->SwitchSurface, update->context, &(altsec->switch_surface));
330 static void update_begin_paint(rdpContext* context)
335 static void update_end_paint(rdpContext* context)
340 static void update_write_refresh_rect(STREAM* s, uint8 count, RECTANGLE_16* areas)
344 stream_write_uint8(s, count); /* numberOfAreas (1 byte) */
345 stream_seek(s, 3); /* pad3Octets (3 bytes) */
347 for (i = 0; i < count; i++)
348 freerdp_write_rectangle_16(s, &areas[i]);
351 static void update_send_refresh_rect(rdpContext* context, uint8 count, RECTANGLE_16* areas)
354 rdpRdp* rdp = context->rdp;
356 s = rdp_data_pdu_init(rdp);
357 update_write_refresh_rect(s, count, areas);
359 rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->user_id);
362 static void update_write_suppress_output(STREAM* s, uint8 allow, RECTANGLE_16* area)
364 stream_write_uint8(s, allow); /* allowDisplayUpdates (1 byte) */
365 stream_seek(s, 3); /* pad3Octets (3 bytes) */
368 freerdp_write_rectangle_16(s, area);
371 static void update_send_suppress_output(rdpContext* context, uint8 allow, RECTANGLE_16* area)
374 rdpRdp* rdp = context->rdp;
376 s = rdp_data_pdu_init(rdp);
377 update_write_suppress_output(s, allow, area);
379 rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT, rdp->mcs->user_id);
382 static void update_send_surface_command(rdpContext* context, STREAM* s)
385 rdpRdp* rdp = context->rdp;
387 update = fastpath_update_pdu_init(rdp->fastpath);
388 stream_check_size(update, stream_get_length(s));
389 stream_write(update, stream_get_head(s), stream_get_length(s));
390 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, update);
393 static void update_send_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_command)
396 rdpRdp* rdp = context->rdp;
398 s = fastpath_update_pdu_init(rdp->fastpath);
399 stream_check_size(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH + (int) surface_bits_command->bitmapDataLength);
400 update_write_surfcmd_surface_bits_header(s, surface_bits_command);
401 stream_write(s, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
402 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
405 static void update_send_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
408 rdpRdp* rdp = context->rdp;
410 s = fastpath_update_pdu_init(rdp->fastpath);
411 update_write_surfcmd_frame_marker(s, surface_frame_marker->frameAction, surface_frame_marker->frameId);
412 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SURFCMDS, s);
415 static void update_send_synchronize(rdpContext* context)
418 rdpRdp* rdp = context->rdp;
420 s = fastpath_update_pdu_init(rdp->fastpath);
421 stream_write_zero(s, 2); /* pad2Octets (2 bytes) */
422 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_SYNCHRONIZE, s);
425 static void update_send_desktop_resize(rdpContext* context)
427 rdp_server_reactivate(context->rdp);
430 static void update_send_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
433 rdpRdp* rdp = context->rdp;
435 s = fastpath_update_pdu_init(rdp->fastpath);
437 stream_write_uint16(s, 1); /* numberOrders (2 bytes) */
438 stream_write_uint8(s, ORDER_STANDARD | ORDER_TYPE_CHANGE); /* controlFlags (1 byte) */
439 stream_write_uint8(s, ORDER_TYPE_SCRBLT); /* orderType (1 byte) */
440 stream_write_uint8(s, 0x7F); /* fieldFlags (variable) */
442 stream_write_uint16(s, scrblt->nLeftRect);
443 stream_write_uint16(s, scrblt->nTopRect);
444 stream_write_uint16(s, scrblt->nWidth);
445 stream_write_uint16(s, scrblt->nHeight);
446 stream_write_uint8(s, scrblt->bRop);
447 stream_write_uint16(s, scrblt->nXSrc);
448 stream_write_uint16(s, scrblt->nYSrc);
450 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_ORDERS, s);
453 static void update_send_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system)
457 rdpRdp* rdp = context->rdp;
459 s = fastpath_update_pdu_init(rdp->fastpath);
460 if (pointer_system->type == SYSPTR_NULL)
461 updateCode = FASTPATH_UPDATETYPE_PTR_NULL;
463 updateCode = FASTPATH_UPDATETYPE_PTR_DEFAULT;
464 fastpath_send_update_pdu(rdp->fastpath, updateCode, s);
467 static void update_write_pointer_color(STREAM* s, POINTER_COLOR_UPDATE* pointer_color)
469 stream_check_size(s, 15 + (int) pointer_color->lengthAndMask + (int) pointer_color->lengthXorMask);
470 stream_write_uint16(s, pointer_color->cacheIndex);
471 stream_write_uint16(s, pointer_color->xPos);
472 stream_write_uint16(s, pointer_color->yPos);
473 stream_write_uint16(s, pointer_color->width);
474 stream_write_uint16(s, pointer_color->height);
475 stream_write_uint16(s, pointer_color->lengthAndMask);
476 stream_write_uint16(s, pointer_color->lengthXorMask);
477 if (pointer_color->lengthXorMask > 0)
478 stream_write(s, pointer_color->xorMaskData, pointer_color->lengthXorMask);
479 if (pointer_color->lengthAndMask > 0)
480 stream_write(s, pointer_color->andMaskData, pointer_color->lengthAndMask);
481 stream_write_uint8(s, 0); /* pad (1 byte) */
484 static void update_send_pointer_color(rdpContext* context, POINTER_COLOR_UPDATE* pointer_color)
487 rdpRdp* rdp = context->rdp;
489 s = fastpath_update_pdu_init(rdp->fastpath);
490 update_write_pointer_color(s, pointer_color);
491 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_COLOR, s);
494 static void update_send_pointer_new(rdpContext* context, POINTER_NEW_UPDATE* pointer_new)
497 rdpRdp* rdp = context->rdp;
499 s = fastpath_update_pdu_init(rdp->fastpath);
500 stream_write_uint16(s, pointer_new->xorBpp); /* xorBpp (2 bytes) */
501 update_write_pointer_color(s, &pointer_new->colorPtrAttr);
502 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_POINTER, s);
505 static void update_send_pointer_cached(rdpContext* context, POINTER_CACHED_UPDATE* pointer_cached)
508 rdpRdp* rdp = context->rdp;
510 s = fastpath_update_pdu_init(rdp->fastpath);
511 stream_write_uint16(s, pointer_cached->cacheIndex); /* cacheIndex (2 bytes) */
512 fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_CACHED, s);
515 void update_register_server_callbacks(rdpUpdate* update)
517 update->BeginPaint = update_begin_paint;
518 update->EndPaint = update_end_paint;
519 update->Synchronize = update_send_synchronize;
520 update->DesktopResize = update_send_desktop_resize;
521 update->RefreshRect = update_send_refresh_rect;
522 update->SuppressOutput = update_send_suppress_output;
523 update->SurfaceBits = update_send_surface_bits;
524 update->SurfaceFrameMarker = update_send_surface_frame_marker;
525 update->SurfaceCommand = update_send_surface_command;
526 update->primary->ScrBlt = update_send_scrblt;
527 update->pointer->PointerSystem = update_send_pointer_system;
528 update->pointer->PointerColor = update_send_pointer_color;
529 update->pointer->PointerNew = update_send_pointer_new;
530 update->pointer->PointerCached = update_send_pointer_cached;
533 rdpUpdate* update_new(rdpRdp* rdp)
537 update = (rdpUpdate*) xzalloc(sizeof(rdpUpdate));
541 OFFSCREEN_DELETE_LIST* deleteList;
543 update->bitmap_update.count = 64;
544 update->bitmap_update.rectangles = (BITMAP_DATA*) xzalloc(sizeof(BITMAP_DATA) * update->bitmap_update.count);
546 update->pointer = xnew(rdpPointerUpdate);
547 update->primary = xnew(rdpPrimaryUpdate);
548 update->secondary = xnew(rdpSecondaryUpdate);
549 update->altsec = xnew(rdpAltSecUpdate);
550 update->window = xnew(rdpWindowUpdate);
552 deleteList = &(update->altsec->create_offscreen_bitmap.deleteList);
553 deleteList->sIndices = 64;
554 deleteList->indices = xmalloc(deleteList->sIndices * 2);
555 deleteList->cIndices = 0;
557 update->SuppressOutput = update_send_suppress_output;
563 void update_free(rdpUpdate* update)
567 OFFSCREEN_DELETE_LIST* deleteList;
568 deleteList = &(update->altsec->create_offscreen_bitmap.deleteList);
569 xfree(deleteList->indices);
571 xfree(update->bitmap_update.rectangles);
572 xfree(update->pointer);
573 xfree(update->primary);
574 xfree(update->secondary);
575 xfree(update->altsec);
576 xfree(update->window);