blob: 89c9a8fdefcdf9c0216e2de24230ae6d54841733 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossman7638e9c2014-01-16 13:12:40 +01002 * Copyright 2009-2014 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 <stdio.h>
20#include <rdr/InStream.h>
Pierre Ossman7638e9c2014-01-16 13:12:40 +010021#include <rfb/msgTypes.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000022#include <rfb/Exception.h>
23#include <rfb/util.h>
24#include <rfb/SMsgHandler.h>
25#include <rfb/SMsgReader.h>
26#include <rfb/Configuration.h>
Constantin Kaplinskyc7755da2008-04-24 11:01:55 +000027#include <rfb/LogWriter.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000028
29using namespace rfb;
30
Constantin Kaplinskyc7755da2008-04-24 11:01:55 +000031static LogWriter vlog("SMsgReader");
32
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000033static IntParameter maxCutText("MaxCutText", "Maximum permitted length of an incoming clipboard update", 256*1024);
34
35SMsgReader::SMsgReader(SMsgHandler* handler_, rdr::InStream* is_)
36 : handler(handler_), is(is_)
37{
38}
39
40SMsgReader::~SMsgReader()
41{
42}
43
Pierre Ossman7638e9c2014-01-16 13:12:40 +010044void SMsgReader::readClientInit()
45{
46 bool shared = is->readU8();
47 handler->clientInit(shared);
48}
49
50void SMsgReader::readMsg()
51{
52 int msgType = is->readU8();
53 switch (msgType) {
54 case msgTypeSetPixelFormat:
55 readSetPixelFormat();
56 break;
57 case msgTypeSetEncodings:
58 readSetEncodings();
59 break;
60 case msgTypeSetDesktopSize:
61 readSetDesktopSize();
62 break;
63 case msgTypeFramebufferUpdateRequest:
64 readFramebufferUpdateRequest();
65 break;
66 case msgTypeEnableContinuousUpdates:
67 readEnableContinuousUpdates();
68 break;
69 case msgTypeClientFence:
70 readFence();
71 break;
72 case msgTypeKeyEvent:
73 readKeyEvent();
74 break;
75 case msgTypePointerEvent:
76 readPointerEvent();
77 break;
78 case msgTypeClientCutText:
79 readClientCutText();
80 break;
81 default:
82 fprintf(stderr, "unknown message type %d\n", msgType);
83 throw Exception("unknown message type");
84 }
85}
86
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000087void SMsgReader::readSetPixelFormat()
88{
89 is->skip(3);
90 PixelFormat pf;
91 pf.read(is);
92 handler->setPixelFormat(pf);
93}
94
95void SMsgReader::readSetEncodings()
96{
97 is->skip(1);
98 int nEncodings = is->readU16();
Peter Åstrand98fe98c2010-02-10 07:43:02 +000099 rdr::S32Array encodings(nEncodings);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000100 for (int i = 0; i < nEncodings; i++)
101 encodings.buf[i] = is->readU32();
102 handler->setEncodings(nEncodings, encodings.buf);
103}
104
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100105void SMsgReader::readSetDesktopSize()
106{
107 int width, height;
108 int screens, i;
109 rdr::U32 id, flags;
110 int sx, sy, sw, sh;
111 ScreenSet layout;
112
113 is->skip(1);
114
115 width = is->readU16();
116 height = is->readU16();
117
118 screens = is->readU8();
119 is->skip(1);
120
121 for (i = 0;i < screens;i++) {
122 id = is->readU32();
123 sx = is->readU16();
124 sy = is->readU16();
125 sw = is->readU16();
126 sh = is->readU16();
127 flags = is->readU32();
128
129 layout.add_screen(Screen(id, sx, sy, sw, sh, flags));
130 }
131
132 handler->setDesktopSize(width, height, layout);
133}
134
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000135void SMsgReader::readFramebufferUpdateRequest()
136{
137 bool inc = is->readU8();
138 int x = is->readU16();
139 int y = is->readU16();
140 int w = is->readU16();
141 int h = is->readU16();
142 handler->framebufferUpdateRequest(Rect(x, y, x+w, y+h), inc);
143}
144
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100145void SMsgReader::readEnableContinuousUpdates()
146{
147 bool enable;
148 int x, y, w, h;
149
150 enable = is->readU8();
151
152 x = is->readU16();
153 y = is->readU16();
154 w = is->readU16();
155 h = is->readU16();
156
157 handler->enableContinuousUpdates(enable, x, y, w, h);
158}
159
160void SMsgReader::readFence()
161{
162 rdr::U32 flags;
163 rdr::U8 len;
164 char data[64];
165
166 is->skip(3);
167
168 flags = is->readU32();
169
170 len = is->readU8();
171 if (len > sizeof(data)) {
172 fprintf(stderr, "Ignoring fence with too large payload\n");
173 is->skip(len);
174 return;
175 }
176
177 is->readBytes(data, len);
178
179 handler->fence(flags, len, data);
180}
181
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000182void SMsgReader::readKeyEvent()
183{
184 bool down = is->readU8();
185 is->skip(2);
186 rdr::U32 key = is->readU32();
187 handler->keyEvent(key, down);
188}
189
190void SMsgReader::readPointerEvent()
191{
192 int mask = is->readU8();
193 int x = is->readU16();
194 int y = is->readU16();
195 handler->pointerEvent(Point(x, y), mask);
196}
197
198
199void SMsgReader::readClientCutText()
200{
201 is->skip(3);
202 int len = is->readU32();
203 if (len > maxCutText) {
204 is->skip(len);
Constantin Kaplinskyc7755da2008-04-24 11:01:55 +0000205 vlog.error("Cut text too long (%d bytes) - ignoring", len);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000206 return;
207 }
208 CharArray ca(len+1);
209 ca.buf[len] = 0;
210 is->readBytes(ca.buf, len);
211 handler->clientCutText(ca.buf, len);
212}
Constantin Kaplinskydafbb012007-04-05 08:43:25 +0000213