7 #include <sys/socket.h>
8 #include <netinet/in.h>
17 #define MAXRESOL (1 << 21)
20 static CARD16 cols
= 0;
21 static CARD16 rows
= 0;
23 /* and buffer for screen updates */
24 static CARD8 updates
[MAXRESOL
];
27 int vncproto_init(char * addr
, int port
)
29 struct sockaddr_in si
;
30 rfbProtocolVersionMsg vmsg
;
31 rfbClientInitMsg clientinit
;
32 rfbServerInitMsg serverinit
;
33 rfbSetPixelFormatMsg pixformmsg
;
41 rfbSetEncodingsMsg
* encodingsmsgp
;
43 encodingsmsgp
= (rfbSetEncodingsMsg
*)malloc(sizeof(rfbSetEncodingsMsg
)+sizeof(CARD32
));
44 if (encodingsmsgp
== NULL
) {
45 perror("malloc: Cannot initiate communication");
49 si
.sin_family
= AF_INET
;
50 si
.sin_port
= htons(port
);
51 he
= gethostbyname(addr
);
53 si
.sin_addr
.s_addr
= *((unsigned long *)(he
->h_addr
));
54 else if (inet_aton(addr
, &(si
.sin_addr
)) < 0) {
55 fprintf(stderr
, "Cannot resolve hostname");
59 servsock
= socket(PF_INET
, SOCK_STREAM
, 0);
61 perror("Cannot create socket");
64 if (connect(servsock
, (struct sockaddr
*)&si
, sizeof(si
)) < 0) {
65 perror("Cannot connect");
69 sprintf(vmsg
, rfbProtocolVersionFormat
, rfbProtocolMajorVersion
, rfbProtocolMinorVersion
);
70 write(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
71 read(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
74 read(servsock
, &i32
, sizeof(i32
));
78 case rfbConnFailed
: /* conn failed */
79 puts("Remote server says: Connection failed");
81 read(servsock
, &i32
, sizeof(i32
));
82 while (i32
-- && (read(servsock
, &x
, sizeof(x
))==sizeof(x
)))
90 puts ("We don't support DES yet");
94 p
= getpass("Enter password: ");
102 /* ClientInitialisation */
103 clientinit
.shared
= 1; /* share */
104 write(servsock
, &clientinit
, sizeof(clientinit
));
106 read(servsock
, &serverinit
, sizeof(serverinit
));
109 cols
= ntohs(serverinit
.framebufferWidth
);
110 if (cols
> fb_cols())
112 rows
= ntohs(serverinit
.framebufferHeight
);
113 if (rows
> fb_rows())
116 i32
= ntohl(serverinit
.nameLength
);
117 for (i
=0; i
<i32
; i
++)
118 read(servsock
, &x
, 1);
120 pixformmsg
.type
= rfbSetPixelFormat
;
121 pixformmsg
.format
.bitsPerPixel
= 8;
122 pixformmsg
.format
.depth
= 8;
123 pixformmsg
.format
.bigEndian
= 0; /* don't care */
124 pixformmsg
.format
.trueColour
= 1;
126 pixformmsg
.format
.redMax
= htons(3);
127 pixformmsg
.format
.greenMax
= htons(7);
128 pixformmsg
.format
.blueMax
= htons(7);
130 pixformmsg
.format
.redShift
= 0;
131 pixformmsg
.format
.greenShift
= 2;
132 pixformmsg
.format
.blueShift
= 5;
134 write(servsock
, &pixformmsg
, sizeof(pixformmsg
));
136 encodingsmsgp
->type
= rfbSetEncodings
;
137 encodingsmsgp
->nEncodings
= htons(1);
138 *((CARD32
*)((char *) encodingsmsgp
+
139 sizeof(rfbSetEncodingsMsg
))) = htonl(rfbEncodingRaw
);
140 write(servsock
, encodingsmsgp
, sizeof(*encodingsmsgp
)+sizeof(CARD32
));
144 int vncproto_free(void)
150 int request_vnc_refresh(int fd
, int inc
)
152 rfbFramebufferUpdateRequestMsg updreq
;
153 updreq
.type
= rfbFramebufferUpdateRequest
;
154 updreq
.incremental
= inc
;
157 updreq
.w
= htons(cols
);
158 updreq
.h
= htons(rows
);
159 write(fd
, &updreq
, sizeof(updreq
));
163 static void update_fb(CARD8
*buffer
, rfbRectangle r
)
165 fbval_t slice
[1 << 14];
167 for (i
= 0; i
< r
.h
; i
++) {
168 for (j
= 0; j
< r
.w
; j
++) {
169 unsigned char *p
= &buffer
[i
* r
.w
+ j
];
170 slice
[j
] = fb_color(*p
, *p
, *p
);
172 fb_set(r
.y
+ i
, r
.x
, slice
, r
.w
);
176 int must_redraw(void)
183 int parse_vnc_in(int fd
)
185 rfbFramebufferUpdateRectHeader uprect
;
186 rfbServerToClientMsg msg
;
187 rfbServerToClientMsg
* vomsgp
= &msg
;
190 i
= read (fd
, vomsgp
, sizeof(CARD8
));
191 if (i
!= sizeof(CARD8
))
193 switch (vomsgp
->type
) {
194 case rfbFramebufferUpdate
:
195 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
196 sizeof(rfbFramebufferUpdateMsg
) - sizeof(CARD8
));
199 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
200 sizeof(rfbBellMsg
) - sizeof(CARD8
));
202 case rfbServerCutText
:
203 i
= read(fd
, (char *) vomsgp
+ sizeof(CARD8
),
204 sizeof(rfbServerCutTextMsg
) - sizeof(CARD8
));
209 switch (vomsgp
->type
) {
213 case rfbFramebufferUpdate
:
214 vomsgp
->fu
.nRects
= ntohs(vomsgp
->fu
.nRects
);
215 for (k
=0; k
<vomsgp
->fu
.nRects
; k
++) {
216 i
= read(fd
, &uprect
, sizeof(uprect
));
217 if (i
!= sizeof(uprect
))
219 uprect
.r
.x
= ntohs(uprect
.r
.x
);
220 uprect
.r
.y
= ntohs(uprect
.r
.y
);
221 uprect
.r
.w
= ntohs(uprect
.r
.w
);
222 uprect
.r
.h
= ntohs(uprect
.r
.h
);
223 if (uprect
.r
.x
>= cols
)
225 if (uprect
.r
.x
+ uprect
.r
.w
> cols
)
227 if (uprect
.r
.y
>= rows
)
229 if (uprect
.r
.y
+ uprect
.r
.h
> rows
)
231 for (i
=0; i
< uprect
.r
.w
* uprect
.r
.h
;) {
232 j
= read(fd
, updates
+ i
,
233 uprect
.r
.w
* uprect
.r
.h
- i
);
238 update_fb(updates
, uprect
.r
);
246 #define ESCKEY '\x1b'
247 /* mouse keys: left, down, up, right, button1, button2, button3 */
248 #define MOUSEKEYS "hjkl\r \t"
249 /* mouse movements in pixels */
252 static int mr
, mc
; /* mouse position */
253 static int esc
; /* escape mode */
254 static char mk
[] = MOUSEKEYS
;
256 static void handle_mouse(int fd
, int c
)
258 rfbPointerEventMsg me
= {rfbPointerEvent
, 0, 0, 0};
260 switch (strchr(mk
, c
) - mk
) {
274 mask
= rfbButton1Mask
;
277 mask
= rfbButton2Mask
;
280 mask
= rfbButton3Mask
;
283 me
.y
= htons(MAX(0, MIN(rows
- 1, mr
)));
284 me
.x
= htons(MAX(0, MIN(cols
- 1, mc
)));
285 write(fd
, &me
, sizeof(me
));
287 me
.buttonMask
= mask
;
288 write(fd
, &me
, sizeof(me
));
290 write(fd
, &me
, sizeof(me
));
294 int parse_kbd_in(int kbdfd
, int fd
)
296 static rfbKeyEventMsg ke
= {rfbKeyEvent
};
300 if ((j
= read(kbdfd
, buf
, sizeof(buf
))) <= 0 )
302 for (i
= 0; i
< j
; i
++) {
319 k
= (unsigned char) buf
[i
];
322 if (strchr(mk
, buf
[i
])) {
323 handle_mouse(fd
, buf
[i
]);
328 k
= (unsigned char) buf
[i
];
334 case '\x03': /* esc ^c */
345 write(fd
, &ke
, sizeof(ke
));
347 write(fd
, &ke
, sizeof(ke
));