7 #include <sys/socket.h>
8 #include <netinet/in.h>
23 /* lowest 2 bits in videoram are used for actual and future videoram.
24 * they are changing their roles by changing the vramactive
26 CARD8 vram
[VT52_YMAX
* VT52_XMAX
];
27 int deltabuf
[] = {0,1,1,0};
28 int joinbuf2
[] = {0,0,3,3};
29 #define VRAM(x,y) (vram[(y)*VT52_XMAX+(x)])
30 #define DELTA(x,y) (deltabuf[VRAM((x),(y))&3])
31 #define JOIN2(x,y) (joinbuf2[(VRAM(i,j)&2)])
32 /* and buffer for screen updates */
33 CARD8 updates
[VT52_YMAX
* VT52_XMAX
];
34 #define RED(x) ((x)&3)
35 #define GREEN(x) (((x)>>2)&7)
36 #define BLUE(x) (((x)>>5)&7)
39 void update_vram(CARD8
* buffer
, rfbRectangle r
)
45 if (GREEN(buffer
[i
+j
*r
.w
]) & 1)
46 VRAM(i
+r
.x
,j
+r
.y
) |= 2;
48 VRAM(i
+r
.x
,j
+r
.y
) &= ~2;
55 static int xphase
=0, yphase
=VT52_YMAX
-YSTEP
;
57 for (j
=yphase
; j
<yphase
+YSTEP
; j
++) {
59 for (i
=xphase
; i
<xphase
+XSTEP
; i
++)
60 if (DELTA(i
,j
) && k
==-1) {
62 } else if (!DELTA(i
,j
) && k
!=-1) {
63 gline(&kan
,k
,VT52_YMAX
-j
-1,i
-1,VT52_YMAX
-j
-1);
67 gline(&kan
,k
,VT52_YMAX
-j
-1,i
-1,VT52_YMAX
-j
-1);
71 for (i
=xphase
; i
<xphase
+XSTEP
; i
++)
72 for (j
=yphase
; j
<yphase
+YSTEP
; j
++)
73 VRAM(i
,j
) = JOIN2(i
,j
);
75 xphase
= (xphase
+XSTEP
)%VT52_XMAX
;
79 yphase
= VT52_YMAX
- YSTEP
;
86 int vncproto_init(char * addr
, int port
)
88 struct sockaddr_in si
;
89 rfbProtocolVersionMsg vmsg
;
90 rfbClientInitMsg clientinit
;
91 rfbServerInitMsg serverinit
;
92 rfbSetPixelFormatMsg pixformmsg
;
100 rfbSetEncodingsMsg
* encodingsmsgp
;
102 encodingsmsgp
= (rfbSetEncodingsMsg
*)malloc(sizeof(rfbSetEncodingsMsg
)+sizeof(CARD32
));
103 if (encodingsmsgp
== NULL
) {
104 perror("malloc: Cannot initiate communication");
108 si
.sin_family
= AF_INET
;
109 si
.sin_port
= htons(port
);
110 he
= gethostbyname(addr
);
112 si
.sin_addr
.s_addr
= *((unsigned long *)(he
->h_addr
));
113 else if (inet_aton(addr
, &(si
.sin_addr
)) < 0) {
114 fprintf(stderr
, "Cannot resolve hostname");
118 servsock
= socket(PF_INET
, SOCK_STREAM
, 0);
119 if (servsock
== -1) {
120 perror("Cannot create socket");
123 if (connect(servsock
, (struct sockaddr_in
*)&si
, sizeof(si
)) < 0) {
124 perror("Cannot connect");
128 sprintf(vmsg
, rfbProtocolVersionFormat
, rfbProtocolMajorVersion
, rfbProtocolMinorVersion
);
129 write(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
130 read(servsock
, vmsg
, sz_rfbProtocolVersionMsg
);
133 read(servsock
, &i32
, sizeof(i32
));
137 case rfbConnFailed
: /* conn failed */
138 puts("Remote server says: Connection failed");
140 read(servsock
, &i32
, sizeof(i32
));
141 while (i32
-- && (read(servsock
, &x
, sizeof(x
))==sizeof(x
)))
149 puts ("We don't support DES yet");
153 p
= getpass("Enter password: ");
161 /* ClientInitialisation */
162 clientinit
.shared
= 1; /* share */
163 write(servsock
, &clientinit
, sizeof(clientinit
));
165 read(servsock
, &serverinit
, sizeof(serverinit
));
167 fb_width
= ntohs(serverinit
.framebufferWidth
);
168 if (fb_width
> VT52_XMAX
)
169 fb_width
= VT52_XMAX
;
170 fb_height
= ntohs(serverinit
.framebufferHeight
);
171 if (fb_height
> VT52_YMAX
)
172 fb_height
= VT52_YMAX
;
174 i32
= ntohl(serverinit
.nameLength
);
175 for (i
=0; i
<i32
; i
++)
176 read(servsock
, &x
, 1);
178 pixformmsg
.type
= rfbSetPixelFormat
;
179 pixformmsg
.format
.bitsPerPixel
= 8;
180 pixformmsg
.format
.depth
= 8;
181 pixformmsg
.format
.bigEndian
= 0; /* don't care */
182 pixformmsg
.format
.trueColour
= 1;
184 pixformmsg
.format
.redMax
= htons(3);
185 pixformmsg
.format
.greenMax
= htons(7);
186 pixformmsg
.format
.blueMax
= htons(7);
188 pixformmsg
.format
.redShift
= 0;
189 pixformmsg
.format
.greenShift
= 2;
190 pixformmsg
.format
.blueShift
= 5;
192 write(servsock
, &pixformmsg
, sizeof(pixformmsg
));
194 encodingsmsgp
->type
= rfbSetEncodings
;
195 encodingsmsgp
->nEncodings
= htons(1);
196 *((CARD32
*)((void *)(encodingsmsgp
) + sizeof(rfbSetEncodingsMsg
))) = htonl(rfbEncodingRaw
);
197 write(servsock
, encodingsmsgp
, sizeof(*encodingsmsgp
)+sizeof(CARD32
));
200 memset(vram
, 0, VT52_YMAX
* VT52_XMAX
);
205 /* uncomment this, if you want to use the different transferr speed as default */
207 gset_scaling(&kan
, 0, 0);
208 gset_attrib(&kan
, GA_XOR
);
214 int request_vnc_refresh(int fd
)
216 rfbFramebufferUpdateRequestMsg updreq
;
217 static int incremental
= 0;
219 updreq
.type
= rfbFramebufferUpdateRequest
;
220 updreq
.incremental
= incremental
; incremental
=1;
223 updreq
.w
= htons(fb_width
);
224 updreq
.h
= htons(fb_height
);
226 write(fd
, &updreq
, sizeof(updreq
));
230 int parse_vnc_in(int fd
)
232 rfbFramebufferUpdateRectHeader uprect
;
233 rfbServerToClientMsg msg
;
234 rfbServerToClientMsg
* vomsgp
= &msg
;
237 i
= read (fd
, vomsgp
, sizeof(CARD8
));
238 if (i
!= sizeof(CARD8
))
240 switch (vomsgp
->type
) {
241 case rfbFramebufferUpdate
:
242 i
= read(fd
, ((void *)vomsgp
)+sizeof(CARD8
), sizeof(rfbFramebufferUpdateMsg
) - sizeof(CARD8
));
245 i
= read(fd
, ((void *)vomsgp
)+sizeof(CARD8
), sizeof(rfbBellMsg
) - sizeof(CARD8
));
247 case rfbServerCutText
:
248 i
= read(fd
, ((void *)vomsgp
)+sizeof(CARD8
), sizeof(rfbServerCutTextMsg
) - sizeof(CARD8
));
253 switch (vomsgp
->type
) {
255 gputc(&kan
, '\x07'); gflush(&kan
);
258 case rfbFramebufferUpdate
:
259 vomsgp
->fu
.nRects
= ntohs(vomsgp
->fu
.nRects
);
260 for (k
=0; k
<vomsgp
->fu
.nRects
; k
++) {
261 i
= read(fd
, &uprect
, sizeof(uprect
));
262 if (i
!= sizeof(uprect
))
264 uprect
.r
.x
= ntohs(uprect
.r
.x
);
265 uprect
.r
.y
= ntohs(uprect
.r
.y
);
266 uprect
.r
.w
= ntohs(uprect
.r
.w
);
267 uprect
.r
.h
= ntohs(uprect
.r
.h
);
268 if (uprect
.r
.x
>= fb_width
)
270 if (uprect
.r
.x
+uprect
.r
.w
> fb_width
)
272 if (uprect
.r
.y
>= fb_height
)
274 if (uprect
.r
.y
+uprect
.r
.h
> fb_height
)
276 for (i
=0; i
<uprect
.r
.w
*uprect
.r
.h
;) {
277 j
= read(fd
, updates
+i
, uprect
.r
.w
*uprect
.r
.h
-i
);
282 update_vram(updates
,uprect
.r
);
289 int parse_kbd_in(int kbdfd
, int fd
)
292 static rfbPointerEventMsg me
= {rfbPointerEvent
, 0, 0, 0};
293 static int mouse_on
= -1; static int mouse_factor
= 1;
296 static int vt_state
=VT_CHAR
;
297 static int ctrllock_state
= 0;
298 static int shiftlock_state
= 0;
302 if (mouse_on
== -1) {
303 me
.x
= htons(VT52_XMAX
/2);
304 me
.y
= htons(VT52_YMAX
/2);
306 ke
.type
= rfbKeyEvent
;
309 if ( (j
=read(kbdfd
, buf
, sizeof(buf
))) <= 0 )
311 for (i
=0; i
<j
; i
++) {
316 case '\x08': k
= 0xFF08; break;
317 case '\x09': k
= 0xFF09; break;
318 case '\x0d': if (!mouse_on
) {
321 case '1': case '2': case '3':
322 case '4': case '5': case '6':
323 case '7': case '8': case '9':
324 case '0': case '.': case '-':
327 k
= (unsigned char)buf
[i
];
332 if (mouse_factor
> 64)
336 if (buf
[i
] == '4' || buf
[i
] == '7' || buf
[i
] == '1')
337 if (ntohs(me
.x
)>mouse_factor
)
338 me
.x
= htons(ntohs(me
.x
)-mouse_factor
);
341 if (buf
[i
] == '6' || buf
[i
] == '9' || buf
[i
] == '3')
342 if (ntohs(me
.x
)+mouse_factor
< VT52_XMAX
-1)
343 me
.x
= htons(ntohs(me
.x
)+mouse_factor
);
345 me
.x
= htons(VT52_XMAX
-1);
346 if (buf
[i
] == '7' || buf
[i
] == '8' || buf
[i
] == '9')
347 if (ntohs(me
.y
)>mouse_factor
)
348 me
.y
= htons(ntohs(me
.y
)-mouse_factor
);
351 if (buf
[i
] == '1' || buf
[i
] == '2' || buf
[i
] == '3')
352 if (ntohs(me
.y
)+mouse_factor
< VT52_YMAX
-1)
353 me
.y
= htons(ntohs(me
.y
)+mouse_factor
);
355 me
.y
= htons(VT52_YMAX
-1);
357 if (buf
[i
]>='1' && buf
[i
]<='9') {
358 write(fd
, &me
, sizeof(me
));
362 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
363 write(fd
, &me
, sizeof(me
));
366 me
.buttonMask
= me
.buttonMask
^ rfbButton2Mask
;
367 write(fd
, &me
, sizeof(me
));
369 if (buf
[i
]=='\x0d') {
370 me
.buttonMask
= me
.buttonMask
^ rfbButton3Mask
;
371 write(fd
, &me
, sizeof(me
));
374 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
375 write(fd
, &me
, sizeof(me
));
376 me
.buttonMask
= me
.buttonMask
^ rfbButton1Mask
;
377 write(fd
, &me
, sizeof(me
));
380 me
.buttonMask
= me
.buttonMask
^ rfbButton2Mask
;
381 write(fd
, &me
, sizeof(me
));
382 me
.buttonMask
= me
.buttonMask
^ rfbButton2Mask
;
383 write(fd
, &me
, sizeof(me
));
386 case '\x1b': vt_state
= VT_ESC
; break;
387 default: k
= (unsigned char)buf
[i
];
392 case '\x1b': k
= (unsigned char)buf
[i
];
394 case '\x03': /* esc ^c */
396 case 'D': k
= 0xFF51; break;
397 case 'A': k
= 0xFF52; break;
398 case 'C': k
= 0xFF53; break;
399 case 'B': k
= 0xFF54; break;
400 case 'P': /* mouse lock */
401 mouse_on
= !mouse_on
;
403 case 'Q': /* control lock */
405 ke
.down
= ctrllock_state
;
407 write(fd
, &ke
, sizeof(ke
));
409 case 'R': /* shift lock */
410 shiftlock_state
^= 1;
411 ke
.down
= shiftlock_state
;
413 write(fd
, &ke
, sizeof(ke
));
415 default: k
= -1; break;
417 vt_state
=VT_CHAR
; break;
423 write(fd
, &ke
, sizeof(ke
));
425 write(fd
, &ke
, sizeof(ke
));