blob: 5471593c59b720e0d6ff9783b1ee0e9f0dad91d8 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossman49f88222009-03-20 13:02:50 +00002 * Copyright 2009 Pierre Ossman for Cendio AB
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00003 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19#include <rfb/PixelFormat.h>
20#include <rfb/msgTypes.h>
21#include <rfb/Exception.h>
22#include <rdr/InStream.h>
23#include <rfb/CMsgReaderV3.h>
24#include <rfb/CMsgHandler.h>
25#include <rfb/util.h>
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000026#include <rfb/ScreenSet.h>
Adam Tkac20e0d712008-11-14 14:48:21 +000027#include <stdio.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000028
29using namespace rfb;
30
31CMsgReaderV3::CMsgReaderV3(CMsgHandler* handler, rdr::InStream* is)
32 : CMsgReader(handler, is), nUpdateRectsLeft(0)
33{
34}
35
36CMsgReaderV3::~CMsgReaderV3()
37{
38}
39
40void CMsgReaderV3::readServerInit()
41{
42 int width = is->readU16();
43 int height = is->readU16();
44 handler->setDesktopSize(width, height);
45 PixelFormat pf;
46 pf.read(is);
47 handler->setPixelFormat(pf);
48 CharArray name(is->readString());
49 handler->setName(name.buf);
50 handler->serverInit();
51}
52
53void CMsgReaderV3::readMsg()
54{
55 if (nUpdateRectsLeft == 0) {
56
57 int type = is->readU8();
58 switch (type) {
59 case msgTypeFramebufferUpdate: readFramebufferUpdate(); break;
60 case msgTypeSetColourMapEntries: readSetColourMapEntries(); break;
61 case msgTypeBell: readBell(); break;
62 case msgTypeServerCutText: readServerCutText(); break;
63
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000064 default:
65 fprintf(stderr, "unknown message type %d\n", type);
66 throw Exception("unknown message type");
67 }
68
69 } else {
70
71 int x = is->readU16();
72 int y = is->readU16();
73 int w = is->readU16();
74 int h = is->readU16();
75 unsigned int encoding = is->readU32();
76
77 switch (encoding) {
78 case pseudoEncodingDesktopSize:
79 handler->setDesktopSize(w, h);
80 break;
Pierre Ossman49f88222009-03-20 13:02:50 +000081 case pseudoEncodingExtendedDesktopSize:
82 readExtendedDesktopSize(x, y, w, h);
83 break;
Peter Åstrandc39e0782009-01-15 12:21:42 +000084 case pseudoEncodingDesktopName:
85 readSetDesktopName(x, y, w, h);
86 break;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000087 case pseudoEncodingCursor:
88 readSetCursor(w, h, Point(x,y));
89 break;
90 case pseudoEncodingLastRect:
91 nUpdateRectsLeft = 1; // this rectangle is the last one
92 break;
93 default:
94 readRect(Rect(x, y, x+w, y+h), encoding);
95 break;
96 };
97
98 nUpdateRectsLeft--;
99 if (nUpdateRectsLeft == 0) handler->framebufferUpdateEnd();
100 }
101}
102
103void CMsgReaderV3::readFramebufferUpdate()
104{
105 is->skip(1);
106 nUpdateRectsLeft = is->readU16();
107 handler->framebufferUpdateStart();
108}
Pierre Ossmane49a7bf2009-03-20 10:02:31 +0000109
110void CMsgReaderV3::readSetDesktopName(int x, int y, int w, int h)
111{
112 char* name = is->readString();
113
114 if (x || y || w || h) {
115 fprintf(stderr, "Ignoring DesktopName rect with non-zero position/size\n");
116 } else {
117 handler->setName(name);
118 }
119
120 delete [] name;
121}
122
Pierre Ossman49f88222009-03-20 13:02:50 +0000123void CMsgReaderV3::readExtendedDesktopSize(int x, int y, int w, int h)
124{
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000125 unsigned int screens, i;
126 rdr::U32 id, flags;
127 int sx, sy, sw, sh;
128 ScreenSet layout;
Pierre Ossman49f88222009-03-20 13:02:50 +0000129
130 screens = is->readU8();
131 is->skip(3);
132
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000133 for (i = 0;i < screens;i++) {
134 id = is->readU32();
135 sx = is->readU16();
136 sy = is->readU16();
137 sw = is->readU16();
138 sh = is->readU16();
139 flags = is->readU32();
Pierre Ossman49f88222009-03-20 13:02:50 +0000140
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000141 layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
142 }
143
144 handler->setExtendedDesktopSize(x, y, w, h, layout);
Pierre Ossman49f88222009-03-20 13:02:50 +0000145}
146