5 #include <netinet/in.h>
10 #include <sys/socket.h>
12 #include <sys/types.h>
19 #define MAXRESOL (1 << 21)
22 static CARD16 cols
= 0;
23 static CARD16 rows
= 0;
25 /* and buffer for screen updates */
26 static CARD8 updates
[MAXRESOL
];
29 int vncproto_init(char * addr
, int port
)
31 struct sockaddr_in si
;
32 rfbProtocolVersionMsg vmsg
;
33 rfbClientInitMsg clientinit
;
34 rfbServerInitMsg serverinit
;
35 rfbSetPixelFormatMsg pixformmsg
;
43 rfbSetEncodingsMsg
* encodingsmsgp
;
45 encodingsmsgp
= (rfbSetEncodingsMsg
*)malloc(sizeof(rfbSetEncodingsMsg
)+sizeof(CARD32
));
46 if (encodingsmsgp
== NULL
) {
47 perror("malloc: Cannot initiate communication");
51 si
.sin_family
= AF_INET
;
52 si
.sin_port
= htons(port
);
53 he
= gethostbyname(addr
);
55 si
.sin_addr
.s_addr
= *((unsigned long *)(he
->h_addr
));
56 else if (inet_aton(addr
, &(si
.sin_addr
)) < 0) {
57 fprintf(stderr
, "Cannot resolve hostname");
61 servsock
= socket(PF_INET
, SOCK_STREAM
, 0);
63 perror("Cannot create socket");
66 if (connect(servsock
, (struct sockaddr
*)&si
, sizeof(si
)) < 0) {
67 perror("Cannot connect");
71 sprintf(vmsg
, rfbProtocolVersionFormat
, rfbProtocolMajorVersion
, rfbProtocolMinorVersion
);
72 write(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
73 read(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
76 read(servsock
, &i32
, sizeof(i32
));
80 case rfbConnFailed
: /* conn failed */
81 puts("Remote server says: Connection failed");
83 read(servsock
, &i32
, sizeof(i32
));
84 while (i32
-- && (read(servsock
, &x
, sizeof(x
))==sizeof(x
)))
92 puts ("We don't support DES yet");
96 p
= getpass("Enter password: ");
104 /* ClientInitialisation */
105 clientinit
.shared
= 1; /* share */
106 write(servsock
, &clientinit
, sizeof(clientinit
));
108 read(servsock
, &serverinit
, sizeof(serverinit
));
111 cols
= ntohs(serverinit
.framebufferWidth
);
112 if (cols
> fb_cols())
114 rows
= ntohs(serverinit
.framebufferHeight
);
115 if (rows
> fb_rows())
118 i32
= ntohl(serverinit
.nameLength
);
119 for (i
=0; i
<i32
; i
++)
120 read(servsock
, &x
, 1);
122 pixformmsg
.type
= rfbSetPixelFormat
;
123 pixformmsg
.format
.bitsPerPixel
= 8;
124 pixformmsg
.format
.depth
= 8;
125 pixformmsg
.format
.bigEndian
= 0; /* don't care */
126 pixformmsg
.format
.trueColour
= 1;
128 pixformmsg
.format
.redMax
= htons(3);
129 pixformmsg
.format
.greenMax
= htons(7);
130 pixformmsg
.format
.blueMax
= htons(7);
132 pixformmsg
.format
.redShift
= 0;
133 pixformmsg
.format
.greenShift
= 2;
134 pixformmsg
.format
.blueShift
= 5;
136 write(servsock
, &pixformmsg
, sizeof(pixformmsg
));
138 encodingsmsgp
->type
= rfbSetEncodings
;
139 encodingsmsgp
->nEncodings
= htons(1);
140 *((CARD32
*)((char *) encodingsmsgp
+
141 sizeof(rfbSetEncodingsMsg
))) = htonl(rfbEncodingRaw
);
142 write(servsock
, encodingsmsgp
, sizeof(*encodingsmsgp
)+sizeof(CARD32
));
146 int vncproto_free(void)
152 int request_vnc_refresh(int fd
, int inc
)
154 rfbFramebufferUpdateRequestMsg updreq
;
155 updreq
.type
= rfbFramebufferUpdateRequest
;
156 updreq
.incremental
= inc
;
159 updreq
.w
= htons(cols
);
160 updreq
.h
= htons(rows
);
161 write(fd
, &updreq
, sizeof(updreq
));
165 static void update_fb(CARD8
*buffer
, rfbRectangle r
)
167 fbval_t slice
[1 << 14];
169 for (i
= 0; i
< r
.h
; i
++) {
170 for (j
= 0; j
< r
.w
; j
++) {
171 unsigned char *p
= &buffer
[i
* r
.w
+ j
];
172 slice
[j
] = fb_color(*p
, *p
, *p
);
174 fb_set(r
.y
+ i
, r
.x
, slice
, r
.w
);
178 int must_redraw(void)
185 int parse_vnc_in(int fd
)
187 rfbFramebufferUpdateRectHeader uprect
;
188 rfbServerToClientMsg msg
;
189 rfbServerToClientMsg
* vomsgp
= &msg
;
192 i
= read (fd
, vomsgp
, sizeof(CARD8
));
193 if (i
!= sizeof(CARD8
))
195 switch (vomsgp
->type
) {
196 case rfbFramebufferUpdate
:
197 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
198 sizeof(rfbFramebufferUpdateMsg
) - sizeof(CARD8
));
201 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
202 sizeof(rfbBellMsg
) - sizeof(CARD8
));
204 case rfbServerCutText
:
205 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
206 sizeof(rfbServerCutTextMsg
) - sizeof(CARD8
));
211 switch (vomsgp
->type
) {
215 case rfbFramebufferUpdate
:
216 vomsgp
->fu
.nRects
= ntohs(vomsgp
->fu
.nRects
);
217 for (k
=0; k
<vomsgp
->fu
.nRects
; k
++) {
218 i
= read(fd
, &uprect
, sizeof(uprect
));
219 if (i
!= sizeof(uprect
))
221 uprect
.r
.x
= ntohs(uprect
.r
.x
);
222 uprect
.r
.y
= ntohs(uprect
.r
.y
);
223 uprect
.r
.w
= ntohs(uprect
.r
.w
);
224 uprect
.r
.h
= ntohs(uprect
.r
.h
);
225 if (uprect
.r
.x
>= cols
)
227 if (uprect
.r
.x
+ uprect
.r
.w
> cols
)
229 if (uprect
.r
.y
>= rows
)
231 if (uprect
.r
.y
+ uprect
.r
.h
> rows
)
233 for (i
=0; i
< uprect
.r
.w
* uprect
.r
.h
;) {
234 j
= read(fd
, updates
+ i
,
235 uprect
.r
.w
* uprect
.r
.h
- i
);
240 update_fb(updates
, uprect
.r
);
247 static int mr
, mc
; /* mouse position */
248 static int cmd
; /* command mode */
249 static char mk
[] = MOUSEKEYS
;
251 static void handle_mouse(int fd
, int c
)
253 rfbPointerEventMsg me
= {rfbPointerEvent
, 0, 0, 0};
255 switch (strchr(mk
, c
) - mk
) {
269 mask
= rfbButton1Mask
;
272 mask
= rfbButton2Mask
;
275 mask
= rfbButton3Mask
;
278 me
.y
= htons(MAX(0, MIN(rows
- 1, mr
)));
279 me
.x
= htons(MAX(0, MIN(cols
- 1, mc
)));
280 write(fd
, &me
, sizeof(me
));
282 me
.buttonMask
= mask
;
283 write(fd
, &me
, sizeof(me
));
285 write(fd
, &me
, sizeof(me
));
289 static int press(int fd
, int key
, int down
)
291 rfbKeyEventMsg ke
= {rfbKeyEvent
};
294 return write(fd
, &ke
, sizeof(ke
));
297 int parse_kbd_in(int kbdfd
, int fd
)
303 if ((j
= read(kbdfd
, buf
, sizeof(buf
))) <= 0 )
305 for (i
= 0; i
< j
; i
++) {
326 k
= (unsigned char) buf
[i
];
329 if (strchr(mk
, buf
[i
])) {
330 handle_mouse(fd
, buf
[i
]);
335 k
= (unsigned char) buf
[i
];
341 case '\x03': /* cmd ^c */
349 if (isupper(k
) || strchr(":\"<>?{}|+_()*&^%$#@!~", k
))
351 if (k
>= 1 && k
<= 26) {