7 #include <sys/socket.h>
8 #include <netinet/in.h>
18 #define MAXRESOL (1 << 21)
21 static CARD16 cols
= 0;
22 static CARD16 rows
= 0;
24 /* and buffer for screen updates */
25 static CARD8 updates
[MAXRESOL
];
28 int vncproto_init(char * addr
, int port
)
30 struct sockaddr_in si
;
31 rfbProtocolVersionMsg vmsg
;
32 rfbClientInitMsg clientinit
;
33 rfbServerInitMsg serverinit
;
34 rfbSetPixelFormatMsg pixformmsg
;
42 rfbSetEncodingsMsg
* encodingsmsgp
;
44 encodingsmsgp
= (rfbSetEncodingsMsg
*)malloc(sizeof(rfbSetEncodingsMsg
)+sizeof(CARD32
));
45 if (encodingsmsgp
== NULL
) {
46 perror("malloc: Cannot initiate communication");
50 si
.sin_family
= AF_INET
;
51 si
.sin_port
= htons(port
);
52 he
= gethostbyname(addr
);
54 si
.sin_addr
.s_addr
= *((unsigned long *)(he
->h_addr
));
55 else if (inet_aton(addr
, &(si
.sin_addr
)) < 0) {
56 fprintf(stderr
, "Cannot resolve hostname");
60 servsock
= socket(PF_INET
, SOCK_STREAM
, 0);
62 perror("Cannot create socket");
65 if (connect(servsock
, (struct sockaddr
*)&si
, sizeof(si
)) < 0) {
66 perror("Cannot connect");
70 sprintf(vmsg
, rfbProtocolVersionFormat
, rfbProtocolMajorVersion
, rfbProtocolMinorVersion
);
71 write(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
72 read(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
75 read(servsock
, &i32
, sizeof(i32
));
79 case rfbConnFailed
: /* conn failed */
80 puts("Remote server says: Connection failed");
82 read(servsock
, &i32
, sizeof(i32
));
83 while (i32
-- && (read(servsock
, &x
, sizeof(x
))==sizeof(x
)))
91 puts ("We don't support DES yet");
95 p
= getpass("Enter password: ");
103 /* ClientInitialisation */
104 clientinit
.shared
= 1; /* share */
105 write(servsock
, &clientinit
, sizeof(clientinit
));
107 read(servsock
, &serverinit
, sizeof(serverinit
));
110 cols
= ntohs(serverinit
.framebufferWidth
);
111 if (cols
> fb_cols())
113 rows
= ntohs(serverinit
.framebufferHeight
);
114 if (rows
> fb_rows())
117 i32
= ntohl(serverinit
.nameLength
);
118 for (i
=0; i
<i32
; i
++)
119 read(servsock
, &x
, 1);
121 pixformmsg
.type
= rfbSetPixelFormat
;
122 pixformmsg
.format
.bitsPerPixel
= 8;
123 pixformmsg
.format
.depth
= 8;
124 pixformmsg
.format
.bigEndian
= 0; /* don't care */
125 pixformmsg
.format
.trueColour
= 1;
127 pixformmsg
.format
.redMax
= htons(3);
128 pixformmsg
.format
.greenMax
= htons(7);
129 pixformmsg
.format
.blueMax
= htons(7);
131 pixformmsg
.format
.redShift
= 0;
132 pixformmsg
.format
.greenShift
= 2;
133 pixformmsg
.format
.blueShift
= 5;
135 write(servsock
, &pixformmsg
, sizeof(pixformmsg
));
137 encodingsmsgp
->type
= rfbSetEncodings
;
138 encodingsmsgp
->nEncodings
= htons(1);
139 *((CARD32
*)((char *) encodingsmsgp
+
140 sizeof(rfbSetEncodingsMsg
))) = htonl(rfbEncodingRaw
);
141 write(servsock
, encodingsmsgp
, sizeof(*encodingsmsgp
)+sizeof(CARD32
));
145 int vncproto_free(void)
151 int request_vnc_refresh(int fd
, int inc
)
153 rfbFramebufferUpdateRequestMsg updreq
;
154 updreq
.type
= rfbFramebufferUpdateRequest
;
155 updreq
.incremental
= inc
;
158 updreq
.w
= htons(cols
);
159 updreq
.h
= htons(rows
);
160 write(fd
, &updreq
, sizeof(updreq
));
164 static void update_fb(CARD8
*buffer
, rfbRectangle r
)
166 fbval_t slice
[1 << 14];
168 for (i
= 0; i
< r
.h
; i
++) {
169 for (j
= 0; j
< r
.w
; j
++) {
170 unsigned char *p
= &buffer
[i
* r
.w
+ j
];
171 slice
[j
] = fb_color(*p
, *p
, *p
);
173 fb_set(r
.y
+ i
, r
.x
, slice
, r
.w
);
177 int must_redraw(void)
184 int parse_vnc_in(int fd
)
186 rfbFramebufferUpdateRectHeader uprect
;
187 rfbServerToClientMsg msg
;
188 rfbServerToClientMsg
* vomsgp
= &msg
;
191 i
= read (fd
, vomsgp
, sizeof(CARD8
));
192 if (i
!= sizeof(CARD8
))
194 switch (vomsgp
->type
) {
195 case rfbFramebufferUpdate
:
196 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
197 sizeof(rfbFramebufferUpdateMsg
) - sizeof(CARD8
));
200 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
201 sizeof(rfbBellMsg
) - sizeof(CARD8
));
203 case rfbServerCutText
:
204 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
205 sizeof(rfbServerCutTextMsg
) - sizeof(CARD8
));
210 switch (vomsgp
->type
) {
214 case rfbFramebufferUpdate
:
215 vomsgp
->fu
.nRects
= ntohs(vomsgp
->fu
.nRects
);
216 for (k
=0; k
<vomsgp
->fu
.nRects
; k
++) {
217 i
= read(fd
, &uprect
, sizeof(uprect
));
218 if (i
!= sizeof(uprect
))
220 uprect
.r
.x
= ntohs(uprect
.r
.x
);
221 uprect
.r
.y
= ntohs(uprect
.r
.y
);
222 uprect
.r
.w
= ntohs(uprect
.r
.w
);
223 uprect
.r
.h
= ntohs(uprect
.r
.h
);
224 if (uprect
.r
.x
>= cols
)
226 if (uprect
.r
.x
+ uprect
.r
.w
> cols
)
228 if (uprect
.r
.y
>= rows
)
230 if (uprect
.r
.y
+ uprect
.r
.h
> rows
)
232 for (i
=0; i
< uprect
.r
.w
* uprect
.r
.h
;) {
233 j
= read(fd
, updates
+ i
,
234 uprect
.r
.w
* uprect
.r
.h
- i
);
239 update_fb(updates
, uprect
.r
);
246 static int mr
, mc
; /* mouse position */
247 static int cmd
; /* command mode */
248 static char mk
[] = MOUSEKEYS
;
250 static void handle_mouse(int fd
, int c
)
252 rfbPointerEventMsg me
= {rfbPointerEvent
, 0, 0, 0};
254 switch (strchr(mk
, c
) - mk
) {
268 mask
= rfbButton1Mask
;
271 mask
= rfbButton2Mask
;
274 mask
= rfbButton3Mask
;
277 me
.y
= htons(MAX(0, MIN(rows
- 1, mr
)));
278 me
.x
= htons(MAX(0, MIN(cols
- 1, mc
)));
279 write(fd
, &me
, sizeof(me
));
281 me
.buttonMask
= mask
;
282 write(fd
, &me
, sizeof(me
));
284 write(fd
, &me
, sizeof(me
));
288 int parse_kbd_in(int kbdfd
, int fd
)
290 static rfbKeyEventMsg ke
= {rfbKeyEvent
};
294 if ((j
= read(kbdfd
, buf
, sizeof(buf
))) <= 0 )
296 for (i
= 0; i
< j
; i
++) {
313 k
= (unsigned char) buf
[i
];
316 if (strchr(mk
, buf
[i
])) {
317 handle_mouse(fd
, buf
[i
]);
322 k
= (unsigned char) buf
[i
];
328 case '\x03': /* cmd ^c */
339 write(fd
, &ke
, sizeof(ke
));
341 write(fd
, &ke
, sizeof(ke
));