00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "rdesktop.h"
00022 #include "orders.h"
00023
00024 extern uint8 *next_packet;
00025 static RDP_ORDER_STATE order_state;
00026
00027
00028 static void
00029 rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
00030 {
00031 uint8 bits;
00032 int i;
00033
00034 if (flags & RDP_ORDER_SMALL)
00035 {
00036 size--;
00037 }
00038
00039 if (flags & RDP_ORDER_TINY)
00040 {
00041 if (size < 2)
00042 size = 0;
00043 else
00044 size -= 2;
00045 }
00046
00047 *present = 0;
00048 for (i = 0; i < size; i++)
00049 {
00050 in_uint8(s, bits);
00051 *present |= bits << (i * 8);
00052 }
00053 }
00054
00055
00056 static void
00057 rdp_in_coord(STREAM s, sint16 * coord, BOOL delta)
00058 {
00059 sint8 change;
00060
00061 if (delta)
00062 {
00063 in_uint8(s, change);
00064 *coord += change;
00065 }
00066 else
00067 {
00068 in_uint16_le(s, *coord);
00069 }
00070 }
00071
00072
00073 static void
00074 rdp_in_colour(STREAM s, uint32 * colour)
00075 {
00076 uint32 i;
00077 in_uint8(s, i);
00078 *colour = i;
00079 in_uint8(s, i);
00080 *colour |= i << 8;
00081 in_uint8(s, i);
00082 *colour |= i << 16;
00083 }
00084
00085
00086 static BOOL
00087 rdp_parse_bounds(STREAM s, BOUNDS * bounds)
00088 {
00089 uint8 present;
00090
00091 in_uint8(s, present);
00092
00093 if (present & 1)
00094 rdp_in_coord(s, &bounds->left, False);
00095 else if (present & 16)
00096 rdp_in_coord(s, &bounds->left, True);
00097
00098 if (present & 2)
00099 rdp_in_coord(s, &bounds->top, False);
00100 else if (present & 32)
00101 rdp_in_coord(s, &bounds->top, True);
00102
00103 if (present & 4)
00104 rdp_in_coord(s, &bounds->right, False);
00105 else if (present & 64)
00106 rdp_in_coord(s, &bounds->right, True);
00107
00108 if (present & 8)
00109 rdp_in_coord(s, &bounds->bottom, False);
00110 else if (present & 128)
00111 rdp_in_coord(s, &bounds->bottom, True);
00112
00113 return s_check(s);
00114 }
00115
00116
00117 static BOOL
00118 rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
00119 {
00120 if (present & 1)
00121 in_uint8(s, pen->style);
00122
00123 if (present & 2)
00124 in_uint8(s, pen->width);
00125
00126 if (present & 4)
00127 rdp_in_colour(s, &pen->colour);
00128
00129 return s_check(s);
00130 }
00131
00132
00133 static BOOL
00134 rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
00135 {
00136 if (present & 1)
00137 in_uint8(s, brush->xorigin);
00138
00139 if (present & 2)
00140 in_uint8(s, brush->yorigin);
00141
00142 if (present & 4)
00143 in_uint8(s, brush->style);
00144
00145 if (present & 8)
00146 in_uint8(s, brush->pattern[0]);
00147
00148 if (present & 16)
00149 in_uint8a(s, &brush->pattern[1], 7);
00150
00151 return s_check(s);
00152 }
00153
00154
00155 static void
00156 process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
00157 {
00158 if (present & 0x01)
00159 rdp_in_coord(s, &os->x, delta);
00160
00161 if (present & 0x02)
00162 rdp_in_coord(s, &os->y, delta);
00163
00164 if (present & 0x04)
00165 rdp_in_coord(s, &os->cx, delta);
00166
00167 if (present & 0x08)
00168 rdp_in_coord(s, &os->cy, delta);
00169
00170 if (present & 0x10)
00171 in_uint8(s, os->opcode);
00172
00173 DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",
00174 os->opcode, os->x, os->y, os->cx, os->cy));
00175
00176 ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
00177 }
00178
00179
00180 static void
00181 process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
00182 {
00183 if (present & 0x0001)
00184 rdp_in_coord(s, &os->x, delta);
00185
00186 if (present & 0x0002)
00187 rdp_in_coord(s, &os->y, delta);
00188
00189 if (present & 0x0004)
00190 rdp_in_coord(s, &os->cx, delta);
00191
00192 if (present & 0x0008)
00193 rdp_in_coord(s, &os->cy, delta);
00194
00195 if (present & 0x0010)
00196 in_uint8(s, os->opcode);
00197
00198 if (present & 0x0020)
00199 rdp_in_colour(s, &os->bgcolour);
00200
00201 if (present & 0x0040)
00202 rdp_in_colour(s, &os->fgcolour);
00203
00204 rdp_parse_brush(s, &os->brush, present >> 7);
00205
00206 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,
00207 os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
00208
00209 ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
00210 &os->brush, os->bgcolour, os->fgcolour);
00211 }
00212
00213
00214 static void
00215 process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
00216 {
00217 if (present & 0x0001)
00218 rdp_in_coord(s, &os->x, delta);
00219
00220 if (present & 0x0002)
00221 rdp_in_coord(s, &os->y, delta);
00222
00223 if (present & 0x0004)
00224 rdp_in_coord(s, &os->cx, delta);
00225
00226 if (present & 0x0008)
00227 rdp_in_coord(s, &os->cy, delta);
00228
00229 if (present & 0x0010)
00230 in_uint8(s, os->opcode);
00231
00232 if (present & 0x0020)
00233 rdp_in_coord(s, &os->srcx, delta);
00234
00235 if (present & 0x0040)
00236 rdp_in_coord(s, &os->srcy, delta);
00237
00238 DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",
00239 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy));
00240
00241 ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
00242 }
00243
00244
00245 static void
00246 process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
00247 {
00248 if (present & 0x0001)
00249 in_uint16_le(s, os->mixmode);
00250
00251 if (present & 0x0002)
00252 rdp_in_coord(s, &os->startx, delta);
00253
00254 if (present & 0x0004)
00255 rdp_in_coord(s, &os->starty, delta);
00256
00257 if (present & 0x0008)
00258 rdp_in_coord(s, &os->endx, delta);
00259
00260 if (present & 0x0010)
00261 rdp_in_coord(s, &os->endy, delta);
00262
00263 if (present & 0x0020)
00264 rdp_in_colour(s, &os->bgcolour);
00265
00266 if (present & 0x0040)
00267 in_uint8(s, os->opcode);
00268
00269 rdp_parse_pen(s, &os->pen, present >> 7);
00270
00271 DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",
00272 os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour));
00273
00274 if (os->opcode < 0x01 || os->opcode > 0x10)
00275 {
00276 error("bad ROP2 0x%x\n", os->opcode);
00277 return;
00278 }
00279
00280 ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
00281 }
00282
00283
00284 static void
00285 process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
00286 {
00287 uint32 i;
00288 if (present & 0x01)
00289 rdp_in_coord(s, &os->x, delta);
00290
00291 if (present & 0x02)
00292 rdp_in_coord(s, &os->y, delta);
00293
00294 if (present & 0x04)
00295 rdp_in_coord(s, &os->cx, delta);
00296
00297 if (present & 0x08)
00298 rdp_in_coord(s, &os->cy, delta);
00299
00300 if (present & 0x10)
00301 {
00302 in_uint8(s, i);
00303 os->colour = (os->colour & 0xffffff00) | i;
00304 }
00305
00306 if (present & 0x20)
00307 {
00308 in_uint8(s, i);
00309 os->colour = (os->colour & 0xffff00ff) | (i << 8);
00310 }
00311
00312 if (present & 0x40)
00313 {
00314 in_uint8(s, i);
00315 os->colour = (os->colour & 0xff00ffff) | (i << 16);
00316 }
00317
00318 DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour));
00319
00320 ui_rect(os->x, os->y, os->cx, os->cy, os->colour);
00321 }
00322
00323
00324 static void
00325 process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
00326 {
00327 int width, height;
00328
00329 if (present & 0x01)
00330 in_uint32_le(s, os->offset);
00331
00332 if (present & 0x02)
00333 rdp_in_coord(s, &os->left, delta);
00334
00335 if (present & 0x04)
00336 rdp_in_coord(s, &os->top, delta);
00337
00338 if (present & 0x08)
00339 rdp_in_coord(s, &os->right, delta);
00340
00341 if (present & 0x10)
00342 rdp_in_coord(s, &os->bottom, delta);
00343
00344 if (present & 0x20)
00345 in_uint8(s, os->action);
00346
00347 DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",
00348 os->left, os->top, os->right, os->bottom, os->offset, os->action));
00349
00350 width = os->right - os->left + 1;
00351 height = os->bottom - os->top + 1;
00352
00353 if (os->action == 0)
00354 ui_desktop_save(os->offset, os->left, os->top, width, height);
00355 else
00356 ui_desktop_restore(os->offset, os->left, os->top, width, height);
00357 }
00358
00359
00360 static void
00361 process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
00362 {
00363 HBITMAP bitmap;
00364
00365 if (present & 0x0001)
00366 {
00367 in_uint8(s, os->cache_id);
00368 in_uint8(s, os->colour_table);
00369 }
00370
00371 if (present & 0x0002)
00372 rdp_in_coord(s, &os->x, delta);
00373
00374 if (present & 0x0004)
00375 rdp_in_coord(s, &os->y, delta);
00376
00377 if (present & 0x0008)
00378 rdp_in_coord(s, &os->cx, delta);
00379
00380 if (present & 0x0010)
00381 rdp_in_coord(s, &os->cy, delta);
00382
00383 if (present & 0x0020)
00384 in_uint8(s, os->opcode);
00385
00386 if (present & 0x0040)
00387 rdp_in_coord(s, &os->srcx, delta);
00388
00389 if (present & 0x0080)
00390 rdp_in_coord(s, &os->srcy, delta);
00391
00392 if (present & 0x0100)
00393 in_uint16_le(s, os->cache_idx);
00394
00395 DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
00396 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx));
00397
00398 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
00399 if (bitmap == NULL)
00400 return;
00401
00402 ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy);
00403 }
00404
00405
00406 static void
00407 process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
00408 {
00409 HBITMAP bitmap;
00410
00411 if (present & 0x000001)
00412 {
00413 in_uint8(s, os->cache_id);
00414 in_uint8(s, os->colour_table);
00415 }
00416
00417 if (present & 0x000002)
00418 rdp_in_coord(s, &os->x, delta);
00419
00420 if (present & 0x000004)
00421 rdp_in_coord(s, &os->y, delta);
00422
00423 if (present & 0x000008)
00424 rdp_in_coord(s, &os->cx, delta);
00425
00426 if (present & 0x000010)
00427 rdp_in_coord(s, &os->cy, delta);
00428
00429 if (present & 0x000020)
00430 in_uint8(s, os->opcode);
00431
00432 if (present & 0x000040)
00433 rdp_in_coord(s, &os->srcx, delta);
00434
00435 if (present & 0x000080)
00436 rdp_in_coord(s, &os->srcy, delta);
00437
00438 if (present & 0x000100)
00439 rdp_in_colour(s, &os->bgcolour);
00440
00441 if (present & 0x000200)
00442 rdp_in_colour(s, &os->fgcolour);
00443
00444 rdp_parse_brush(s, &os->brush, present >> 10);
00445
00446 if (present & 0x008000)
00447 in_uint16_le(s, os->cache_idx);
00448
00449 if (present & 0x010000)
00450 in_uint16_le(s, os->unknown);
00451
00452 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",
00453 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx,
00454 os->brush.style, os->bgcolour, os->fgcolour));
00455
00456 bitmap = cache_get_bitmap(os->cache_id, os->cache_idx);
00457 if (bitmap == NULL)
00458 return;
00459
00460 ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
00461 bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
00462 }
00463
00464
00465 static int
00466 parse_delta(uint8 * buffer, int *offset)
00467 {
00468 int value = buffer[(*offset)++];
00469 int two_byte = value & 0x80;
00470
00471 if (value & 0x40)
00472 value |= ~0x3f;
00473 else
00474 value &= 0x3f;
00475
00476 if (two_byte)
00477 value = (value << 8) | buffer[(*offset)++];
00478
00479 return value;
00480 }
00481
00482
00483 static void
00484 process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
00485 {
00486 int index, line, data;
00487 int x, y, xfrom, yfrom;
00488 uint8 flags = 0;
00489 PEN pen;
00490 uint8 opcode;
00491
00492 if (present & 0x01)
00493 rdp_in_coord(s, &os->x, delta);
00494
00495 if (present & 0x02)
00496 rdp_in_coord(s, &os->y, delta);
00497
00498 if (present & 0x04)
00499 in_uint8(s, os->opcode);
00500
00501 if (present & 0x10)
00502 rdp_in_colour(s, &os->fgcolour);
00503
00504 if (present & 0x20)
00505 in_uint8(s, os->lines);
00506
00507 if (present & 0x40)
00508 {
00509 in_uint8(s, os->datasize);
00510 in_uint8a(s, os->data, os->datasize);
00511 }
00512
00513 DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n",
00514 os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize));
00515
00516 DEBUG(("Data: "));
00517
00518 for (index = 0; index < os->datasize; index++)
00519 DEBUG(("%02x ", os->data[index]));
00520
00521 DEBUG(("\n"));
00522
00523 if (os->opcode < 0x01 || os->opcode > 0x10)
00524 {
00525 error("bad ROP2 0x%x\n", os->opcode);
00526 return;
00527 }
00528
00529 opcode = os->opcode - 1;
00530 x = os->x;
00531 y = os->y;
00532 pen.style = pen.width = 0;
00533 pen.colour = os->fgcolour;
00534
00535 index = 0;
00536 data = ((os->lines - 1) / 4) + 1;
00537 for (line = 0; (line < os->lines) && (data < os->datasize); line++)
00538 {
00539 xfrom = x;
00540 yfrom = y;
00541
00542 if (line % 4 == 0)
00543 flags = os->data[index++];
00544
00545 if ((flags & 0xc0) == 0)
00546 flags |= 0xc0;
00547
00548 if (flags & 0x40)
00549 x += parse_delta(os->data, &data);
00550
00551 if (flags & 0x80)
00552 y += parse_delta(os->data, &data);
00553
00554 ui_line(opcode, xfrom, yfrom, x, y, &pen);
00555
00556 flags <<= 2;
00557 }
00558 }
00559
00560
00561 static void
00562 process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
00563 {
00564 int i;
00565
00566 if (present & 0x000001)
00567 in_uint8(s, os->font);
00568
00569 if (present & 0x000002)
00570 in_uint8(s, os->flags);
00571
00572 if (present & 0x000004)
00573 in_uint8(s, os->unknown);
00574
00575 if (present & 0x000008)
00576 in_uint8(s, os->mixmode);
00577
00578 if (present & 0x000010)
00579 rdp_in_colour(s, &os->fgcolour);
00580
00581 if (present & 0x000020)
00582 rdp_in_colour(s, &os->bgcolour);
00583
00584 if (present & 0x000040)
00585 in_uint16_le(s, os->clipleft);
00586
00587 if (present & 0x000080)
00588 in_uint16_le(s, os->cliptop);
00589
00590 if (present & 0x000100)
00591 in_uint16_le(s, os->clipright);
00592
00593 if (present & 0x000200)
00594 in_uint16_le(s, os->clipbottom);
00595
00596 if (present & 0x000400)
00597 in_uint16_le(s, os->boxleft);
00598
00599 if (present & 0x000800)
00600 in_uint16_le(s, os->boxtop);
00601
00602 if (present & 0x001000)
00603 in_uint16_le(s, os->boxright);
00604
00605 if (present & 0x002000)
00606 in_uint16_le(s, os->boxbottom);
00607
00608 if (present & 0x004000)
00609 in_uint8s(s, 10);
00610
00611
00612 if (present & 0x080000)
00613 in_uint16_le(s, os->x);
00614
00615 if (present & 0x100000)
00616 in_uint16_le(s, os->y);
00617
00618 if (present & 0x200000)
00619 {
00620 in_uint8(s, os->length);
00621 in_uint8a(s, os->text, os->length);
00622 }
00623
00624 DEBUG(("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,bb=%d,br=%d,fg=0x%x,bg=0x%x,font=%d,fl=0x%x,mix=%d,unk=0x%x,n=%d)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->fgcolour, os->bgcolour, os->font, os->flags, os->mixmode, os->unknown, os->length));
00625
00626 DEBUG(("Text: "));
00627
00628 for (i = 0; i < os->length; i++)
00629 DEBUG(("%02x ", os->text[i]));
00630
00631 DEBUG(("\n"));
00632
00633 ui_draw_text(os->font, os->flags, os->mixmode, os->x, os->y,
00634 os->clipleft, os->cliptop,
00635 os->clipright - os->clipleft,
00636 os->clipbottom - os->cliptop,
00637 os->boxleft, os->boxtop,
00638 os->boxright - os->boxleft,
00639 os->boxbottom - os->boxtop, os->bgcolour, os->fgcolour, os->text, os->length);
00640 }
00641
00642
00643 static void
00644 process_raw_bmpcache(STREAM s)
00645 {
00646 HBITMAP bitmap;
00647 uint16 cache_idx, bufsize;
00648 uint8 cache_id, width, height, bpp, Bpp;
00649 uint8 *data, *inverted;
00650 int y;
00651
00652 in_uint8(s, cache_id);
00653 in_uint8s(s, 1);
00654 in_uint8(s, width);
00655 in_uint8(s, height);
00656 in_uint8(s, bpp);
00657 Bpp = (bpp + 7) / 8;
00658 in_uint16_le(s, bufsize);
00659 in_uint16_le(s, cache_idx);
00660 in_uint8p(s, data, bufsize);
00661
00662 DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
00663 inverted = (uint8*)xmalloc(width * height * Bpp);
00664 for (y = 0; y < height; y++)
00665 {
00666 memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)],
00667 width * Bpp);
00668 }
00669
00670 bitmap = ui_create_bitmap(width, height, inverted);
00671 xfree(inverted);
00672 cache_put_bitmap(cache_id, cache_idx, bitmap);
00673 }
00674
00675
00676 static void
00677 process_bmpcache(STREAM s)
00678 {
00679 HBITMAP bitmap;
00680 uint16 cache_idx, size;
00681 uint8 cache_id, width, height, bpp, Bpp;
00682 uint8 *data, *bmpdata;
00683
00684 in_uint8(s, cache_id);
00685 in_uint8s(s, 1);
00686 in_uint8(s, width);
00687 in_uint8(s, height);
00688 in_uint8(s, bpp);
00689 Bpp = (bpp + 7) / 8;
00690 in_uint8s(s, 2);
00691 in_uint16_le(s, cache_idx);
00692 in_uint8s(s, 2);
00693 in_uint16_le(s, size);
00694 in_uint8s(s, 4);
00695 in_uint8p(s, data, size);
00696 DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
00697 bmpdata = (uint8*)xmalloc(width * height * Bpp);
00698 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
00699 {
00700 bitmap = ui_create_bitmap(width, height, bmpdata);
00701 cache_put_bitmap(cache_id, cache_idx, bitmap);
00702 }
00703 xfree(bmpdata);
00704 }
00705
00706
00707 static void
00708 process_colcache(STREAM s)
00709 {
00710 COLOURENTRY *entry;
00711 COLOURMAP map;
00712 HCOLOURMAP hmap;
00713 uint8 cache_id;
00714 int i;
00715 in_uint8(s, cache_id);
00716 in_uint16_le(s, map.ncolours);
00717
00718 map.colours = (COLOURENTRY*)xmalloc(3 * map.ncolours);
00719
00720 for (i = 0; i < map.ncolours; i++)
00721 {
00722 entry = &map.colours[i];
00723 in_uint8(s, entry->blue);
00724 in_uint8(s, entry->green);
00725 in_uint8(s, entry->red);
00726 in_uint8s(s, 1);
00727 }
00728
00729 DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours));
00730
00731 hmap = ui_create_colourmap(&map);
00732 ui_set_colourmap(hmap);
00733
00734 xfree(map.colours);
00735 }
00736
00737
00738 static void
00739 process_fontcache(STREAM s)
00740 {
00741 HGLYPH bitmap;
00742 uint8 font, nglyphs;
00743 uint16 character, offset, baseline, width, height;
00744 int i, datasize;
00745 uint8 *data;
00746
00747 in_uint8(s, font);
00748 in_uint8(s, nglyphs);
00749
00750 DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs));
00751
00752 for (i = 0; i < nglyphs; i++)
00753 {
00754 in_uint16_le(s, character);
00755 in_uint16_le(s, offset);
00756 in_uint16_le(s, baseline);
00757 in_uint16_le(s, width);
00758 in_uint16_le(s, height);
00759
00760 datasize = (height * ((width + 7) / 8) + 3) & ~3;
00761 in_uint8p(s, data, datasize);
00762
00763 bitmap = ui_create_glyph(width, height, data);
00764 cache_put_font(font, character, offset, baseline, width, height, bitmap);
00765 }
00766 }
00767
00768
00769 static void
00770 process_secondary_order(STREAM s)
00771 {
00772 uint16 length;
00773 uint8 type;
00774 uint8 *next_order;
00775
00776 in_uint16_le(s, length);
00777 in_uint8s(s, 2);
00778 in_uint8(s, type);
00779
00780 next_order = s->p + length + 7;
00781
00782 switch (type)
00783 {
00784 case RDP_ORDER_RAW_BMPCACHE:
00785 process_raw_bmpcache(s);
00786 break;
00787
00788 case RDP_ORDER_COLCACHE:
00789 process_colcache(s);
00790 break;
00791
00792 case RDP_ORDER_BMPCACHE:
00793 process_bmpcache(s);
00794 break;
00795
00796 case RDP_ORDER_FONTCACHE:
00797 process_fontcache(s);
00798 break;
00799
00800 default:
00801 unimpl("secondary order %d\n", type);
00802 }
00803
00804 s->p = next_order;
00805 }
00806
00807
00808 void
00809 process_orders(STREAM s)
00810 {
00811 RDP_ORDER_STATE *os = &order_state;
00812 uint32 present;
00813 uint16 num_orders;
00814 uint8 order_flags;
00815 int size, processed = 0;
00816 BOOL delta;
00817
00818 in_uint8s(s, 2);
00819 in_uint16_le(s, num_orders);
00820 in_uint8s(s, 2);
00821
00822 while (processed < num_orders)
00823 {
00824 in_uint8(s, order_flags);
00825
00826 if (!(order_flags & RDP_ORDER_STANDARD))
00827 {
00828 error("order parsing failed\n");
00829 break;
00830 }
00831
00832 if (order_flags & RDP_ORDER_SECONDARY)
00833 {
00834 process_secondary_order(s);
00835 }
00836 else
00837 {
00838 if (order_flags & RDP_ORDER_CHANGE)
00839 {
00840 in_uint8(s, os->order_type);
00841 }
00842
00843 switch (os->order_type)
00844 {
00845 case RDP_ORDER_TRIBLT:
00846 case RDP_ORDER_TEXT2:
00847 size = 3;
00848 break;
00849
00850 case RDP_ORDER_PATBLT:
00851 case RDP_ORDER_MEMBLT:
00852 case RDP_ORDER_LINE:
00853 size = 2;
00854 break;
00855
00856 default:
00857 size = 1;
00858 }
00859
00860 rdp_in_present(s, &present, order_flags, size);
00861
00862 if (order_flags & RDP_ORDER_BOUNDS)
00863 {
00864 if (!(order_flags & RDP_ORDER_LASTBOUNDS))
00865 rdp_parse_bounds(s, &os->bounds);
00866
00867 ui_set_clip(os->bounds.left,
00868 os->bounds.top,
00869 os->bounds.right -
00870 os->bounds.left + 1,
00871 os->bounds.bottom - os->bounds.top + 1);
00872 }
00873
00874 delta = order_flags & RDP_ORDER_DELTA;
00875
00876 switch (os->order_type)
00877 {
00878 case RDP_ORDER_DESTBLT:
00879 process_destblt(s, &os->destblt, present, delta);
00880 break;
00881
00882 case RDP_ORDER_PATBLT:
00883 process_patblt(s, &os->patblt, present, delta);
00884 break;
00885
00886 case RDP_ORDER_SCREENBLT:
00887 process_screenblt(s, &os->screenblt, present, delta);
00888 break;
00889
00890 case RDP_ORDER_LINE:
00891 process_line(s, &os->line, present, delta);
00892 break;
00893
00894 case RDP_ORDER_RECT:
00895 process_rect(s, &os->rect, present, delta);
00896 break;
00897
00898 case RDP_ORDER_DESKSAVE:
00899 process_desksave(s, &os->desksave, present, delta);
00900 break;
00901
00902 case RDP_ORDER_MEMBLT:
00903 process_memblt(s, &os->memblt, present, delta);
00904 break;
00905
00906 case RDP_ORDER_TRIBLT:
00907 process_triblt(s, &os->triblt, present, delta);
00908 break;
00909
00910 case RDP_ORDER_POLYLINE:
00911 process_polyline(s, &os->polyline, present, delta);
00912 break;
00913
00914 case RDP_ORDER_TEXT2:
00915 process_text2(s, &os->text2, present, delta);
00916 break;
00917
00918 default:
00919 unimpl("order %d\n", os->order_type);
00920 return;
00921 }
00922
00923 if (order_flags & RDP_ORDER_BOUNDS)
00924 ui_reset_clip();
00925 }
00926
00927 processed++;
00928 }
00929
00930 if (s->p != next_packet)
00931 error("%d bytes remaining\n", (int) (next_packet - s->p));
00932 }
00933
00934
00935 void
00936 reset_order_state(void)
00937 {
00938 memset(&order_state, 0, sizeof(order_state));
00939 order_state.order_type = RDP_ORDER_PATBLT;
00940 }