Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenorders.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*- 00002 rdesktop: A Remote Desktop Protocol client. 00003 RDP order processing 00004 Copyright (C) Matthew Chapman 1999-2005 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License along 00017 with this program; if not, write to the Free Software Foundation, Inc., 00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include <precomp.h> 00022 00023 00024 extern uint8 *g_next_packet; 00025 static RDP_ORDER_STATE g_order_state; 00026 extern BOOL g_use_rdp5; 00027 00028 /* Read field indicating which parameters are present */ 00029 static void 00030 rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size) 00031 { 00032 uint8 bits; 00033 int i; 00034 00035 if (flags & RDP_ORDER_SMALL) 00036 { 00037 size--; 00038 } 00039 00040 if (flags & RDP_ORDER_TINY) 00041 { 00042 if (size < 2) 00043 size = 0; 00044 else 00045 size -= 2; 00046 } 00047 00048 *present = 0; 00049 for (i = 0; i < size; i++) 00050 { 00051 in_uint8(s, bits); 00052 *present |= bits << (i * 8); 00053 } 00054 } 00055 00056 /* Read a co-ordinate (16-bit, or 8-bit delta) */ 00057 static void 00058 rdp_in_coord(STREAM s, sint16 * coord, BOOL delta) 00059 { 00060 sint8 change; 00061 00062 if (delta) 00063 { 00064 in_uint8(s, change); 00065 *coord += change; 00066 } 00067 else 00068 { 00069 in_uint16_le(s, *coord); 00070 } 00071 } 00072 00073 /* Parse a delta co-ordinate in polyline/polygon order form */ 00074 static int 00075 parse_delta(uint8 * buffer, int *offset) 00076 { 00077 int value = buffer[(*offset)++]; 00078 int two_byte = value & 0x80; 00079 00080 if (value & 0x40) /* sign bit */ 00081 value |= ~0x3f; 00082 else 00083 value &= 0x3f; 00084 00085 if (two_byte) 00086 value = (value << 8) | buffer[(*offset)++]; 00087 00088 return value; 00089 } 00090 00091 /* Read a colour entry */ 00092 static void 00093 rdp_in_colour(STREAM s, uint32 * colour) 00094 { 00095 uint32 i; 00096 in_uint8(s, i); 00097 *colour = i; 00098 in_uint8(s, i); 00099 *colour |= i << 8; 00100 in_uint8(s, i); 00101 *colour |= i << 16; 00102 } 00103 00104 /* Parse bounds information */ 00105 static BOOL 00106 rdp_parse_bounds(STREAM s, BOUNDS * bounds) 00107 { 00108 uint8 present; 00109 00110 in_uint8(s, present); 00111 00112 if (present & 1) 00113 rdp_in_coord(s, &bounds->left, False); 00114 else if (present & 16) 00115 rdp_in_coord(s, &bounds->left, True); 00116 00117 if (present & 2) 00118 rdp_in_coord(s, &bounds->top, False); 00119 else if (present & 32) 00120 rdp_in_coord(s, &bounds->top, True); 00121 00122 if (present & 4) 00123 rdp_in_coord(s, &bounds->right, False); 00124 else if (present & 64) 00125 rdp_in_coord(s, &bounds->right, True); 00126 00127 if (present & 8) 00128 rdp_in_coord(s, &bounds->bottom, False); 00129 else if (present & 128) 00130 rdp_in_coord(s, &bounds->bottom, True); 00131 00132 return s_check(s); 00133 } 00134 00135 /* Parse a pen */ 00136 static BOOL 00137 rdp_parse_pen(STREAM s, PEN * pen, uint32 present) 00138 { 00139 if (present & 1) 00140 in_uint8(s, pen->style); 00141 00142 if (present & 2) 00143 in_uint8(s, pen->width); 00144 00145 if (present & 4) 00146 rdp_in_colour(s, &pen->colour); 00147 00148 return s_check(s); 00149 } 00150 00151 /* Parse a brush */ 00152 static BOOL 00153 rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present) 00154 { 00155 if (present & 1) 00156 in_uint8(s, brush->xorigin); 00157 00158 if (present & 2) 00159 in_uint8(s, brush->yorigin); 00160 00161 if (present & 4) 00162 in_uint8(s, brush->style); 00163 00164 if (present & 8) 00165 in_uint8(s, brush->pattern[0]); 00166 00167 if (present & 16) 00168 in_uint8a(s, &brush->pattern[1], 7); 00169 00170 return s_check(s); 00171 } 00172 00173 /* Process a destination blt order */ 00174 static void 00175 process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta) 00176 { 00177 if (present & 0x01) 00178 rdp_in_coord(s, &os->x, delta); 00179 00180 if (present & 0x02) 00181 rdp_in_coord(s, &os->y, delta); 00182 00183 if (present & 0x04) 00184 rdp_in_coord(s, &os->cx, delta); 00185 00186 if (present & 0x08) 00187 rdp_in_coord(s, &os->cy, delta); 00188 00189 if (present & 0x10) 00190 in_uint8(s, os->opcode); 00191 00192 DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n", 00193 os->opcode, os->x, os->y, os->cx, os->cy)); 00194 00195 ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy); 00196 } 00197 00198 /* Process a pattern blt order */ 00199 static void 00200 process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta) 00201 { 00202 if (present & 0x0001) 00203 rdp_in_coord(s, &os->x, delta); 00204 00205 if (present & 0x0002) 00206 rdp_in_coord(s, &os->y, delta); 00207 00208 if (present & 0x0004) 00209 rdp_in_coord(s, &os->cx, delta); 00210 00211 if (present & 0x0008) 00212 rdp_in_coord(s, &os->cy, delta); 00213 00214 if (present & 0x0010) 00215 in_uint8(s, os->opcode); 00216 00217 if (present & 0x0020) 00218 rdp_in_colour(s, &os->bgcolour); 00219 00220 if (present & 0x0040) 00221 rdp_in_colour(s, &os->fgcolour); 00222 00223 rdp_parse_brush(s, &os->brush, present >> 7); 00224 00225 DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x, 00226 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour)); 00227 00228 ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy, 00229 &os->brush, os->bgcolour, os->fgcolour); 00230 } 00231 00232 /* Process a screen blt order */ 00233 static void 00234 process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta) 00235 { 00236 if (present & 0x0001) 00237 rdp_in_coord(s, &os->x, delta); 00238 00239 if (present & 0x0002) 00240 rdp_in_coord(s, &os->y, delta); 00241 00242 if (present & 0x0004) 00243 rdp_in_coord(s, &os->cx, delta); 00244 00245 if (present & 0x0008) 00246 rdp_in_coord(s, &os->cy, delta); 00247 00248 if (present & 0x0010) 00249 in_uint8(s, os->opcode); 00250 00251 if (present & 0x0020) 00252 rdp_in_coord(s, &os->srcx, delta); 00253 00254 if (present & 0x0040) 00255 rdp_in_coord(s, &os->srcy, delta); 00256 00257 DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n", 00258 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy)); 00259 00260 ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy); 00261 } 00262 00263 /* Process a line order */ 00264 static void 00265 process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta) 00266 { 00267 if (present & 0x0001) 00268 in_uint16_le(s, os->mixmode); 00269 00270 if (present & 0x0002) 00271 rdp_in_coord(s, &os->startx, delta); 00272 00273 if (present & 0x0004) 00274 rdp_in_coord(s, &os->starty, delta); 00275 00276 if (present & 0x0008) 00277 rdp_in_coord(s, &os->endx, delta); 00278 00279 if (present & 0x0010) 00280 rdp_in_coord(s, &os->endy, delta); 00281 00282 if (present & 0x0020) 00283 rdp_in_colour(s, &os->bgcolour); 00284 00285 if (present & 0x0040) 00286 in_uint8(s, os->opcode); 00287 00288 rdp_parse_pen(s, &os->pen, present >> 7); 00289 00290 DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dy=%d,fg=0x%x)\n", 00291 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour)); 00292 00293 if (os->opcode < 0x01 || os->opcode > 0x10) 00294 { 00295 error("bad ROP2 0x%x\n", os->opcode); 00296 return; 00297 } 00298 00299 ui_line(ROP_MINUS_1(os->opcode), os->startx, os->starty, os->endx, os->endy, &os->pen); 00300 } 00301 00302 /* Process an opaque rectangle order */ 00303 static void 00304 process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta) 00305 { 00306 uint32 i; 00307 if (present & 0x01) 00308 rdp_in_coord(s, &os->x, delta); 00309 00310 if (present & 0x02) 00311 rdp_in_coord(s, &os->y, delta); 00312 00313 if (present & 0x04) 00314 rdp_in_coord(s, &os->cx, delta); 00315 00316 if (present & 0x08) 00317 rdp_in_coord(s, &os->cy, delta); 00318 00319 if (present & 0x10) 00320 { 00321 in_uint8(s, i); 00322 os->colour = (os->colour & 0xffffff00) | i; 00323 } 00324 00325 if (present & 0x20) 00326 { 00327 in_uint8(s, i); 00328 os->colour = (os->colour & 0xffff00ff) | (i << 8); 00329 } 00330 00331 if (present & 0x40) 00332 { 00333 in_uint8(s, i); 00334 os->colour = (os->colour & 0xff00ffff) | (i << 16); 00335 } 00336 00337 DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour)); 00338 00339 ui_rect(os->x, os->y, os->cx, os->cy, os->colour); 00340 } 00341 00342 /* Process a desktop save order */ 00343 static void 00344 process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta) 00345 { 00346 int width, height; 00347 00348 if (present & 0x01) 00349 in_uint32_le(s, os->offset); 00350 00351 if (present & 0x02) 00352 rdp_in_coord(s, &os->left, delta); 00353 00354 if (present & 0x04) 00355 rdp_in_coord(s, &os->top, delta); 00356 00357 if (present & 0x08) 00358 rdp_in_coord(s, &os->right, delta); 00359 00360 if (present & 0x10) 00361 rdp_in_coord(s, &os->bottom, delta); 00362 00363 if (present & 0x20) 00364 in_uint8(s, os->action); 00365 00366 DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n", 00367 os->left, os->top, os->right, os->bottom, os->offset, os->action)); 00368 00369 width = os->right - os->left + 1; 00370 height = os->bottom - os->top + 1; 00371 00372 if (os->action == 0) 00373 ui_desktop_save(os->offset, os->left, os->top, width, height); 00374 else 00375 ui_desktop_restore(os->offset, os->left, os->top, width, height); 00376 } 00377 00378 /* Process a memory blt order */ 00379 static void 00380 process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta) 00381 { 00382 HBITMAP bitmap; 00383 00384 if (present & 0x0001) 00385 { 00386 in_uint8(s, os->cache_id); 00387 in_uint8(s, os->colour_table); 00388 } 00389 00390 if (present & 0x0002) 00391 rdp_in_coord(s, &os->x, delta); 00392 00393 if (present & 0x0004) 00394 rdp_in_coord(s, &os->y, delta); 00395 00396 if (present & 0x0008) 00397 rdp_in_coord(s, &os->cx, delta); 00398 00399 if (present & 0x0010) 00400 rdp_in_coord(s, &os->cy, delta); 00401 00402 if (present & 0x0020) 00403 in_uint8(s, os->opcode); 00404 00405 if (present & 0x0040) 00406 rdp_in_coord(s, &os->srcx, delta); 00407 00408 if (present & 0x0080) 00409 rdp_in_coord(s, &os->srcy, delta); 00410 00411 if (present & 0x0100) 00412 in_uint16_le(s, os->cache_idx); 00413 00414 DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n", 00415 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx)); 00416 00417 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx); 00418 if (bitmap == NULL) 00419 return; 00420 00421 ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy); 00422 } 00423 00424 /* Process a 3-way blt order */ 00425 static void 00426 process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta) 00427 { 00428 HBITMAP bitmap; 00429 00430 if (present & 0x000001) 00431 { 00432 in_uint8(s, os->cache_id); 00433 in_uint8(s, os->colour_table); 00434 } 00435 00436 if (present & 0x000002) 00437 rdp_in_coord(s, &os->x, delta); 00438 00439 if (present & 0x000004) 00440 rdp_in_coord(s, &os->y, delta); 00441 00442 if (present & 0x000008) 00443 rdp_in_coord(s, &os->cx, delta); 00444 00445 if (present & 0x000010) 00446 rdp_in_coord(s, &os->cy, delta); 00447 00448 if (present & 0x000020) 00449 in_uint8(s, os->opcode); 00450 00451 if (present & 0x000040) 00452 rdp_in_coord(s, &os->srcx, delta); 00453 00454 if (present & 0x000080) 00455 rdp_in_coord(s, &os->srcy, delta); 00456 00457 if (present & 0x000100) 00458 rdp_in_colour(s, &os->bgcolour); 00459 00460 if (present & 0x000200) 00461 rdp_in_colour(s, &os->fgcolour); 00462 00463 rdp_parse_brush(s, &os->brush, present >> 10); 00464 00465 if (present & 0x008000) 00466 in_uint16_le(s, os->cache_idx); 00467 00468 if (present & 0x010000) 00469 in_uint16_le(s, os->unknown); 00470 00471 DEBUG(("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n", 00472 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx, 00473 os->brush.style, os->bgcolour, os->fgcolour)); 00474 00475 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx); 00476 if (bitmap == NULL) 00477 return; 00478 00479 ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy, 00480 bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour); 00481 } 00482 00483 /* Process a polygon order */ 00484 static void 00485 process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta) 00486 { 00487 int index, data, next; 00488 uint8 flags = 0; 00489 POINT *points; 00490 00491 if (present & 0x01) 00492 rdp_in_coord(s, &os->x, delta); 00493 00494 if (present & 0x02) 00495 rdp_in_coord(s, &os->y, delta); 00496 00497 if (present & 0x04) 00498 in_uint8(s, os->opcode); 00499 00500 if (present & 0x08) 00501 in_uint8(s, os->fillmode); 00502 00503 if (present & 0x10) 00504 rdp_in_colour(s, &os->fgcolour); 00505 00506 if (present & 0x20) 00507 in_uint8(s, os->npoints); 00508 00509 if (present & 0x40) 00510 { 00511 in_uint8(s, os->datasize); 00512 in_uint8a(s, os->data, os->datasize); 00513 } 00514 00515 DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n", 00516 os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize)); 00517 00518 DEBUG(("Data: ")); 00519 00520 for (index = 0; index < os->datasize; index++) 00521 DEBUG(("%02x ", os->data[index])); 00522 00523 DEBUG(("\n")); 00524 00525 if (os->opcode < 0x01 || os->opcode > 0x10) 00526 { 00527 error("bad ROP2 0x%x\n", os->opcode); 00528 return; 00529 } 00530 00531 points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT)); 00532 memset(points, 0, (os->npoints + 1) * sizeof(POINT)); 00533 00534 points[0].x = os->x; 00535 points[0].y = os->y; 00536 00537 index = 0; 00538 data = ((os->npoints - 1) / 4) + 1; 00539 for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++) 00540 { 00541 if ((next - 1) % 4 == 0) 00542 flags = os->data[index++]; 00543 00544 if (~flags & 0x80) 00545 points[next].x = parse_delta(os->data, &data); 00546 00547 if (~flags & 0x40) 00548 points[next].y = parse_delta(os->data, &data); 00549 00550 flags <<= 2; 00551 } 00552 00553 if (next - 1 == os->npoints) 00554 ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, NULL, 0, 00555 os->fgcolour); 00556 else 00557 error("polygon parse error\n"); 00558 00559 xfree(points); 00560 } 00561 00562 /* Process a polygon2 order */ 00563 static void 00564 process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta) 00565 { 00566 int index, data, next; 00567 uint8 flags = 0; 00568 POINT *points; 00569 00570 if (present & 0x0001) 00571 rdp_in_coord(s, &os->x, delta); 00572 00573 if (present & 0x0002) 00574 rdp_in_coord(s, &os->y, delta); 00575 00576 if (present & 0x0004) 00577 in_uint8(s, os->opcode); 00578 00579 if (present & 0x0008) 00580 in_uint8(s, os->fillmode); 00581 00582 if (present & 0x0010) 00583 rdp_in_colour(s, &os->bgcolour); 00584 00585 if (present & 0x0020) 00586 rdp_in_colour(s, &os->fgcolour); 00587 00588 rdp_parse_brush(s, &os->brush, present >> 6); 00589 00590 if (present & 0x0800) 00591 in_uint8(s, os->npoints); 00592 00593 if (present & 0x1000) 00594 { 00595 in_uint8(s, os->datasize); 00596 in_uint8a(s, os->data, os->datasize); 00597 } 00598 00599 DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n", 00600 os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour, 00601 os->npoints, os->datasize)); 00602 00603 DEBUG(("Data: ")); 00604 00605 for (index = 0; index < os->datasize; index++) 00606 DEBUG(("%02x ", os->data[index])); 00607 00608 DEBUG(("\n")); 00609 00610 if (os->opcode < 0x01 || os->opcode > 0x10) 00611 { 00612 error("bad ROP2 0x%x\n", os->opcode); 00613 return; 00614 } 00615 00616 points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT)); 00617 memset(points, 0, (os->npoints + 1) * sizeof(POINT)); 00618 00619 points[0].x = os->x; 00620 points[0].y = os->y; 00621 00622 index = 0; 00623 data = ((os->npoints - 1) / 4) + 1; 00624 for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++) 00625 { 00626 if ((next - 1) % 4 == 0) 00627 flags = os->data[index++]; 00628 00629 if (~flags & 0x80) 00630 points[next].x = parse_delta(os->data, &data); 00631 00632 if (~flags & 0x40) 00633 points[next].y = parse_delta(os->data, &data); 00634 00635 flags <<= 2; 00636 } 00637 00638 if (next - 1 == os->npoints) 00639 ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, 00640 &os->brush, os->bgcolour, os->fgcolour); 00641 else 00642 error("polygon2 parse error\n"); 00643 00644 xfree(points); 00645 } 00646 00647 /* Process a polyline order */ 00648 static void 00649 process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta) 00650 { 00651 int index, next, data; 00652 uint8 flags = 0; 00653 PEN pen; 00654 POINT *points; 00655 00656 if (present & 0x01) 00657 rdp_in_coord(s, &os->x, delta); 00658 00659 if (present & 0x02) 00660 rdp_in_coord(s, &os->y, delta); 00661 00662 if (present & 0x04) 00663 in_uint8(s, os->opcode); 00664 00665 if (present & 0x10) 00666 rdp_in_colour(s, &os->fgcolour); 00667 00668 if (present & 0x20) 00669 in_uint8(s, os->lines); 00670 00671 if (present & 0x40) 00672 { 00673 in_uint8(s, os->datasize); 00674 in_uint8a(s, os->data, os->datasize); 00675 } 00676 00677 DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n", 00678 os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize)); 00679 00680 DEBUG(("Data: ")); 00681 00682 for (index = 0; index < os->datasize; index++) 00683 DEBUG(("%02x ", os->data[index])); 00684 00685 DEBUG(("\n")); 00686 00687 if (os->opcode < 0x01 || os->opcode > 0x10) 00688 { 00689 error("bad ROP2 0x%x\n", os->opcode); 00690 return; 00691 } 00692 00693 points = (POINT *) xmalloc((os->lines + 1) * sizeof(POINT)); 00694 memset(points, 0, (os->lines + 1) * sizeof(POINT)); 00695 00696 points[0].x = os->x; 00697 points[0].y = os->y; 00698 pen.style = pen.width = 0; 00699 pen.colour = os->fgcolour; 00700 00701 index = 0; 00702 data = ((os->lines - 1) / 4) + 1; 00703 for (next = 1; (next <= os->lines) && (data < os->datasize); next++) 00704 { 00705 if ((next - 1) % 4 == 0) 00706 flags = os->data[index++]; 00707 00708 if (~flags & 0x80) 00709 points[next].x = parse_delta(os->data, &data); 00710 00711 if (~flags & 0x40) 00712 points[next].y = parse_delta(os->data, &data); 00713 00714 flags <<= 2; 00715 } 00716 00717 if (next - 1 == os->lines) 00718 ui_polyline(ROP_MINUS_1(os->opcode), points, os->lines + 1, &pen); 00719 else 00720 error("polyline parse error\n"); 00721 00722 xfree(points); 00723 } 00724 00725 /* Process an ellipse order */ 00726 static void 00727 process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, BOOL delta) 00728 { 00729 if (present & 0x01) 00730 rdp_in_coord(s, &os->left, delta); 00731 00732 if (present & 0x02) 00733 rdp_in_coord(s, &os->top, delta); 00734 00735 if (present & 0x04) 00736 rdp_in_coord(s, &os->right, delta); 00737 00738 if (present & 0x08) 00739 rdp_in_coord(s, &os->bottom, delta); 00740 00741 if (present & 0x10) 00742 in_uint8(s, os->opcode); 00743 00744 if (present & 0x20) 00745 in_uint8(s, os->fillmode); 00746 00747 if (present & 0x40) 00748 rdp_in_colour(s, &os->fgcolour); 00749 00750 DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top, 00751 os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour)); 00752 00753 ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left, 00754 os->bottom - os->top, NULL, 0, os->fgcolour); 00755 } 00756 00757 /* Process an ellipse2 order */ 00758 static void 00759 process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, BOOL delta) 00760 { 00761 if (present & 0x0001) 00762 rdp_in_coord(s, &os->left, delta); 00763 00764 if (present & 0x0002) 00765 rdp_in_coord(s, &os->top, delta); 00766 00767 if (present & 0x0004) 00768 rdp_in_coord(s, &os->right, delta); 00769 00770 if (present & 0x0008) 00771 rdp_in_coord(s, &os->bottom, delta); 00772 00773 if (present & 0x0010) 00774 in_uint8(s, os->opcode); 00775 00776 if (present & 0x0020) 00777 in_uint8(s, os->fillmode); 00778 00779 if (present & 0x0040) 00780 rdp_in_colour(s, &os->bgcolour); 00781 00782 if (present & 0x0080) 00783 rdp_in_colour(s, &os->fgcolour); 00784 00785 rdp_parse_brush(s, &os->brush, present >> 8); 00786 00787 DEBUG(("ELLIPSE2(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x)\n", 00788 os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style, 00789 os->bgcolour, os->fgcolour)); 00790 00791 ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left, 00792 os->bottom - os->top, &os->brush, os->bgcolour, os->fgcolour); 00793 } 00794 00795 /* Process a text order */ 00796 static void 00797 process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta) 00798 { 00799 int i; 00800 00801 if (present & 0x000001) 00802 in_uint8(s, os->font); 00803 00804 if (present & 0x000002) 00805 in_uint8(s, os->flags); 00806 00807 if (present & 0x000004) 00808 in_uint8(s, os->opcode); 00809 00810 if (present & 0x000008) 00811 in_uint8(s, os->mixmode); 00812 00813 if (present & 0x000010) 00814 rdp_in_colour(s, &os->fgcolour); 00815 00816 if (present & 0x000020) 00817 rdp_in_colour(s, &os->bgcolour); 00818 00819 if (present & 0x000040) 00820 in_uint16_le(s, os->clipleft); 00821 00822 if (present & 0x000080) 00823 in_uint16_le(s, os->cliptop); 00824 00825 if (present & 0x000100) 00826 in_uint16_le(s, os->clipright); 00827 00828 if (present & 0x000200) 00829 in_uint16_le(s, os->clipbottom); 00830 00831 if (present & 0x000400) 00832 in_uint16_le(s, os->boxleft); 00833 00834 if (present & 0x000800) 00835 in_uint16_le(s, os->boxtop); 00836 00837 if (present & 0x001000) 00838 in_uint16_le(s, os->boxright); 00839 00840 if (present & 0x002000) 00841 in_uint16_le(s, os->boxbottom); 00842 00843 rdp_parse_brush(s, &os->brush, present >> 14); 00844 00845 if (present & 0x080000) 00846 in_uint16_le(s, os->x); 00847 00848 if (present & 0x100000) 00849 in_uint16_le(s, os->y); 00850 00851 if (present & 0x200000) 00852 { 00853 in_uint8(s, os->length); 00854 in_uint8a(s, os->text, os->length); 00855 } 00856 00857 DEBUG(("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,br=%d,bb=%d,bs=%d,bg=0x%x,fg=0x%x,font=%d,fl=0x%x,op=0x%x,mix=%d,n=%d)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->brush.style, os->bgcolour, os->fgcolour, os->font, os->flags, os->opcode, os->mixmode, os->length)); 00858 00859 DEBUG(("Text: ")); 00860 00861 for (i = 0; i < os->length; i++) 00862 DEBUG(("%02x ", os->text[i])); 00863 00864 DEBUG(("\n")); 00865 00866 ui_draw_text(os->font, os->flags, ROP_MINUS_1(os->opcode), os->mixmode, os->x, os->y, 00867 os->clipleft, os->cliptop, os->clipright - os->clipleft, 00868 os->clipbottom - os->cliptop, os->boxleft, os->boxtop, 00869 os->boxright - os->boxleft, os->boxbottom - os->boxtop, 00870 &os->brush, os->bgcolour, os->fgcolour, os->text, os->length); 00871 } 00872 00873 /* Process a raw bitmap cache order */ 00874 static void 00875 process_raw_bmpcache(STREAM s) 00876 { 00877 HBITMAP bitmap; 00878 uint16 cache_idx, bufsize; 00879 uint8 cache_id, width, height, bpp, Bpp; 00880 uint8 *data, *inverted; 00881 int y; 00882 00883 in_uint8(s, cache_id); 00884 in_uint8s(s, 1); /* pad */ 00885 in_uint8(s, width); 00886 in_uint8(s, height); 00887 in_uint8(s, bpp); 00888 Bpp = (bpp + 7) / 8; 00889 in_uint16_le(s, bufsize); 00890 in_uint16_le(s, cache_idx); 00891 in_uint8p(s, data, bufsize); 00892 00893 DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); 00894 inverted = (uint8 *) xmalloc(width * height * Bpp); 00895 for (y = 0; y < height; y++) 00896 { 00897 memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)], 00898 width * Bpp); 00899 } 00900 00901 bitmap = ui_create_bitmap(width, height, inverted); 00902 xfree(inverted); 00903 cache_put_bitmap(cache_id, cache_idx, bitmap); 00904 } 00905 00906 /* Process a bitmap cache order */ 00907 static void 00908 process_bmpcache(STREAM s) 00909 { 00910 HBITMAP bitmap; 00911 uint16 cache_idx, size; 00912 uint8 cache_id, width, height, bpp, Bpp; 00913 uint8 *data, *bmpdata; 00914 uint16 bufsize, pad2, row_size, final_size; 00915 uint8 pad1; 00916 00917 pad2 = row_size = final_size = 0xffff; /* Shut the compiler up */ 00918 00919 in_uint8(s, cache_id); 00920 in_uint8(s, pad1); /* pad */ 00921 in_uint8(s, width); 00922 in_uint8(s, height); 00923 in_uint8(s, bpp); 00924 Bpp = (bpp + 7) / 8; 00925 in_uint16_le(s, bufsize); /* bufsize */ 00926 in_uint16_le(s, cache_idx); 00927 00928 if (g_use_rdp5) 00929 { 00930 size = bufsize; 00931 } 00932 else 00933 { 00934 00935 /* Begin compressedBitmapData */ 00936 in_uint16_le(s, pad2); /* pad */ 00937 in_uint16_le(s, size); 00938 /* in_uint8s(s, 4); *//* row_size, final_size */ 00939 in_uint16_le(s, row_size); 00940 in_uint16_le(s, final_size); 00941 00942 } 00943 in_uint8p(s, data, size); 00944 00945 DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d,bpp=%d,size=%d,pad1=%d,bufsize=%d,pad2=%d,rs=%d,fs=%d)\n", width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size, final_size)); 00946 (void)pad1; (void)pad2; 00947 00948 bmpdata = (uint8 *) xmalloc(width * height * Bpp); 00949 00950 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) 00951 { 00952 bitmap = ui_create_bitmap(width, height, bmpdata); 00953 cache_put_bitmap(cache_id, cache_idx, bitmap); 00954 } 00955 else 00956 { 00957 DEBUG(("Failed to decompress bitmap data\n")); 00958 } 00959 00960 xfree(bmpdata); 00961 } 00962 00963 /* Process a bitmap cache v2 order */ 00964 static void 00965 process_bmpcache2(STREAM s, uint16 flags, BOOL compressed) 00966 { 00967 HBITMAP bitmap; 00968 int y; 00969 uint8 cache_id, cache_idx_low, width, height, Bpp; 00970 uint16 cache_idx, bufsize; 00971 uint8 *data, *bmpdata, *bitmap_id; 00972 00973 bitmap_id = NULL; /* prevent compiler warning */ 00974 cache_id = flags & ID_MASK; 00975 Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2; 00976 00977 if (flags & PERSIST) 00978 { 00979 in_uint8p(s, bitmap_id, 8); 00980 } 00981 00982 if (flags & SQUARE) 00983 { 00984 in_uint8(s, width); 00985 height = width; 00986 } 00987 else 00988 { 00989 in_uint8(s, width); 00990 in_uint8(s, height); 00991 } 00992 00993 in_uint16_be(s, bufsize); 00994 bufsize &= BUFSIZE_MASK; 00995 in_uint8(s, cache_idx); 00996 00997 if (cache_idx & LONG_FORMAT) 00998 { 00999 in_uint8(s, cache_idx_low); 01000 cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low; 01001 } 01002 01003 in_uint8p(s, data, bufsize); 01004 01005 DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n", 01006 compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize)); 01007 01008 bmpdata = (uint8 *) xmalloc(width * height * Bpp); 01009 01010 if (compressed) 01011 { 01012 if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp)) 01013 { 01014 DEBUG(("Failed to decompress bitmap data\n")); 01015 xfree(bmpdata); 01016 return; 01017 } 01018 } 01019 else 01020 { 01021 for (y = 0; y < height; y++) 01022 memcpy(&bmpdata[(height - y - 1) * (width * Bpp)], 01023 &data[y * (width * Bpp)], width * Bpp); 01024 } 01025 01026 bitmap = ui_create_bitmap(width, height, bmpdata); 01027 01028 if (bitmap) 01029 { 01030 cache_put_bitmap(cache_id, cache_idx, bitmap); 01031 if (flags & PERSIST) 01032 pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height, 01033 (uint16) (width * height * Bpp), bmpdata); 01034 } 01035 else 01036 { 01037 DEBUG(("process_bmpcache2: ui_create_bitmap failed\n")); 01038 } 01039 01040 xfree(bmpdata); 01041 } 01042 01043 /* Process a colourmap cache order */ 01044 static void 01045 process_colcache(STREAM s) 01046 { 01047 COLOURENTRY *entry; 01048 COLOURMAP map; 01049 RD_HCOLOURMAP hmap; 01050 uint8 cache_id; 01051 int i; 01052 01053 in_uint8(s, cache_id); 01054 in_uint16_le(s, map.ncolours); 01055 01056 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); 01057 01058 for (i = 0; i < map.ncolours; i++) 01059 { 01060 entry = &map.colours[i]; 01061 in_uint8(s, entry->blue); 01062 in_uint8(s, entry->green); 01063 in_uint8(s, entry->red); 01064 in_uint8s(s, 1); /* pad */ 01065 } 01066 01067 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours)); 01068 01069 hmap = ui_create_colourmap(&map); 01070 01071 if (cache_id) 01072 ui_set_colourmap(hmap); 01073 01074 xfree(map.colours); 01075 } 01076 01077 /* Process a font cache order */ 01078 static void 01079 process_fontcache(STREAM s) 01080 { 01081 RD_HGLYPH bitmap; 01082 uint8 font, nglyphs; 01083 uint16 character, offset, baseline, width, height; 01084 int i, datasize; 01085 uint8 *data; 01086 01087 in_uint8(s, font); 01088 in_uint8(s, nglyphs); 01089 01090 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs)); 01091 01092 for (i = 0; i < nglyphs; i++) 01093 { 01094 in_uint16_le(s, character); 01095 in_uint16_le(s, offset); 01096 in_uint16_le(s, baseline); 01097 in_uint16_le(s, width); 01098 in_uint16_le(s, height); 01099 01100 datasize = (height * ((width + 7) / 8) + 3) & ~3; 01101 in_uint8p(s, data, datasize); 01102 01103 bitmap = ui_create_glyph(width, height, data); 01104 cache_put_font(font, character, offset, baseline, width, height, bitmap); 01105 } 01106 } 01107 01108 /* Process a secondary order */ 01109 static void 01110 process_secondary_order(STREAM s) 01111 { 01112 /* The length isn't calculated correctly by the server. 01113 * For very compact orders the length becomes negative 01114 * so a signed integer must be used. */ 01115 uint16 length; 01116 uint16 flags; 01117 uint8 type; 01118 uint8 *next_order; 01119 01120 in_uint16_le(s, length); 01121 in_uint16_le(s, flags); /* used by bmpcache2 */ 01122 in_uint8(s, type); 01123 01124 next_order = s->p + (sint16) length + 7; 01125 01126 switch (type) 01127 { 01128 case RDP_ORDER_RAW_BMPCACHE: 01129 process_raw_bmpcache(s); 01130 break; 01131 01132 case RDP_ORDER_COLCACHE: 01133 process_colcache(s); 01134 break; 01135 01136 case RDP_ORDER_BMPCACHE: 01137 process_bmpcache(s); 01138 break; 01139 01140 case RDP_ORDER_FONTCACHE: 01141 process_fontcache(s); 01142 break; 01143 01144 case RDP_ORDER_RAW_BMPCACHE2: 01145 process_bmpcache2(s, flags, False); /* uncompressed */ 01146 break; 01147 01148 case RDP_ORDER_BMPCACHE2: 01149 process_bmpcache2(s, flags, True); /* compressed */ 01150 break; 01151 01152 default: 01153 unimpl("secondary order %d\n", type); 01154 } 01155 01156 s->p = next_order; 01157 } 01158 01159 /* Process an order PDU */ 01160 void 01161 process_orders(STREAM s, uint16 num_orders) 01162 { 01163 RDP_ORDER_STATE *os = &g_order_state; 01164 uint32 present; 01165 uint8 order_flags; 01166 int size, processed = 0; 01167 BOOL delta; 01168 01169 while (processed < num_orders) 01170 { 01171 in_uint8(s, order_flags); 01172 01173 if (!(order_flags & RDP_ORDER_STANDARD)) 01174 { 01175 error("order parsing failed\n"); 01176 break; 01177 } 01178 01179 if (order_flags & RDP_ORDER_SECONDARY) 01180 { 01181 process_secondary_order(s); 01182 } 01183 else 01184 { 01185 if (order_flags & RDP_ORDER_CHANGE) 01186 { 01187 in_uint8(s, os->order_type); 01188 } 01189 01190 switch (os->order_type) 01191 { 01192 case RDP_ORDER_TRIBLT: 01193 case RDP_ORDER_TEXT2: 01194 size = 3; 01195 break; 01196 01197 case RDP_ORDER_PATBLT: 01198 case RDP_ORDER_MEMBLT: 01199 case RDP_ORDER_LINE: 01200 case RDP_ORDER_POLYGON2: 01201 case RDP_ORDER_ELLIPSE2: 01202 size = 2; 01203 break; 01204 01205 default: 01206 size = 1; 01207 } 01208 01209 rdp_in_present(s, &present, order_flags, size); 01210 01211 if (order_flags & RDP_ORDER_BOUNDS) 01212 { 01213 if (!(order_flags & RDP_ORDER_LASTBOUNDS)) 01214 rdp_parse_bounds(s, &os->bounds); 01215 01216 ui_set_clip(os->bounds.left, 01217 os->bounds.top, 01218 os->bounds.right - 01219 os->bounds.left + 1, 01220 os->bounds.bottom - os->bounds.top + 1); 01221 } 01222 01223 delta = order_flags & RDP_ORDER_DELTA; 01224 01225 switch (os->order_type) 01226 { 01227 case RDP_ORDER_DESTBLT: 01228 process_destblt(s, &os->destblt, present, delta); 01229 break; 01230 01231 case RDP_ORDER_PATBLT: 01232 process_patblt(s, &os->patblt, present, delta); 01233 break; 01234 01235 case RDP_ORDER_SCREENBLT: 01236 process_screenblt(s, &os->screenblt, present, delta); 01237 break; 01238 01239 case RDP_ORDER_LINE: 01240 process_line(s, &os->line, present, delta); 01241 break; 01242 01243 case RDP_ORDER_RECT: 01244 process_rect(s, &os->rect, present, delta); 01245 break; 01246 01247 case RDP_ORDER_DESKSAVE: 01248 process_desksave(s, &os->desksave, present, delta); 01249 break; 01250 01251 case RDP_ORDER_MEMBLT: 01252 process_memblt(s, &os->memblt, present, delta); 01253 break; 01254 01255 case RDP_ORDER_TRIBLT: 01256 process_triblt(s, &os->triblt, present, delta); 01257 break; 01258 01259 case RDP_ORDER_POLYGON: 01260 process_polygon(s, &os->polygon, present, delta); 01261 break; 01262 01263 case RDP_ORDER_POLYGON2: 01264 process_polygon2(s, &os->polygon2, present, delta); 01265 break; 01266 01267 case RDP_ORDER_POLYLINE: 01268 process_polyline(s, &os->polyline, present, delta); 01269 break; 01270 01271 case RDP_ORDER_ELLIPSE: 01272 process_ellipse(s, &os->ellipse, present, delta); 01273 break; 01274 01275 case RDP_ORDER_ELLIPSE2: 01276 process_ellipse2(s, &os->ellipse2, present, delta); 01277 break; 01278 01279 case RDP_ORDER_TEXT2: 01280 process_text2(s, &os->text2, present, delta); 01281 break; 01282 01283 default: 01284 unimpl("order %d\n", os->order_type); 01285 return; 01286 } 01287 01288 if (order_flags & RDP_ORDER_BOUNDS) 01289 ui_reset_clip(); 01290 } 01291 01292 processed++; 01293 } 01294 #if 0 01295 /* not true when RDP_COMPRESSION is set */ 01296 if (s->p != g_next_packet) 01297 error("%d bytes remaining\n", (int) (g_next_packet - s->p)); 01298 #endif 01299 01300 } 01301 01302 /* Reset order state */ 01303 void 01304 reset_order_state(void) 01305 { 01306 memset(&g_order_state, 0, sizeof(g_order_state)); 01307 g_order_state.order_type = RDP_ORDER_PATBLT; 01308 } Generated on Sun May 27 2012 04:17:10 for ReactOS by
1.7.6.1
|