7 #include <sys/socket.h>
8 #include <netinet/in.h>
17 #define MAXRESOL (1 << 21)
23 /* and buffer for screen updates */
24 CARD8 updates
[MAXRESOL
];
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
;
44 rfbSetEncodingsMsg
* encodingsmsgp
;
46 encodingsmsgp
= (rfbSetEncodingsMsg
*)malloc(sizeof(rfbSetEncodingsMsg
)+sizeof(CARD32
));
47 if (encodingsmsgp
== NULL
) {
48 perror("malloc: Cannot initiate communication");
52 si
.sin_family
= AF_INET
;
53 si
.sin_port
= htons(port
);
54 he
= gethostbyname(addr
);
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");
62 servsock
= socket(PF_INET
, SOCK_STREAM
, 0);
64 perror("Cannot create socket");
67 if (connect(servsock
, (struct sockaddr
*)&si
, sizeof(si
)) < 0) {
68 perror("Cannot connect");
72 sprintf(vmsg
, rfbProtocolVersionFormat
, rfbProtocolMajorVersion
, rfbProtocolMinorVersion
);
73 write(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
74 read(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
77 read(servsock
, &i32
, sizeof(i32
));
81 case rfbConnFailed
: /* conn failed */
82 puts("Remote server says: Connection failed");
84 read(servsock
, &i32
, sizeof(i32
));
85 while (i32
-- && (read(servsock
, &x
, sizeof(x
))==sizeof(x
)))
93 puts ("We don't support DES yet");
97 p
= getpass("Enter password: ");
105 /* ClientInitialisation */
106 clientinit
.shared
= 1; /* share */
107 write(servsock
, &clientinit
, sizeof(clientinit
));
109 read(servsock
, &serverinit
, sizeof(serverinit
));
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
));
147 int vncproto_free(void)
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;
162 updreq
.w
= htons(fb_width
);
163 updreq
.h
= htons(fb_height
);
165 write(fd
, &updreq
, sizeof(updreq
));
169 void update_fb(CARD8
*buffer
, rfbRectangle r
)
171 fbval_t slice
[1 << 14];
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
;
189 i
= read (fd
, vomsgp
, sizeof(CARD8
));
190 if (i
!= sizeof(CARD8
))
192 switch (vomsgp
->type
) {
193 case rfbFramebufferUpdate
:
194 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
195 sizeof(rfbFramebufferUpdateMsg
) - sizeof(CARD8
));
198 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
199 sizeof(rfbBellMsg
) - sizeof(CARD8
));
201 case rfbServerCutText
:
202 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
203 sizeof(rfbServerCutTextMsg
) - sizeof(CARD8
));
208 switch (vomsgp
->type
) {
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
))
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
)
224 if (uprect
.r
.x
+uprect
.r
.w
> fb_width
)
226 if (uprect
.r
.y
>= fb_height
)
228 if (uprect
.r
.y
+uprect
.r
.h
> fb_height
)
230 for (i
=0; i
<uprect
.r
.w
*uprect
.r
.h
;) {
231 j
= read(fd
, updates
+i
, uprect
.r
.w
*uprect
.r
.h
-i
);
236 update_fb(updates
,uprect
.r
);
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;
250 static int vt_state
=VT_CHAR
;
251 static int ctrllock_state
= 0;
252 static int shiftlock_state
= 0;
256 if (mouse_on
== -1) {
257 me
.x
= htons(fb_cols() / 2);
258 me
.y
= htons(fb_rows() / 2);
260 ke
.type
= rfbKeyEvent
;
263 if ( (j
=read(kbdfd
, buf
, sizeof(buf
))) <= 0 )
265 for (i
=0; i
<j
; i
++) {
270 case '\x08': k
= 0xFF08; break;
271 case '\x09': k
= 0xFF09; break;
272 case '\x0d': if (!mouse_on
) {
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 '-':
281 k
= (unsigned char)buf
[i
];
286 if (mouse_factor
> 64)
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
);
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
);
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
);
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
);
312 me
.y
= htons(fb_rows()-1);
315 if (buf
[i
]>='1' && buf
[i
]<='9') {
316 write(fd
, &me
, sizeof(me
));
320 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
321 write(fd
, &me
, sizeof(me
));
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
));
332 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
333 write(fd
, &me
, sizeof(me
));
334 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
335 write(fd
, &me
, sizeof(me
));
338 me
.buttonMask
= me
.buttonMask
^ rfbButton2Mask
;
339 write(fd
, &me
, sizeof(me
));
340 me
.buttonMask
= me
.buttonMask
^ rfbButton2Mask
;
341 write(fd
, &me
, sizeof(me
));
344 case '\x1b': vt_state
= VT_ESC
; break;
345 default: k
= (unsigned char)buf
[i
];
350 case '\x1b': k
= (unsigned char)buf
[i
];
352 case '\x03': /* esc ^c */
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
;
361 case 'Q': /* control lock */
363 ke
.down
= ctrllock_state
;
365 write(fd
, &ke
, sizeof(ke
));
367 case 'R': /* shift lock */
368 shiftlock_state
^= 1;
369 ke
.down
= shiftlock_state
;
371 write(fd
, &ke
, sizeof(ke
));
373 default: k
= -1; break;
375 vt_state
=VT_CHAR
; break;
382 write(fd
, &ke
, sizeof(ke
));
384 write(fd
, &ke
, sizeof(ke
));