move fb_init() and fb_free() to vncproto.c
[fbvnc.git] / vncproto.c
blob075b7c01946f3bbab3bd3430c6341a07c1a4735a
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 CARD16 fb_width = 0;
21 CARD16 fb_height = 0;
23 /* and buffer for screen updates */
24 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 fb_width = ntohs(serverinit.framebufferWidth);
113 if (fb_width > fb_cols())
114 fb_width = fb_cols();
115 fb_height = ntohs(serverinit.framebufferHeight);
116 if (fb_height > fb_rows())
117 fb_height = 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(fb_width);
163 updreq.h = htons(fb_height);
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 >= fb_width)
223 return -1;
224 if (uprect.r.x+uprect.r.w > fb_width)
225 return -1;
226 if (uprect.r.y >= fb_height)
227 return -1;
228 if (uprect.r.y+uprect.r.h > fb_height)
229 return -1;
230 for (i=0; i<uprect.r.w*uprect.r.h;) {
231 j = read(fd, updates+i, uprect.r.w*uprect.r.h-i);
232 if (j == -1)
233 return 0;
234 i+=j;
236 update_fb(updates,uprect.r);
238 break;
240 return 0;
243 int parse_kbd_in(int kbdfd, int fd)
245 static rfbKeyEventMsg ke;
246 static rfbPointerEventMsg me = {rfbPointerEvent, 0, 0, 0};
247 static int mouse_on = -1; static int mouse_factor = 1;
248 #define VT_CHAR 0
249 #define VT_ESC 1
250 static int vt_state=VT_CHAR;
251 static int ctrllock_state = 0;
252 static int shiftlock_state = 0;
253 char buf[1024];
254 int i, j, k;
256 if (mouse_on == -1) {
257 me.x = htons(fb_cols() / 2);
258 me.y = htons(fb_rows() / 2);
259 mouse_on = 0;
260 ke.type = rfbKeyEvent;
263 if ( (j=read(kbdfd, buf, sizeof(buf))) <= 0 )
264 return -1;
265 for (i=0; i<j; i++) {
266 k = -1;
267 switch(vt_state) {
268 case VT_CHAR:
269 switch(buf[i]) {
270 case '\x08': k = 0xFF08; break;
271 case '\x09': k = 0xFF09; break;
272 case '\x0d': if (!mouse_on) {
273 k = 0xFF0D; break;
275 case '1': case '2': case '3':
276 case '4': case '5': case '6':
277 case '7': case '8': case '9':
278 case '0': case '.': case '-':
279 case ',':
280 if (!mouse_on) {
281 k = (unsigned char)buf[i];
282 break;
284 if (buf[i] == '5') {
285 mouse_factor <<= 1;
286 if (mouse_factor > 64)
287 mouse_factor = 1;
288 break;
290 if (buf[i] == '4' || buf[i] == '7' || buf[i] == '1') {
291 if (ntohs(me.x)>mouse_factor)
292 me.x = htons(ntohs(me.x)-mouse_factor);
293 else
294 me.x = htons(0);
296 if (buf[i] == '6' || buf[i] == '9' || buf[i] == '3') {
297 if (ntohs(me.x)+mouse_factor < fb_cols()-1)
298 me.x = htons(ntohs(me.x)+mouse_factor);
299 else
300 me.x = htons(fb_cols()-1);
302 if (buf[i] == '7' || buf[i] == '8' || buf[i] == '9') {
303 if (ntohs(me.y)>mouse_factor)
304 me.y = htons(ntohs(me.y)-mouse_factor);
305 else
306 me.y = htons(0);
308 if (buf[i] == '1' || buf[i] == '2' || buf[i] == '3') {
309 if (ntohs(me.y)+mouse_factor < fb_rows()-1)
310 me.y = htons(ntohs(me.y)+mouse_factor);
311 else
312 me.y = htons(fb_rows()-1);
315 if (buf[i]>='1' && buf[i]<='9') {
316 write(fd, &me, sizeof(me));
317 break;
319 if (buf[i]=='-') {
320 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
321 write(fd, &me, sizeof(me));
323 if (buf[i]==',') {
324 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
325 write(fd, &me, sizeof(me));
327 if (buf[i]=='\x0d') {
328 me.buttonMask = me.buttonMask ^ rfbButton3Mask;
329 write(fd, &me, sizeof(me));
331 if (buf[i]=='0') {
332 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
333 write(fd, &me, sizeof(me));
334 me.buttonMask = me.buttonMask ^ rfbButton1Mask;
335 write(fd, &me, sizeof(me));
337 if (buf[i]=='.') {
338 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
339 write(fd, &me, sizeof(me));
340 me.buttonMask = me.buttonMask ^ rfbButton2Mask;
341 write(fd, &me, sizeof(me));
343 break;
344 case '\x1b': vt_state = VT_ESC; break;
345 default: k = (unsigned char)buf[i];
347 break;
348 case VT_ESC:
349 switch(buf[i]) {
350 case '\x1b': k = (unsigned char)buf[i];
351 break;
352 case '\x03': /* esc ^c */
353 return -1;
354 case 'D': k = 0xFF51; break;
355 case 'A': k = 0xFF52; break;
356 case 'C': k = 0xFF53; break;
357 case 'B': k = 0xFF54; break;
358 case 'P': /* mouse lock */
359 mouse_on = !mouse_on;
360 break;
361 case 'Q': /* control lock */
362 ctrllock_state ^= 1;
363 ke.down = ctrllock_state;
364 ke.key = 0xFFE3;
365 write(fd, &ke, sizeof(ke));
366 break;
367 case 'R': /* shift lock */
368 shiftlock_state ^= 1;
369 ke.down = shiftlock_state;
370 ke.key = 0xFFE1;
371 write(fd, &ke, sizeof(ke));
372 break;
373 default: k = -1; break;
375 vt_state=VT_CHAR; break;
376 default:
377 break;
379 if (k>0) {
380 ke.down = 1;
381 ke.key = htonl(k);
382 write(fd, &ke, sizeof(ke));
383 ke.down = 0;
384 write(fd, &ke, sizeof(ke));
387 return 0;