vncproto: rename fb_(width|height) to cols/rows
[fbvnc.git] / vncproto.c
blobebd0ba86d1658afb615daabb966d50d33c9584bf
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <netdb.h>
11 #include <pwd.h>
12 #include <string.h>
14 #include "fbvnc.h"
15 #include "draw.h"
17 #define MAXRESOL (1 << 21)
19 /* vnc part */
20 static CARD16 cols = 0;
21 static CARD16 rows = 0;
23 /* and buffer for screen updates */
24 static CARD8 updates[MAXRESOL];
26 int drawdelta(void) {
27 return 0;
30 int vncproto_init(char * addr, int port)
32 struct sockaddr_in si;
33 rfbProtocolVersionMsg vmsg;
34 rfbClientInitMsg clientinit;
35 rfbServerInitMsg serverinit;
36 rfbSetPixelFormatMsg pixformmsg;
37 struct hostent * he;
38 int servsock, i;
39 CARD32 i32;
40 CARD8 x;
41 #if 0
42 CARD8 passwd[128];
43 #endif
44 rfbSetEncodingsMsg * encodingsmsgp;
46 encodingsmsgp = (rfbSetEncodingsMsg *)malloc(sizeof(rfbSetEncodingsMsg)+sizeof(CARD32));
47 if (encodingsmsgp == NULL) {
48 perror("malloc: Cannot initiate communication");
49 return -1;
52 si.sin_family = AF_INET;
53 si.sin_port = htons(port);
54 he = gethostbyname(addr);
55 if (he)
56 si.sin_addr.s_addr = *((unsigned long *)(he->h_addr));
57 else if (inet_aton(addr, &(si.sin_addr)) < 0) {
58 fprintf(stderr, "Cannot resolve hostname");
59 return -1;
62 servsock = socket(PF_INET, SOCK_STREAM, 0);
63 if (servsock == -1) {
64 perror("Cannot create socket");
65 return -1;
67 if (connect(servsock, (struct sockaddr *)&si, sizeof(si)) < 0) {
68 perror("Cannot connect");
69 close(servsock);
70 return -1;
72 sprintf(vmsg, rfbProtocolVersionFormat, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
73 write(servsock, vmsg, sz_rfbProtocolVersionMsg);
74 read(servsock, vmsg, sz_rfbProtocolVersionMsg);
76 i32 = rfbConnFailed;
77 read(servsock, &i32, sizeof(i32));
78 i32 = ntohl(i32);
80 switch(i32) {
81 case rfbConnFailed: /* conn failed */
82 puts("Remote server says: Connection failed");
83 i32 = 0;
84 read(servsock, &i32, sizeof(i32));
85 while (i32-- && (read(servsock, &x, sizeof(x))==sizeof(x)))
86 printf ("%c", x);
87 puts("");
88 close(servsock);
89 return -1;
90 case rfbNoAuth:
91 break;
92 case rfbVncAuth:
93 puts ("We don't support DES yet");
94 close(servsock);
95 return -1;
96 #if 0
97 p = getpass("Enter password: ");
98 if (!p) {
99 close(servsock);
100 return -1;
102 #endif
105 /* ClientInitialisation */
106 clientinit.shared = 1; /* share */
107 write(servsock, &clientinit, sizeof(clientinit));
109 read(servsock, &serverinit, sizeof(serverinit));
111 fb_init();
112 cols = ntohs(serverinit.framebufferWidth);
113 if (cols > fb_cols())
114 cols = fb_cols();
115 rows = ntohs(serverinit.framebufferHeight);
116 if (rows > fb_rows())
117 rows = fb_rows();
119 i32 = ntohl(serverinit.nameLength);
120 for (i=0; i<i32; i++)
121 read(servsock, &x, 1);
123 pixformmsg.type = rfbSetPixelFormat;
124 pixformmsg.format.bitsPerPixel = 8;
125 pixformmsg.format.depth = 8;
126 pixformmsg.format.bigEndian = 0; /* don't care */
127 pixformmsg.format.trueColour = 1;
129 pixformmsg.format.redMax = htons(3);
130 pixformmsg.format.greenMax = htons(7);
131 pixformmsg.format.blueMax = htons(7);
133 pixformmsg.format.redShift = 0;
134 pixformmsg.format.greenShift = 2;
135 pixformmsg.format.blueShift = 5;
137 write(servsock, &pixformmsg, sizeof(pixformmsg));
139 encodingsmsgp->type = rfbSetEncodings;
140 encodingsmsgp->nEncodings = htons(1);
141 *((CARD32 *)((char *) encodingsmsgp +
142 sizeof(rfbSetEncodingsMsg))) = htonl(rfbEncodingRaw);
143 write(servsock, encodingsmsgp, sizeof(*encodingsmsgp)+sizeof(CARD32));
144 return servsock;
147 int vncproto_free(void)
149 fb_free();
150 return 0;
153 int request_vnc_refresh(int fd)
155 rfbFramebufferUpdateRequestMsg updreq;
156 static int incremental = 0;
158 updreq.type = rfbFramebufferUpdateRequest;
159 updreq.incremental = incremental; incremental=1;
160 updreq.x = htons(0);
161 updreq.y = htons(0);
162 updreq.w = htons(cols);
163 updreq.h = htons(rows);
165 write(fd, &updreq, sizeof(updreq));
166 return 0;
169 void update_fb(CARD8 *buffer, rfbRectangle r)
171 fbval_t slice[1 << 14];
172 int i, j;
173 for (i = 0; i < r.h; i++) {
174 for (j = 0; j < r.w; j++) {
175 unsigned char *p = &buffer[i * r.w + j];
176 slice[j] = fb_color(*p, *p, *p);
178 fb_set(r.y + i, r.x, slice, r.w);
182 int parse_vnc_in(int fd)
184 rfbFramebufferUpdateRectHeader uprect;
185 rfbServerToClientMsg msg;
186 rfbServerToClientMsg * vomsgp = &msg;
187 int i, j, k;
189 i = read (fd, vomsgp, sizeof(CARD8));
190 if (i != sizeof(CARD8))
191 return -1;
192 switch (vomsgp->type) {
193 case rfbFramebufferUpdate:
194 i = read(fd, (char *) vomsgp + sizeof(CARD8),
195 sizeof(rfbFramebufferUpdateMsg) - sizeof(CARD8));
196 break;
197 case rfbBell:
198 i = read(fd, (char *) vomsgp + sizeof(CARD8),
199 sizeof(rfbBellMsg) - sizeof(CARD8));
200 break;
201 case rfbServerCutText:
202 i = read(fd, (char *) vomsgp + sizeof(CARD8),
203 sizeof(rfbServerCutTextMsg) - sizeof(CARD8));
204 break;
205 default:
206 return -1;
208 switch (vomsgp->type) {
209 case rfbBell:
210 break;
212 case rfbFramebufferUpdate:
213 vomsgp->fu.nRects = ntohs(vomsgp->fu.nRects);
214 for (k=0; k<vomsgp->fu.nRects; k++) {
215 i = read(fd, &uprect, sizeof(uprect));
216 if (i != sizeof(uprect))
217 return -1;
218 uprect.r.x = ntohs(uprect.r.x);
219 uprect.r.y = ntohs(uprect.r.y);
220 uprect.r.w = ntohs(uprect.r.w);
221 uprect.r.h = ntohs(uprect.r.h);
222 if (uprect.r.x >= cols)
223 return -1;
224 if (uprect.r.x + uprect.r.w > cols)
225 return -1;
226 if (uprect.r.y >= rows)
227 return -1;
228 if (uprect.r.y + uprect.r.h > rows)
229 return -1;
230 for (i=0; i < uprect.r.w * uprect.r.h;) {
231 j = read(fd, updates + i,
232 uprect.r.w * uprect.r.h - i);
233 if (j == -1)
234 return 0;
235 i+=j;
237 update_fb(updates, uprect.r);
239 break;
241 return 0;
244 int parse_kbd_in(int kbdfd, int fd)
246 static rfbKeyEventMsg ke;
247 static rfbPointerEventMsg me = {rfbPointerEvent, 0, 0, 0};
248 static int mouse_on = -1; static int mouse_factor = 1;
249 #define VT_CHAR 0
250 #define VT_ESC 1
251 static int vt_state=VT_CHAR;
252 static int ctrllock_state = 0;
253 static int shiftlock_state = 0;
254 char buf[1024];
255 int i, j, k;
257 if (mouse_on == -1) {
258 me.x = htons(fb_cols() / 2);
259 me.y = htons(fb_rows() / 2);
260 mouse_on = 0;
261 ke.type = rfbKeyEvent;
264 if ( (j=read(kbdfd, buf, sizeof(buf))) <= 0 )
265 return -1;
266 for (i=0; i<j; i++) {
267 k = -1;
268 switch(vt_state) {
269 case VT_CHAR:
270 switch(buf[i]) {
271 case '\x08': k = 0xFF08; break;
272 case '\x09': k = 0xFF09; break;
273 case '\x0d': if (!mouse_on) {
274 k = 0xFF0D; break;
276 case '1': case '2': case '3':
277 case '4': case '5': case '6':
278 case '7': case '8': case '9':
279 case '0': case '.': case '-':
280 case ',':
281 if (!mouse_on) {
282 k = (unsigned char)buf[i];
283 break;
285 if (buf[i] == '5') {
286 mouse_factor <<= 1;
287 if (mouse_factor > 64)
288 mouse_factor = 1;
289 break;
291 if (buf[i] == '4' || buf[i] == '7' || buf[i] == '1') {
292 if (ntohs(me.x)>mouse_factor)
293 me.x = htons(ntohs(me.x)-mouse_factor);
294 else
295 me.x = htons(0);
297 if (buf[i] == '6' || buf[i] == '9' || buf[i] == '3') {
298 if (ntohs(me.x)+mouse_factor < fb_cols()-1)
299 me.x = htons(ntohs(me.x)+mouse_factor);
300 else
301 me.x = htons(fb_cols()-1);
303 if (buf[i] == '7' || buf[i] == '8' || buf[i] == '9') {
304 if (ntohs(me.y)>mouse_factor)
305 me.y = htons(ntohs(me.y)-mouse_factor);
306 else
307 me.y = htons(0);
309 if (buf[i] == '1' || buf[i] == '2' || buf[i] == '3') {
310 if (ntohs(me.y)+mouse_factor < fb_rows()-1)
311 me.y = htons(ntohs(me.y)+mouse_factor);
312 else
313 me.y = htons(fb_rows()-1);
316 if (buf[i]>='1' && buf[i]<='9') {
317 write(fd, &me, sizeof(me));
318 break;
320 if (buf[i]=='-') {
321 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
322 write(fd, &me, sizeof(me));
324 if (buf[i]==',') {
325 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
326 write(fd, &me, sizeof(me));
328 if (buf[i]=='\x0d') {
329 me.buttonMask = me.buttonMask ^ rfbButton3Mask;
330 write(fd, &me, sizeof(me));
332 if (buf[i]=='0') {
333 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
334 write(fd, &me, sizeof(me));
335 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
336 write(fd, &me, sizeof(me));
338 if (buf[i]=='.') {
339 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
340 write(fd, &me, sizeof(me));
341 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
342 write(fd, &me, sizeof(me));
344 break;
345 case '\x1b': vt_state = VT_ESC; break;
346 default: k = (unsigned char)buf[i];
348 break;
349 case VT_ESC:
350 switch(buf[i]) {
351 case '\x1b': k = (unsigned char)buf[i];
352 break;
353 case '\x03': /* esc ^c */
354 return -1;
355 case 'D': k = 0xFF51; break;
356 case 'A': k = 0xFF52; break;
357 case 'C': k = 0xFF53; break;
358 case 'B': k = 0xFF54; break;
359 case 'P': /* mouse lock */
360 mouse_on = !mouse_on;
361 break;
362 case 'Q': /* control lock */
363 ctrllock_state ^= 1;
364 ke.down = ctrllock_state;
365 ke.key = 0xFFE3;
366 write(fd, &ke, sizeof(ke));
367 break;
368 case 'R': /* shift lock */
369 shiftlock_state ^= 1;
370 ke.down = shiftlock_state;
371 ke.key = 0xFFE1;
372 write(fd, &ke, sizeof(ke));
373 break;
374 default: k = -1; break;
376 vt_state=VT_CHAR; break;
377 default:
378 break;
380 if (k>0) {
381 ke.down = 1;
382 ke.key = htonl(k);
383 write(fd, &ke, sizeof(ke));
384 ke.down = 0;
385 write(fd, &ke, sizeof(ke));
388 return 0;