blob: 085cc5ad5bbf3711a137fb0f8ea57b0b912b0bc3 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossmanc754cce2011-11-14 15:44:11 +00002 * Copyright 2009-2011 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;
Pierre Ossmanc754cce2011-11-14 15:44:11 +000063 case msgTypeServerFence: readFence(); break;
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000064 case msgTypeEndOfContinuousUpdates: readEndOfContinuousUpdates(); break;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000065
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000066 default:
67 fprintf(stderr, "unknown message type %d\n", type);
68 throw Exception("unknown message type");
69 }
70
71 } else {
72
73 int x = is->readU16();
74 int y = is->readU16();
75 int w = is->readU16();
76 int h = is->readU16();
Peter Åstrand98fe98c2010-02-10 07:43:02 +000077 int encoding = is->readS32();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000078
79 switch (encoding) {
80 case pseudoEncodingDesktopSize:
81 handler->setDesktopSize(w, h);
82 break;
Pierre Ossman49f88222009-03-20 13:02:50 +000083 case pseudoEncodingExtendedDesktopSize:
84 readExtendedDesktopSize(x, y, w, h);
85 break;
Peter Åstrandc39e0782009-01-15 12:21:42 +000086 case pseudoEncodingDesktopName:
87 readSetDesktopName(x, y, w, h);
88 break;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000089 case pseudoEncodingCursor:
90 readSetCursor(w, h, Point(x,y));
91 break;
92 case pseudoEncodingLastRect:
93 nUpdateRectsLeft = 1; // this rectangle is the last one
94 break;
95 default:
96 readRect(Rect(x, y, x+w, y+h), encoding);
97 break;
98 };
99
100 nUpdateRectsLeft--;
101 if (nUpdateRectsLeft == 0) handler->framebufferUpdateEnd();
102 }
103}
104
105void CMsgReaderV3::readFramebufferUpdate()
106{
107 is->skip(1);
108 nUpdateRectsLeft = is->readU16();
109 handler->framebufferUpdateStart();
110}
Pierre Ossmane49a7bf2009-03-20 10:02:31 +0000111
112void CMsgReaderV3::readSetDesktopName(int x, int y, int w, int h)
113{
114 char* name = is->readString();
115
116 if (x || y || w || h) {
117 fprintf(stderr, "Ignoring DesktopName rect with non-zero position/size\n");
118 } else {
119 handler->setName(name);
120 }
121
122 delete [] name;
123}
124
Pierre Ossman49f88222009-03-20 13:02:50 +0000125void CMsgReaderV3::readExtendedDesktopSize(int x, int y, int w, int h)
126{
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000127 unsigned int screens, i;
128 rdr::U32 id, flags;
129 int sx, sy, sw, sh;
130 ScreenSet layout;
Pierre Ossman49f88222009-03-20 13:02:50 +0000131
132 screens = is->readU8();
133 is->skip(3);
134
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000135 for (i = 0;i < screens;i++) {
136 id = is->readU32();
137 sx = is->readU16();
138 sy = is->readU16();
139 sw = is->readU16();
140 sh = is->readU16();
141 flags = is->readU32();
Pierre Ossman49f88222009-03-20 13:02:50 +0000142
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000143 layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
144 }
145
146 handler->setExtendedDesktopSize(x, y, w, h, layout);
Pierre Ossman49f88222009-03-20 13:02:50 +0000147}
148
Pierre Ossmanc754cce2011-11-14 15:44:11 +0000149void CMsgReaderV3::readFence()
150{
151 rdr::U32 flags;
152 rdr::U8 len;
153 char data[64];
154
155 is->skip(3);
156
157 flags = is->readU32();
158
159 len = is->readU8();
160 if (len > sizeof(data)) {
161 fprintf(stderr, "Ignoring fence with too large payload\n");
162 is->skip(len);
163 return;
164 }
165
166 is->readBytes(data, len);
167
168 handler->fence(flags, len, data);
169}
Pierre Ossmanc898d9a2011-11-14 16:22:23 +0000170
171void CMsgReaderV3::readEndOfContinuousUpdates()
172{
173 handler->endOfContinuousUpdates();
174}