~ubuntu-branches/ubuntu/precise/virtualbox/precise-updates

« back to all changes in this revision

Viewing changes to src/VBox/RDP/client/orders.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-07-04 13:02:31 UTC
  • mfrom: (3.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110704130231-l843es6wqhx614n7
Tags: 4.0.10-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Add the Modaliases control field manually for maximum backportability.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- c-basic-offset: 8 -*-
2
2
   rdesktop: A Remote Desktop Protocol client.
3
3
   RDP order processing
4
 
   Copyright (C) Matthew Chapman 1999-2007
 
4
   Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5
5
 
6
 
   This program is free software; you can redistribute it and/or modify
 
6
   This program is free software: you can redistribute it and/or modify
7
7
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2 of the License, or
 
8
   the Free Software Foundation, either version 3 of the License, or
9
9
   (at your option) any later version.
10
10
 
11
11
   This program is distributed in the hope that it will be useful,
14
14
   GNU General Public License for more details.
15
15
 
16
16
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
18
*/
20
19
 
21
20
/*
157
156
        return s_check(s);
158
157
}
159
158
 
 
159
static void
 
160
setup_brush(BRUSH * out_brush, BRUSH * in_brush)
 
161
{
 
162
        BRUSHDATA *brush_data;
 
163
        uint8 cache_idx;
 
164
        uint8 colour_code;
 
165
 
 
166
        memcpy(out_brush, in_brush, sizeof(BRUSH));
 
167
        if (out_brush->style & 0x80)
 
168
        {
 
169
                colour_code = out_brush->style & 0x0f;
 
170
                cache_idx = out_brush->pattern[0];
 
171
                brush_data = cache_get_brush_data(colour_code, cache_idx);
 
172
                if ((brush_data == NULL) || (brush_data->data == NULL))
 
173
                {
 
174
                        error("error getting brush data, style %x\n", out_brush->style);
 
175
                        out_brush->bd = NULL;
 
176
                        memset(out_brush->pattern, 0, 8);
 
177
                }
 
178
                else
 
179
                {
 
180
                        out_brush->bd = brush_data;
 
181
                }
 
182
                out_brush->style = 3;
 
183
        }
 
184
}
 
185
 
160
186
/* Parse a brush */
161
187
static RD_BOOL
162
188
rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
208
234
static void
209
235
process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, RD_BOOL delta)
210
236
{
 
237
        BRUSH brush;
 
238
 
211
239
        if (present & 0x0001)
212
240
                rdp_in_coord(s, &os->x, delta);
213
241
 
234
262
        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,
235
263
               os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
236
264
 
 
265
        setup_brush(&brush, &os->brush);
 
266
 
237
267
        ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
238
 
                  &os->brush, os->bgcolour, os->fgcolour);
 
268
                  &brush, os->bgcolour, os->fgcolour);
239
269
}
240
270
 
241
271
/* Process a screen blt order */
435
465
process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, RD_BOOL delta)
436
466
{
437
467
        RD_HBITMAP bitmap;
 
468
        BRUSH brush;
438
469
 
439
470
        if (present & 0x000001)
440
471
        {
485
516
        if (bitmap == NULL)
486
517
                return;
487
518
 
 
519
        setup_brush(&brush, &os->brush);
 
520
 
488
521
        ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
489
 
                  bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
 
522
                  bitmap, os->srcx, os->srcy, &brush, os->bgcolour, os->fgcolour);
490
523
}
491
524
 
492
525
/* Process a polygon order */
575
608
        int index, data, next;
576
609
        uint8 flags = 0;
577
610
        RD_POINT *points;
 
611
        BRUSH brush;
578
612
 
579
613
        if (present & 0x0001)
580
614
                rdp_in_coord(s, &os->x, delta);
622
656
                return;
623
657
        }
624
658
 
 
659
        setup_brush(&brush, &os->brush);
 
660
 
625
661
        points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
626
662
        memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
627
663
 
646
682
 
647
683
        if (next - 1 == os->npoints)
648
684
                ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
649
 
                           &os->brush, os->bgcolour, os->fgcolour);
 
685
                           &brush, os->bgcolour, os->fgcolour);
650
686
        else
651
687
                error("polygon2 parse error\n");
652
688
 
767
803
static void
768
804
process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, RD_BOOL delta)
769
805
{
 
806
        BRUSH brush;
 
807
 
770
808
        if (present & 0x0001)
771
809
                rdp_in_coord(s, &os->left, delta);
772
810
 
797
835
               os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
798
836
               os->bgcolour, os->fgcolour));
799
837
 
 
838
        setup_brush(&brush, &os->brush);
 
839
 
800
840
        ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
801
 
                   os->bottom - os->top, &os->brush, os->bgcolour, os->fgcolour);
 
841
                   os->bottom - os->top, &brush, os->bgcolour, os->fgcolour);
802
842
}
803
843
 
804
844
/* Process a text order */
806
846
process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, RD_BOOL delta)
807
847
{
808
848
        int i;
 
849
        BRUSH brush;
809
850
 
810
851
        if (present & 0x000001)
811
852
                in_uint8(s, os->font);
872
913
 
873
914
        DEBUG(("\n"));
874
915
 
 
916
        setup_brush(&brush, &os->brush);
 
917
 
875
918
        ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
876
919
                     os->clipleft, os->cliptop, os->clipright - os->clipleft,
877
920
                     os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
878
921
                     os->boxright - os->boxleft, os->boxbottom - os->boxtop,
879
 
                     &os->brush, os->bgcolour, os->fgcolour, os->text, os->length);
 
