ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

orders.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.