fix syntax warnings and errors
[fbvnc.git] / vncproto.c
blob0979bf0bfbedfa16dc22bd80948c52089fe65806
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 "vt52vnc.h"
16 /* vnc part */
17 CARD16 fb_width = 0;
18 CARD16 fb_height = 0;
20 /* graphics part */
21 t_kanal kan;
23 /* lowest 2 bits in videoram are used for actual and future videoram.
24 * they are changing their roles by changing the vramactive
25 * variable */
26 CARD8 vram[VT52_YMAX * VT52_XMAX];
27 int deltabuf[] = {0,1,1,0};
28 int joinbuf2[] = {0,0,3,3};
29 #define VRAM(x,y) (vram[(y)*VT52_XMAX+(x)])
30 #define DELTA(x,y) (deltabuf[VRAM((x),(y))&3])
31 #define JOIN2(x,y) (joinbuf2[(VRAM(i,j)&2)])
32 /* and buffer for screen updates */
33 CARD8 updates[VT52_YMAX * VT52_XMAX];
34 #define RED(x) ((x)&3)
35 #define GREEN(x) (((x)>>2)&7)
36 #define BLUE(x) (((x)>>5)&7)
38 /* code */
39 void update_vram(CARD8 * buffer, rfbRectangle r)
41 int i, j;
43 for(i=0; i<r.w; i++)
44 for(j=0; j<r.h; j++)
45 if (GREEN(buffer[i+j*r.w]) & 1)
46 VRAM(i+r.x,j+r.y) |= 2;
47 else
48 VRAM(i+r.x,j+r.y) &= ~2;
51 int drawdelta(void) {
52 int i,j,k;
53 #define XSTEP 128
54 #define YSTEP 64
55 static int xphase=0, yphase=VT52_YMAX-YSTEP;
57 for (j=yphase; j<yphase+YSTEP; j++) {
58 k = -1;
59 for (i=xphase; i<xphase+XSTEP; i++)
60 if (DELTA(i,j) && k==-1) {
61 k=i;
62 } else if (!DELTA(i,j) && k!=-1) {
63 gline(&kan,k,VT52_YMAX-j-1,i-1,VT52_YMAX-j-1);
64 k=-1;
66 if (k!=-1)
67 gline(&kan,k,VT52_YMAX-j-1,i-1,VT52_YMAX-j-1);
69 gflush(&kan);
71 for (i=xphase; i<xphase+XSTEP; i++)
72 for (j=yphase; j<yphase+YSTEP; j++)
73 VRAM(i,j) = JOIN2(i,j);
75 xphase = (xphase+XSTEP)%VT52_XMAX;
76 if (!xphase) {
77 yphase -= YSTEP;
78 if (yphase < 0) {
79 yphase = VT52_YMAX - YSTEP;
80 return 0;
83 return 1;
86 int vncproto_init(char * addr, int port)
88 struct sockaddr_in si;
89 rfbProtocolVersionMsg vmsg;
90 rfbClientInitMsg clientinit;
91 rfbServerInitMsg serverinit;
92 rfbSetPixelFormatMsg pixformmsg;
93 struct hostent * he;
94 int servsock, i;
95 CARD32 i32;
96 CARD8 x;
97 #if 0
98 CARD8 passwd[128];
99 #endif
100 rfbSetEncodingsMsg * encodingsmsgp;
102 encodingsmsgp = (rfbSetEncodingsMsg *)malloc(sizeof(rfbSetEncodingsMsg)+sizeof(CARD32));
103 if (encodingsmsgp == NULL) {
104 perror("malloc: Cannot initiate communication");
105 return -1;
108 si.sin_family = AF_INET;
109 si.sin_port = htons(port);
110 he = gethostbyname(addr);
111 if (he)
112 si.sin_addr.s_addr = *((unsigned long *)(he->h_addr));
113 else if (inet_aton(addr, &(si.sin_addr)) < 0) {
114 fprintf(stderr, "Cannot resolve hostname");
115 return -1;
118 servsock = socket(PF_INET, SOCK_STREAM, 0);
119 if (servsock == -1) {
120 perror("Cannot create socket");
121 return -1;
123 if (connect(servsock, (struct sockaddr *)&si, sizeof(si)) < 0) {
124 perror("Cannot connect");
125 close(servsock);
126 return -1;
128 sprintf(vmsg, rfbProtocolVersionFormat, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
129 write(servsock, vmsg, sz_rfbProtocolVersionMsg);
130 read(servsock, vmsg, sz_rfbProtocolVersionMsg);
132 i32 = rfbConnFailed;
133 read(servsock, &i32, sizeof(i32));
134 i32 = ntohl(i32);
136 switch(i32) {
137 case rfbConnFailed: /* conn failed */
138 puts("Remote server says: Connection failed");
139 i32 = 0;
140 read(servsock, &i32, sizeof(i32));
141 while (i32-- && (read(servsock, &x, sizeof(x))==sizeof(x)))
142 printf ("%c", x);
143 puts("");
144 close(servsock);
145 return -1;
146 case rfbNoAuth:
147 break;
148 case rfbVncAuth:
149 puts ("We don't support DES yet");
150 close(servsock);
151 return -1;
152 #if 0
153 p = getpass("Enter password: ");
154 if (!p) {
155 close(servsock);
156 return -1;
158 #endif
161 /* ClientInitialisation */
162 clientinit.shared = 1; /* share */
163 write(servsock, &clientinit, sizeof(clientinit));
165 read(servsock, &serverinit, sizeof(serverinit));
167 fb_width = ntohs(serverinit.framebufferWidth);
168 if (fb_width > VT52_XMAX)
169 fb_width = VT52_XMAX;
170 fb_height = ntohs(serverinit.framebufferHeight);
171 if (fb_height > VT52_YMAX)
172 fb_height = VT52_YMAX;
174 i32 = ntohl(serverinit.nameLength);
175 for (i=0; i<i32; i++)
176 read(servsock, &x, 1);
178 pixformmsg.type = rfbSetPixelFormat;
179 pixformmsg.format.bitsPerPixel = 8;
180 pixformmsg.format.depth = 8;
181 pixformmsg.format.bigEndian = 0; /* don't care */
182 pixformmsg.format.trueColour = 1;
184 pixformmsg.format.redMax = htons(3);
185 pixformmsg.format.greenMax = htons(7);
186 pixformmsg.format.blueMax = htons(7);
188 pixformmsg.format.redShift = 0;
189 pixformmsg.format.greenShift = 2;
190 pixformmsg.format.blueShift = 5;
192 write(servsock, &pixformmsg, sizeof(pixformmsg));
194 encodingsmsgp->type = rfbSetEncodings;
195 encodingsmsgp->nEncodings = htons(1);
196 *((CARD32 *)((void *)(encodingsmsgp) + sizeof(rfbSetEncodingsMsg))) = htonl(rfbEncodingRaw);
197 write(servsock, encodingsmsgp, sizeof(*encodingsmsgp)+sizeof(CARD32));
200 memset(vram, 0, VT52_YMAX * VT52_XMAX);
202 kan.pos = 0;
203 greset(&kan);
204 gflush(&kan);
205 /* uncomment this, if you want to use the different transferr speed as default */
206 // sleep(10);
207 gset_scaling(&kan, 0, 0);
208 gset_attrib(&kan, GA_XOR);
209 gflush(&kan);
211 return servsock;
214 int request_vnc_refresh(int fd)
216 rfbFramebufferUpdateRequestMsg updreq;
217 static int incremental = 0;
219 updreq.type = rfbFramebufferUpdateRequest;
220 updreq.incremental = incremental; incremental=1;
221 updreq.x = htons(0);
222 updreq.y = htons(0);
223 updreq.w = htons(fb_width);
224 updreq.h = htons(fb_height);
226 write(fd, &updreq, sizeof(updreq));
227 return 0;
230 int parse_vnc_in(int fd)
232 rfbFramebufferUpdateRectHeader uprect;
233 rfbServerToClientMsg msg;
234 rfbServerToClientMsg * vomsgp = &msg;
235 int i, j, k;
237 i = read (fd, vomsgp, sizeof(CARD8));
238 if (i != sizeof(CARD8))
239 return -1;
240 switch (vomsgp->type) {
241 case rfbFramebufferUpdate:
242 i = read(fd, ((void *)vomsgp)+sizeof(CARD8), sizeof(rfbFramebufferUpdateMsg) - sizeof(CARD8));
243 break;
244 case rfbBell:
245 i = read(fd, ((void *)vomsgp)+sizeof(CARD8), sizeof(rfbBellMsg) - sizeof(CARD8));
246 break;
247 case rfbServerCutText:
248 i = read(fd, ((void *)vomsgp)+sizeof(CARD8), sizeof(rfbServerCutTextMsg) - sizeof(CARD8));
249 break;
250 default:
251 return -1;
253 switch (vomsgp->type) {
254 case rfbBell:
255 gputc(&kan, '\x07'); gflush(&kan);
256 break;
258 case rfbFramebufferUpdate:
259 vomsgp->fu.nRects = ntohs(vomsgp->fu.nRects);
260 for (k=0; k<vomsgp->fu.nRects; k++) {
261 i = read(fd, &uprect, sizeof(uprect));
262 if (i != sizeof(uprect))
263 return -1;
264 uprect.r.x = ntohs(uprect.r.x);
265 uprect.r.y = ntohs(uprect.r.y);
266 uprect.r.w = ntohs(uprect.r.w);
267 uprect.r.h = ntohs(uprect.r.h);
268 if (uprect.r.x >= fb_width)
269 return -1;
270 if (uprect.r.x+uprect.r.w > fb_width)
271 return -1;
272 if (uprect.r.y >= fb_height)
273 return -1;
274 if (uprect.r.y+uprect.r.h > fb_height)
275 return -1;
276 for (i=0; i<uprect.r.w*uprect.r.h;) {
277 j = read(fd, updates+i, uprect.r.w*uprect.r.h-i);
278 if (j == -1)
279 return 0;
280 i+=j;
282 update_vram(updates,uprect.r);
284 break;
286 return 0;
289 int parse_kbd_in(int kbdfd, int fd)
291 rfbKeyEventMsg ke;
292 static rfbPointerEventMsg me = {rfbPointerEvent, 0, 0, 0};
293 static int mouse_on = -1; static int mouse_factor = 1;
294 #define VT_CHAR 0
295 #define VT_ESC 1
296 static int vt_state=VT_CHAR;
297 static int ctrllock_state = 0;
298 static int shiftlock_state = 0;
299 char buf[1024];
300 int i, j, k;
302 if (mouse_on == -1) {
303 me.x = htons(VT52_XMAX/2);
304 me.y = htons(VT52_YMAX/2);
305 mouse_on = 0;
306 ke.type = rfbKeyEvent;
309 if ( (j=read(kbdfd, buf, sizeof(buf))) <= 0 )
310 return -1;
311 for (i=0; i<j; i++) {
312 k = -1;
313 switch(vt_state) {
314 case VT_CHAR:
315 switch(buf[i]) {
316 case '\x08': k = 0xFF08; break;
317 case '\x09': k = 0xFF09; break;
318 case '\x0d': if (!mouse_on) {
319 k = 0xFF0D; break;
321 case '1': case '2': case '3':
322 case '4': case '5': case '6':
323 case '7': case '8': case '9':
324 case '0': case '.': case '-':
325 case ',':
326 if (!mouse_on) {
327 k = (unsigned char)buf[i];
328 break;
330 if (buf[i] == '5') {
331 mouse_factor <<= 1;
332 if (mouse_factor > 64)
333 mouse_factor = 1;
334 break;
336 if (buf[i] == '4' || buf[i] == '7' || buf[i] == '1') {
337 if (ntohs(me.x)>mouse_factor)
338 me.x = htons(ntohs(me.x)-mouse_factor);
339 else
340 me.x = htons(0);
342 if (buf[i] == '6' || buf[i] == '9' || buf[i] == '3') {
343 if (ntohs(me.x)+mouse_factor < VT52_XMAX-1)
344 me.x = htons(ntohs(me.x)+mouse_factor);
345 else
346 me.x = htons(VT52_XMAX-1);
348 if (buf[i] == '7' || buf[i] == '8' || buf[i] == '9') {
349 if (ntohs(me.y)>mouse_factor)
350 me.y = htons(ntohs(me.y)-mouse_factor);
351 else
352 me.y = htons(0);
354 if (buf[i] == '1' || buf[i] == '2' || buf[i] == '3') {
355 if (ntohs(me.y)+mouse_factor < VT52_YMAX-1)
356 me.y = htons(ntohs(me.y)+mouse_factor);
357 else
358 me.y = htons(VT52_YMAX-1);
361 if (buf[i]>='1' && buf[i]<='9') {
362 write(fd, &me, sizeof(me));
363 break;
365 if (buf[i]=='-') {
366 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
367 write(fd, &me, sizeof(me));
369 if (buf[i]==',') {
370 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
371 write(fd, &me, sizeof(me));
373 if (buf[i]=='\x0d') {
374 me.buttonMask = me.buttonMask ^ rfbButton3Mask;
375 write(fd, &me, sizeof(me));
377 if (buf[i]=='0') {
378 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
379 write(fd, &me, sizeof(me));
380 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
381 write(fd, &me, sizeof(me));
383 if (buf[i]=='.') {
384 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
385 write(fd, &me, sizeof(me));
386 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
387 write(fd, &me, sizeof(me));
389 break;
390 case '\x1b': vt_state = VT_ESC; break;
391 default: k = (unsigned char)buf[i];
393 break;
394 case VT_ESC:
395 switch(buf[i]) {
396 case '\x1b': k = (unsigned char)buf[i];
397 break;
398 case '\x03': /* esc ^c */
399 return -1;
400 case 'D': k = 0xFF51; break;
401 case 'A': k = 0xFF52; break;
402 case 'C': k = 0xFF53; break;
403 case 'B': k = 0xFF54; break;
404 case 'P': /* mouse lock */
405 mouse_on = !mouse_on;
406 break;
407 case 'Q': /* control lock */
408 ctrllock_state ^= 1;
409 ke.down = ctrllock_state;
410 ke.key = 0xFFE3;
411 write(fd, &ke, sizeof(ke));
412 break;
413 case 'R': /* shift lock */
414 shiftlock_state ^= 1;
415 ke.down = shiftlock_state;
416 ke.key = 0xFFE1;
417 write(fd, &ke, sizeof(ke));
418 break;
419 default: k = -1; break;
421 vt_state=VT_CHAR; break;
422 default:
423 break;
425 if (k>0) {
426 ke.down = 1;
427 ke.key = htonl(k);
428 write(fd, &ke, sizeof(ke));
429 ke.down = 0;
430 write(fd, &ke, sizeof(ke));
433 return 0;