922
                     &brush, os->bgcolour, os->fgcolour, os->text, os->length);
880
923
}
881
924
 
882
925
/* Process a raw bitmap cache order */
1113
1156
        }
1114
1157
}
1115
1158
 
 
1159
static void
 
1160
process_compressed_8x8_brush_data(uint8 * in, uint8 * out, int Bpp)
 
1161
{
 
1162
        int x, y, pal_index, in_index, shift, do2, i;
 
1163
        uint8 *pal;
 
1164
 
 
1165
        in_index = 0;
 
1166
        pal = in + 16;
 
1167
        /* read it bottom up */
 
1168
        for (y = 7; y >= 0; y--)
 
1169
        {
 
1170
                /* 2 bytes per row */
 
1171
                x = 0;
 
1172
                for (do2 = 0; do2 < 2; do2++)
 
1173
                {
 
1174
                        /* 4 pixels per byte */
 
1175
                        shift = 6;
 
1176
                        while (shift >= 0)
 
1177
                        {
 
1178
                                pal_index = (in[in_index] >> shift) & 3;
 
1179
                                /* size of palette entries depends on Bpp */
 
1180
                                for (i = 0; i < Bpp; i++)
 
1181
                                {
 
1182
                                        out[(y * 8 + x) * Bpp + i] = pal[pal_index * Bpp + i];
 
1183
                                }
 
1184
                                x++;
 
1185
                                shift -= 2;
 
1186
                        }
 
1187
                        in_index++;
 
1188
                }
 
1189
        }
 
1190
}
 
1191
 
 
1192
/* Process a brush cache order */
 
1193
static void
 
1194
process_brushcache(STREAM s, uint16 flags)
 
1195
{
 
1196
        BRUSHDATA brush_data;
 
1197
        uint8 cache_idx, colour_code, width, height, size, type;
 
1198
        uint8 *comp_brush;
 
1199
        int index;
 
1200
        int Bpp;
 
1201
 
 
1202
        in_uint8(s, cache_idx);
 
1203
        in_uint8(s, colour_code);
 
1204
        in_uint8(s, width);
 
1205
        in_uint8(s, height);
 
1206
        in_uint8(s, type);      /* type, 0x8x = cached */
 
1207
        in_uint8(s, size);
 
1208
 
 
1209
        DEBUG(("BRUSHCACHE(idx=%d,wd=%d,ht=%d,sz=%d)\n", cache_idx, width, height, size));
 
1210
 
 
1211
        if ((width == 8) && (height == 8))
 
1212
        {
 
1213
                if (colour_code == 1)
 
1214
                {
 
1215
                        brush_data.colour_code = 1;
 
1216
                        brush_data.data_size = 8;
 
1217
                        brush_data.data = xmalloc(8);
 
1218
                        if (size == 8)
 
1219
                        {
 
1220
                                /* read it bottom up */
 
1221
                                for (index = 7; index >= 0; index--)
 
1222
                                {
 
1223
                                        in_uint8(s, brush_data.data[index]);
 
1224
                                }
 
1225
                        }
 
1226
                        else
 
1227
                        {
 
1228
                                warning("incompatible brush, colour_code %d size %d\n", colour_code,
 
1229
                                        size);
 
1230
                        }
 
1231
                        cache_put_brush_data(1, cache_idx, &brush_data);
 
1232
                }
 
1233
                else if ((colour_code >= 3) && (colour_code <= 6))
 
1234
                {
 
1235
                        Bpp = colour_code - 2;
 
1236
                        brush_data.colour_code = colour_code;
 
1237
                        brush_data.data_size = 8 * 8 * Bpp;
 
1238
                        brush_data.data = xmalloc(8 * 8 * Bpp);
 
1239
                        if (size == 16 + 4 * Bpp)
 
1240
                        {
 
1241
                                in_uint8p(s, comp_brush, 16 + 4 * Bpp);
 
1242
                                process_compressed_8x8_brush_data(comp_brush, brush_data.data, Bpp);
 
1243
                        }
 
1244
                        else
 
1245
                        {
 
1246
                                in_uint8a(s, brush_data.data, 8 * 8 * Bpp);
 
1247
                        }
 
1248
                        cache_put_brush_data(colour_code, cache_idx, &brush_data);
 
1249
                }
 
1250
                else
 
1251
                {
 
1252
                        warning("incompatible brush, colour_code %d size %d\n", colour_code, size);
 
1253
                }
 
1254
        }
 
1255
        else
 
1256
        {
 
1257
                warning("incompatible brush, width height %d %d\n", width, height);
 
1258
        }
 
1259
}
 
1260
 
1116
1261
/* Process a secondary order */
1117
1262
static void
1118
1263
process_secondary_order(STREAM s)
1157
1302
                        process_bmpcache2(s, flags, True);      /* compressed */
1158
1303
                        break;
1159
1304
 
 
1305
                case RDP_ORDER_BRUSHCACHE:
 
1306
                        process_brushcache(s, flags);
 
1307
                        break;
 
1308
 
1160
1309
                default:
1161
1310
                        unimpl("secondary order %d\n", type);
1162
1311
        }