VNC client: bugfixes, better GUI, error reporting.

git-svn-id: svn://kolibrios.org@5668 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2015-08-03 18:07:56 +00:00
parent 1b36f8ca5f
commit ffa9fb9858
7 changed files with 588 additions and 356 deletions

View File

@ -12,7 +12,7 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
encoding_copyrect: encoding_CopyRect:
DEBUGF 1,"CopyRect\n" DEBUGF 1,"CopyRect\n"
@ -35,22 +35,22 @@ encoding_copyrect:
add eax, ebx ; [screen.width]*[src.y]+[src.x] add eax, ebx ; [screen.width]*[src.y]+[src.x]
lea esi, [framebuffer_data+eax*3] ; esi = framebuffer_data+([screen.width]*[src.y]+[src.x])*3 lea esi, [framebuffer_data+eax*3] ; esi = framebuffer_data+([screen.width]*[src.y]+[src.x])*3
movzx eax, [rectangle.y] mov eax, [rectangle.y]
movzx ebx, [screen.width] movzx ebx, [screen.width]
mul ebx ; [screen.width]*[rectangle.y] mul ebx ; [screen.width]*[rectangle.y]
movzx ebx, [rectangle.x] mov ebx, [rectangle.x]
add eax, ebx ; [screen.width]*[rectangle.y]+[rectangle.x] add eax, ebx ; [screen.width]*[rectangle.y]+[rectangle.x]
lea edi, [framebuffer_data+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3 lea edi, [framebuffer_data+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3
movzx eax, [screen.width] movzx eax, [screen.width]
sub ax, [rectangle.width] sub eax, [rectangle.width]
lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3 lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3
cmp esi, edi cmp esi, edi
ja .copy ja .copy
; source pixels come before destination in buffer, copy backwards ; source pixels come before destination in buffer, copy backwards
movzx eax, [rectangle.height] mov eax, [rectangle.height]
movzx edx, [screen.width] movzx edx, [screen.width]
mul edx mul edx
lea eax, [eax*3-1] lea eax, [eax*3-1]
@ -61,8 +61,8 @@ encoding_copyrect:
std std
.copy: .copy:
movzx edx, [rectangle.height] mov edx, [rectangle.height]
movzx ecx, [rectangle.width] mov ecx, [rectangle.width]
lea ecx, [ecx*3] lea ecx, [ecx*3]
.lineloop: .lineloop:
push ecx push ecx

View File

@ -0,0 +1,163 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VNC client for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
draw_gui:
mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY
.redraw:
mcall 12, 1 ; start window draw
; DRAW WINDOW
xor eax, eax ; function 0 _logon: define and draw window
mov ebx, 160 shl 16 + 330 ; [x start]:[x size]
mov ecx, 160 shl 16 + 100 ; [y start]:[y size]
mov edx, 0x34DDDDDD ; color of work area RRGGBB
mov edi, name ; WINDOW LABEL
mcall
cmp [status], STATUS_INITIAL
jne @f
mov ebx, 25 shl 16 + 15
xor ecx, ecx
mov edx, serverstr
mov esi, userstr-serverstr
mcall 4 ; "server" text
invoke edit_box_draw, URLbox ; Server textbox
mov ebx, 220 shl 16 + 85
mov ecx, 47 shl 16 + 16
mov edx, 2
mov esi, 0xCCCCCC
mcall 8 ; Connect button
mov ebx, 240 shl 16 + 49
mov edx, connectstr
mov esi, loginstr-connectstr
mcall 4 ; Connect button text
jmp .redraw_done
@@:
cmp [status], STATUS_LOGIN
jne @f
mov ebx, 25 shl 16 + 15
xor ecx, ecx
mov edx, userstr
mov esi, passstr-userstr
mcall 4 ; "user" text
add bl, 19
mov edx, passstr
mov esi, connectstr-passstr ; "password" text
mcall
mov ebx, 220 shl 16 + 85
mov ecx, 47 shl 16 + 16
mov edx, 3
mov esi, 0xCCCCCC
mcall 8 ; Login button
mov ebx, 240 shl 16 + 49
mov edx, loginstr
mov esi, loginstr_e-loginstr
mcall 4 ; Login button text
jmp .redraw_done
@@:
mov ebx, 25 shl 16 + 15
mov ecx, 0x80ca0000 ; red ASCIIZ string
mov edx, [status]
sub edx, 10
mov edx, [err_msg+4*edx]
mcall 4 ; print error message to window
.redraw_done:
mov [update_gui], 0
mcall 12, 2
.loop:
cmp [update_gui], 0
jne .redraw
cmp [status], STATUS_CONNECTED
je .connected
mcall 23, 10 ; wait for event
dec eax ; redraw request ?
jz .redraw
dec eax ; key in buffer ?
jz .key
dec eax ; button in buffer ?
jz .btn
sub eax, 3
jz .mouse
jmp .loop
.connected:
ret
.key: ; key event handler
mcall 2 ; read key
cmp [status], STATUS_INITIAL
jne @f
test [URLbox.flags], ed_focus
jz mainloop
cmp ah, 13 ; enter (return) key
je .connect
invoke edit_box_key, URLbox
@@:
jmp .loop
.btn:
mcall 17 ; get id
cmp ah, 1 ; close ?
jz .close
cmp ah, 2 ; connect ?
je .connect
cmp ah, 3 ; login ?
je .login
jmp .loop
.connect:
mov eax, [URLbox.pos]
mov byte[serveraddr+eax], 0
; Create network thread
mcall 51, 1, thread_start, thread_stack
cmp eax, -1
jne @f
mov [status], STATUS_THREAD_ERR
inc [update_gui]
@@:
jmp .loop
.login:
;;;
ret
.mouse:
mcall 23
cmp [status], STATUS_INITIAL
jne @f
invoke edit_box_mouse, URLbox
@@:
jmp .loop
.close:
mcall -1

View File

@ -1,135 +0,0 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VNC client for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
logon:
mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY
.redraw:
mcall 12, 1 ; start window draw
pusha
; DRAW WINDOW
xor eax, eax ; function 0 _logon: define and draw window
mov ebx, 160 shl 16 + 330 ; [x start]:[x size]
mov ecx, 160 shl 16 + 100 ; [y start]:[y size]
mov edx, 0x34DDDDDD ; color of work area RRGGBB
mov edi, name ; WINDOW LABEL
mcall
mov eax, 8 ; LOGON BUTTON
mov ebx, 220 shl 16 + 85
mov ecx, 47 shl 16 + 16
mov edx, 2
mov esi, 0xCCCCCC
mcall
cmp byte[mode], 0
je .servermode
mov eax, 4 ; function 4 write text to window
mov ebx, 25 shl 16 + 15 ; [x start]:[y start]
xor ecx, ecx
mov edx, userstr ; pointer to text beginning
mov esi, passstr-userstr ; text length
mcall
add bl, 19
mov edx, passstr ; pointer to text beginning
mov esi, connectstr-passstr ; text length
mcall
jmp .drawtherest
.servermode:
mov eax, 4 ; function 4 write text to window
mov ebx, 25 shl 16 + 15 ; [x start] *65536 + [y start]
xor ecx, ecx
mov edx, serverstr ; pointer to text beginning
mov esi, userstr-serverstr ; text length
mcall
invoke edit_box_draw, URLbox
.drawtherest:
mov ebx, 240 shl 16 + 49 ; [x start] *65536 + [y start]
mov edx, connectstr ; pointer to text beginning
mov esi, connect_e-connectstr ; text length
mcall
popa
inc ebx
mcall
.loop:
mcall 10 ; wait for event
dec eax ; redraw request ?
jz .redraw
dec eax ; key in buffer ?
jz .key
dec eax ; button in buffer ?
jz .btn
sub eax, 3
jz .mouse
jmp .loop
.key: ; key event handler
mcall 2 ; read key
test [URLbox.flags], ed_focus
jz mainloop
cmp ah, 13 ; enter (return) key
je .go
invoke edit_box_key, URLbox
jmp .loop
.go:
mov eax, [URLbox.pos]
mov byte[serveraddr+eax], 0
ret
.btn:
mcall 17 ; get id
cmp ah, 1 ; close ?
jz .close
cmp ah, 2 ; logon ?
je .go
jmp .loop
.mouse:
mcall 23
invoke edit_box_mouse, URLbox
jmp .loop
.close:
mcall -1
; DATA AREA
passchar db "*"
passlen dd 0
addr dd 0
temp dd 0
mode db 0 ; 0 = connection details, 1 = authentication
serverstr db "server:"
userstr db "username:"
passstr db "password:"
connectstr db "connect !"
connect_e:
I_END_logon:

View File

@ -14,9 +14,7 @@
thread_start: thread_start:
DEBUGF 1, "I am the thread!\n" mcall 40, 0 ; disable all events for this thread
mcall 40, 0 ; disable all events
; resolve name ; resolve name
push esp ; reserve stack place push esp ; reserve stack place
@ -24,7 +22,7 @@ thread_start:
pop esi pop esi
; test for error ; test for error
test eax, eax test eax, eax
jnz exit jnz err_dns
mov eax, [esi+addrinfo.ai_addr] mov eax, [esi+addrinfo.ai_addr]
mov eax, [eax+sockaddr_in.sin_addr] mov eax, [eax+sockaddr_in.sin_addr]
@ -35,40 +33,37 @@ thread_start:
[sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \ [sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \
[sockaddr1.port]:2 [sockaddr1.port]:2
invoke freeaddrinfo, esi
mcall socket, AF_INET4, SOCK_STREAM, 0 mcall socket, AF_INET4, SOCK_STREAM, 0
test eax, eax cmp eax, -1
jz exit je err_sock
;;; invoke freeaddrinfo, ??
mov [socketnum], eax mov [socketnum], eax
mcall connect, [socketnum], sockaddr1, 18 mcall connect, [socketnum], sockaddr1, 18
;;; test eax, eax cmp eax, -1
je err_connect
; TODO: implement timeout ; TODO: implement timeout
call wait_for_data call wait_for_data
cmp dword[receive_buffer], "RFB " cmp dword[receive_buffer], "RFB "
jne no_rfb jne err_proto
DEBUGF 1, "received: %s\n", receive_buffer DEBUGF 1, "received: %s\n", receive_buffer
mcall send, [socketnum], handshake, 12, 0 mcall send, [socketnum], HandShake, 12, 0
DEBUGF 1, "Sending handshake: protocol version\n" DEBUGF 1, "Sending handshake: protocol version\n"
call wait_for_data call wait_for_data
cmp dword[receive_buffer], 0x00000000
je invalid_security
cmp dword[receive_buffer], 0x01000000 cmp dword[receive_buffer], 0x01000000
je no_security je no_security
cmp dword[receive_buffer], 0x02000000 cmp dword[receive_buffer], 0x02000000
je vnc_security je vnc_security
jmp err_security
DEBUGF 1, "Unknown security type\n"
jmp exit
vnc_security: vnc_security:
mov byte[mode], 1 mov [status], STATUS_LOGIN
call logon call draw_gui
no_security: no_security:
mcall send, [socketnum], ClientInit, 1, 0 mcall send, [socketnum], ClientInit, 1, 0
@ -83,26 +78,40 @@ no_security:
[receive_buffer+framebuffer.pixelformat.true_color]:1 [receive_buffer+framebuffer.pixelformat.true_color]:1
mov eax, dword[receive_buffer+framebuffer.width] mov eax, dword[receive_buffer+framebuffer.width]
mov dword[fbur.width], eax mov dword[FramebufferUpdateRequest.width], eax
bswap eax bswap eax
mov dword[screen], eax mov dword[screen], eax
DEBUGF 1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2 DEBUGF 1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2
mcall send, [socketnum], pixel_format8, 20, 0 mcall send, [socketnum], SetPixelFormat8, 20, 0
DEBUGF 1, "Sending pixel format\n" DEBUGF 1, "Sending pixel format\n"
mcall send, [socketnum], encodings, 12, 0 mcall send, [socketnum], SetEncodings, 12, 0
DEBUGF 1, "Sending encoding info\n" DEBUGF 1, "Sending encoding info\n"
mov [thread_ready], 1 ; Set main window caption to servername
mov ecx, dword[receive_buffer+framebuffer.name_length]
bswap ecx
cmp ecx, 64
jbe @f
mov ecx, 64
@@:
lea esi, [receive_buffer+framebuffer.name]
mov edi, servername
rep movsb
mov byte[edi], 0
mov [name.dash], "-"
; Tell the main thread we are ready for business!
mov [status], STATUS_CONNECTED
; Request initial update ; Request initial update
mov [fbur.inc], 0 mov [FramebufferUpdateRequest.inc], 0
request_fbu: request_fbu:
DEBUGF 1, "Requesting framebuffer update\n" DEBUGF 1, "Requesting framebuffer update\n"
mcall send, [socketnum], fbur, 10, 0 mcall send, [socketnum], FramebufferUpdateRequest, 10, 0
mov [fbur.inc], 1 mov [FramebufferUpdateRequest.inc], 1
thread_loop: thread_loop:
call read_data ; Read the data into the buffer call read_data ; Read the data into the buffer
@ -147,17 +156,19 @@ rectangle_loop:
jmp @b jmp @b
@@: @@:
lodsd ; position xor eax, eax
bswap eax lodsw
mov [rectangle.y], ax xchg al, ah
shr eax, 16 mov [rectangle.x], eax
mov [rectangle.x], ax lodsw
xchg al, ah
lodsd ; size mov [rectangle.y], eax
bswap eax lodsw
mov [rectangle.height], ax xchg al, ah
shr eax, 16 mov [rectangle.width], eax
mov [rectangle.width], ax lodsw
xchg al, ah
mov [rectangle.height], eax
lodsd ; encoding lodsd ; encoding
DEBUGF 1, "rectangle: width=%u height=%u x=%u y=%u encoding: ",\ DEBUGF 1, "rectangle: width=%u height=%u x=%u y=%u encoding: ",\
@ -166,9 +177,9 @@ rectangle_loop:
cmp eax, 0 cmp eax, 0
je encoding_raw je encoding_raw
cmp eax, 1 cmp eax, 1
je encoding_copyrect je encoding_CopyRect
; cmp eax, 2 cmp eax, 2
; je encoding_RRE je encoding_RRE
; cmp eax, 5 ; cmp eax, 5
; je encoding_hextile ; je encoding_hextile
; cmp eax, 15 ; cmp eax, 15
@ -179,8 +190,6 @@ rectangle_loop:
DEBUGF 1, "\nunknown encoding: %u\n", eax DEBUGF 1, "\nunknown encoding: %u\n", eax
jmp thread_loop jmp thread_loop
;; jmp rectangle_loop
next_rectangle: next_rectangle:
push esi push esi
call drawbuffer call drawbuffer
@ -245,30 +254,65 @@ read_data:
mcall recv, [socketnum], [datapointer], 4096, 0 mcall recv, [socketnum], [datapointer], 4096, 0
pop edi esi edx ecx ebx pop edi esi edx ecx ebx
cmp eax, -1 cmp eax, -1
je .error je err_disconnected
add [datapointer], eax ; TODO: check for buffer overflow add [datapointer], eax
; Check for buffer overflow
cmp [datapointer], receive_buffer + RECEIVE_BUFFER_SIZE
jbe @f
; Buffer is full, first needed data by program is pointed to by esi.
; Move all remaining data, starting from esi, to begin of buffer
cmp esi, receive_buffer
je err_proto
mov ecx, [datapointer]
sub ecx, esi
mov edi, receive_buffer
rep movsb
mov [datapointer], edi
mov esi, receive_buffer
@@:
cmp eax, 4096 cmp eax, 4096
je .more je .more
ret ret
.error:
DEBUGF 1, "Socket error!\n"
mcall -1
ret
wait_for_data: ; FIXME: add timeout wait_for_data: ; FIXME: add timeout
mcall recv, [socketnum], receive_buffer, 4096, 0 mcall recv, [socketnum], receive_buffer, 4096, 0
cmp eax, -1 cmp eax, -1
je .error je err_disconnected
test eax, eax test eax, eax
jz wait_for_data jz wait_for_data
ret ret
.error:
DEBUGF 1, "Socket error!\n" err_disconnected:
mov [status], STATUS_DISCONNECTED
inc [update_gui]
mcall -1
err_dns:
mov [status], STATUS_DNS_ERR
inc [update_gui]
mcall -1
err_sock:
mov [status], STATUS_SOCK_ERR
inc [update_gui]
mcall -1
err_connect:
mov [status], STATUS_CONNECT_ERR
inc [update_gui]
mcall -1 mcall -1
ret ret
err_proto:
mov [status], STATUS_PROTO_ERR
inc [update_gui]
mcall -1
ret
err_security:
mov [status], STATUS_SECURITY_ERR
inc [update_gui]
mcall -1
ret

View File

@ -16,8 +16,8 @@ encoding_raw:
DEBUGF 1,"RAW\n" DEBUGF 1,"RAW\n"
movzx eax, [rectangle.width] mov eax, [rectangle.width]
movzx ebx, [rectangle.height] mov ebx, [rectangle.height]
mul ebx mul ebx
add eax, esi add eax, esi
@@: @@:
@ -29,23 +29,23 @@ encoding_raw:
jmp @b jmp @b
@@: @@:
movzx eax, [rectangle.y] mov eax, [rectangle.y]
movzx ebx, [screen.width] movzx ebx, [screen.width]
mul ebx ; [screen.width]*[rectangle.y] mul ebx ; [screen.width]*[rectangle.y]
movzx ebx, [rectangle.x] mov ebx, [rectangle.x]
add eax, ebx ; [screen.width]*[rectangle.y]+[rectangle.x] add eax, ebx ; [screen.width]*[rectangle.y]+[rectangle.x]
lea edi, [framebuffer_data+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3 lea edi, [framebuffer_data+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3
movzx eax, [screen.width] movzx eax, [screen.width]
sub ax, [rectangle.width] sub eax, [rectangle.width]
lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3 lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3
mov bl, 85 mov bl, 85
movzx edx, [rectangle.height] mov edx, [rectangle.height]
.lineloop: .lineloop:
movzx ecx, [rectangle.width] mov ecx, [rectangle.width]
.pixelloop: .pixelloop:
mov al, [esi] mov al, [esi]

View File

@ -0,0 +1,130 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VNC client for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
pixel_to_24bpp: ; returns in ecx, destroys eax, ebx
; Convert pixel to 24BPP
mov bl, 85
mov al, [esi]
shr al, 4
and al, 3
mul bl
mov cl, al
mov al, [esi]
shr al, 2
and al, 3
mul bl
mov ch, al
mov al, [esi]
and al, 3
mul bl
shl ecx, 8
mov cl, al
ret
encoding_RRE:
DEBUGF 1,"RRE\n"
@@:
lea eax, [esi+5]
cmp [datapointer], eax
jae @f
call read_data.more
jmp @b
@@:
lodsd
bswap eax
mov [subrectangles], eax
call pixel_to_24bpp
movzx eax, [screen.width]
mul [rectangle.y] ; [screen.width]*[rectangle.y]
add eax, [rectangle.x] ; [screen.width]*[rectangle.y]+[rectangle.x]
lea edi, [framebuffer_data+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3
movzx eax, [screen.width]
sub eax, [rectangle.width]
lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3
push edi
mov eax, ecx
mov edx, [rectangle.height]
.lineloop:
mov ecx, [rectangle.width]
.pixelloop:
stosw
rol eax, 16
stosb
rol eax, 16
dec ecx
jnz .pixelloop
add edi, ebp
dec edx
jnz .lineloop
pop edi
.subrectangle:
@@:
lea eax, [esi+9]
cmp [datapointer], eax
jae @f
call read_data.more
jmp @b
@@:
call pixel_to_24bpp
xor eax, eax
lodsw
xchg al, ah
mov [subrectangle.x], eax
lodsw
xchg al, ah
mov [subrectangle.y], eax
lodsw
xchg al, ah
mov [subrectangle.height], eax
lodsw
xchg al, ah
mov [subrectangle.width], eax
push edi
mov eax, [rectangle.width]
mul [subrectangle.y]
add eax, [subrectangle.x]
add edi, eax
mov eax, ecx
mov edx, [subrectangle.height]
.lineloop2:
mov ecx, [subrectangle.width]
.pixelloop2:
stosw
rol eax, 16
stosb
rol eax, 16
dec ecx
jnz .pixelloop2
add edi, ebp
dec edx
jnz .lineloop2
pop edi
dec [subrectangles]
jnz .subrectangle
jmp next_rectangle

View File

@ -3,7 +3,7 @@
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; vncc.asm - VNC client for KolibriOS ;; ;; VNC client for KolibriOS ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;; ;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
@ -17,11 +17,6 @@ format binary as ""
__DEBUG__ = 1 __DEBUG__ = 1
__DEBUG_LEVEL__ = 1 __DEBUG_LEVEL__ = 1
xpos = 4 ; coordinates of image
ypos = 22 ;
TIMEOUT = 5 ; timeout in seconds
use32 use32
org 0x0 org 0x0
@ -34,7 +29,6 @@ use32
dd IM_END ; esp dd IM_END ; esp
dd 0x0, 0x0 ; I_Param , I_Path dd 0x0, 0x0 ; I_Param , I_Path
include "../../macros.inc" include "../../macros.inc"
include "../../debug-fdo.inc" include "../../debug-fdo.inc"
include "../../proc32.inc" include "../../proc32.inc"
@ -65,34 +59,49 @@ struct framebuffer
name rb 256 name rb 256
ends ends
include "logon.inc" xpos = 4
ypos = 22
TIMEOUT = 5 ; timeout in seconds
RECEIVE_BUFFER_SIZE = 8*1024*1024 ; 8 Mib
STATUS_INITIAL = 0
STATUS_CONNECTING = 1
STATUS_LOGIN = 2
STATUS_CONNECTED = 3
STATUS_DISCONNECTED = 10
STATUS_DNS_ERR = 11
STATUS_SOCK_ERR = 12
STATUS_CONNECT_ERR = 13
STATUS_PROTO_ERR = 14
STATUS_SECURITY_ERR = 15
STATUS_LIB_ERR = 16
STATUS_THREAD_ERR = 17
include "gui.inc"
include "network.inc"
include "raw.inc" include "raw.inc"
include "copyrect.inc" include "copyrect.inc"
include "thread.inc" include "rre.inc"
START: START:
mcall 68, 11 ; init heap mcall 68, 11 ; init heap
; load libraries ; Load libraries
stdcall dll.Load, @IMPORT stdcall dll.Load, @IMPORT
test eax, eax test eax, eax
jnz exit jz @f
mov [status], STATUS_LIB_ERR
call logon
mcall 40, 0 ; disable all events
mcall 67, 0, 0, 0, 0 ; resize the window (hide it)
mcall 51, 1, thread_start, thread_stack
DEBUGF 1,"Thread created: %u\n", eax
@@: @@:
mcall 5, 10
cmp byte[thread_ready], 0
je @r
mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_KEY + EVM_REDRAW + EVM_BUTTON ; Present the user with the GUI and wait for network connection
call draw_gui
; Create main window
mcall 71, 1, name ; reset window caption (add server name)
mov edx, dword[screen] mov edx, dword[screen]
movzx esi, dx movzx esi, dx
@ -101,54 +110,9 @@ START:
add esi, ypos+xpos add esi, ypos+xpos
mcall 67, 10, 10 ; resize the window mcall 67, 10, 10 ; resize the window
mainloop: mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_KEY + EVM_REDRAW + EVM_BUTTON
mcall 10 ; wait for event
dec eax
jz redraw
dec eax
jz key
dec eax
jz button
sub eax, 3
jz mouse
jmp mainloop
key:
; DEBUGF 1,"Sending key event\n"
mcall 2
mov byte[keyevent.key+3], ah
mcall send, [socketnum], keyevent, 8, 0
jmp mainloop
mouse:
; DEBUGF 1,"Sending mouse event\n"
mcall 37, 1 ; get mouse pos
sub eax, xpos shl 16 + ypos
bswap eax
mov [pointerevent.x], ax
shr eax, 16
mov [pointerevent.y], ax
mcall 37, 2 ; get mouse buttons
test al, 00000010b ; test if right button was pressed (bit 1 in kolibri)
jz @f
add al, 00000010b ; in RFB protocol it is bit 2, so if we add bit 2 again, we"ll get bit 3 and bit 1 will remain the same
@@:
mov [pointerevent.mask],al
mcall send, [socketnum], pointerevent, 6, 0
jmp mainloop
redraw: redraw:
; DEBUGF 1,"Drawing window\n"
mcall 12, 1 mcall 12, 1
mov ebx, dword[screen] mov ebx, dword[screen]
@ -162,38 +126,69 @@ redraw:
mcall 12, 2 mcall 12, 2
mainloop:
cmp [status], STATUS_CONNECTED
jne draw_gui
mcall 23, 100 ; Check for event with 1s timeout
dec eax
jz redraw
dec eax
jz key
dec eax
jz button
sub eax, 3
jz mouse
jmp mainloop jmp mainloop
drawbuffer: drawbuffer:
mcall 7, framebuffer_data, dword[screen], 0 mcall 7, framebuffer_data, dword[screen], 0
ret ret
key:
; DEBUGF 1, "Sending key event\n"
mcall 2
mov byte[KeyEvent.key+3], ah
mcall send, [socketnum], KeyEvent, 8, 0
jmp mainloop
mouse:
; DEBUGF 1, "Sending mouse event\n"
mcall 37, 1 ; get mouse pos
sub eax, xpos shl 16 + ypos
bswap eax
mov [PointerEvent.x], ax
shr eax, 16
mov [PointerEvent.y], ax
mcall 37, 2 ; get mouse buttons
test al, 00000010b ; test if right button was pressed (bit 1 in kolibri)
jz @f
add al, 00000010b ; in RFB protocol it is bit 2, so if we add bit 2 again, we"ll get bit 3 and bit 1 will remain the same
@@:
mov [PointerEvent.mask], al
mcall send, [socketnum], PointerEvent, 6, 0
jmp mainloop
button: button:
mcall 17 ; get id mcall 17 ; get id
exit:
DEBUGF 1, "Closing time!\n"
mcall close, [socketnum]
mcall -1 mcall -1
no_rfb:
DEBUGF 1, "This is no vnc server!\n"
jmp exit
invalid_security:
DEBUGF 1, "Security error: %s\n", receive_buffer+5
jmp exit
; DATA AREA ; DATA AREA
include_debug_strings ; ALWAYS present in data section include_debug_strings
HandShake db "RFB 003.003", 10
handshake db "RFB 003.003", 10
ClientInit db 0 ; not shared ClientInit db 0 ; not shared
beep db 0x85, 0x25, 0x85, 0x40, 0
pixel_format32 db 0 ; setPixelformat SetPixelFormat32 db 0 ; setPixelformat
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
.bpp db 32 ; bits per pixel .bpp db 32 ; bits per pixel
.depth db 32 ; depth .depth db 32 ; depth
@ -207,7 +202,7 @@ pixel_format32 db 0 ; setPixelformat
.blue_shift db 16 ; blue-shift .blue_shift db 16 ; blue-shift
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
pixel_format16 db 0 ; setPixelformat SetPixelFormat16 db 0 ; setPixelformat
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
.bpp db 16 ; bits per pixel .bpp db 16 ; bits per pixel
.depth db 15 ; depth .depth db 15 ; depth
@ -221,7 +216,7 @@ pixel_format16 db 0 ; setPixelformat
.blue_shift db 10 ; blue-shift .blue_shift db 10 ; blue-shift
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
pixel_format8 db 0 ; setPixelformat SetPixelFormat8 db 0 ; setPixelformat
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
.bpp db 8 ; bits per pixel .bpp db 8 ; bits per pixel
.depth db 6 ; depth .depth db 6 ; depth
@ -235,7 +230,7 @@ pixel_format8 db 0 ; setPixelformat
.blue_shift db 4 ; blue-shift .blue_shift db 4 ; blue-shift
db 0, 0, 0 ; padding db 0, 0, 0 ; padding
encodings db 2 ; setEncodings SetEncodings db 2 ; setEncodings
db 0 ; padding db 0 ; padding
db 0, 2 ; number of encodings db 0, 2 ; number of encodings
db 0, 0, 0, 0 ; raw encoding (DWORD, Big endian order) db 0, 0, 0, 0 ; raw encoding (DWORD, Big endian order)
@ -245,19 +240,19 @@ encodings db 2 ; setEncodings
; db 0, 0, 0, 15 ; TRLE ; db 0, 0, 0, 15 ; TRLE
; db 0, 0, 0, 16 ; ZRLE ; db 0, 0, 0, 16 ; ZRLE
fbur db 3 ; frame buffer update request FramebufferUpdateRequest db 3
.inc db 0 ; incremental .inc db 0 ; incremental
.x dw 0 .x dw 0
.y dw 0 .y dw 0
.width dw 0 .width dw 0
.height dw 0 .height dw 0
keyevent db 4 ; keyevent KeyEvent db 4 ; keyevent
.down db 0 ; down-flag .down db 0 ; down-flag
dw 0 ; padding dw 0 ; padding
.key dd 0 ; key .key dd 0 ; key
pointerevent db 5 ; pointerevent PointerEvent db 5 ; pointerevent
.mask db 0 ; button-mask .mask db 0 ; button-mask
.x dw 0 ; x-position .x dw 0 ; x-position
.y dw 0 ; y-position .y dw 0 ; y-position
@ -269,11 +264,39 @@ sockaddr1:
.ip dd 0 .ip dd 0
rb 10 rb 10
thread_ready db 0 beep db 0x85, 0x25, 0x85, 0x40, 0
mouse_dd dd ?
status dd STATUS_INITIAL
update_gui dd 0
mouse_dd dd 0
URLbox edit_box 200, 25, 16, 0xffffff, 0x6f9480, 0, 0, 0, 65535, serveraddr, mouse_dd, ed_focus, 0, 0 URLbox edit_box 200, 25, 16, 0xffffff, 0x6f9480, 0, 0, 0, 65535, serveraddr, mouse_dd, ed_focus, 0, 0
serverstr db "server:"
userstr db "username:"
passstr db "password:"
connectstr db "connect"
loginstr db "login"
loginstr_e:
sz_err_disconnected db "Server closed connection unexpectedly.", 0
sz_err_dns db "Could not resolve hostname.", 0
sz_err_sock db "Could not open socket.", 0
sz_err_connect db "Could not connect to the server.", 0
sz_err_proto db "A protocol error has occured.", 0
sz_err_security db "Server requested an unsupported security type.", 0
sz_err_library db "Could not load needed libraries.", 0
sz_err_thread db "Could not create thread.", 0
err_msg dd sz_err_disconnected
dd sz_err_dns
dd sz_err_sock
dd sz_err_connect
dd sz_err_proto
dd sz_err_security
dd sz_err_library
dd sz_err_thread
; import ; import
align 4 align 4
@IMPORT: @IMPORT:
@ -299,8 +322,8 @@ import box_lib,\
import archiver,\ import archiver,\
deflate_unpack, "deflate_unpack" deflate_unpack, "deflate_unpack"
name db "VNC client " name db "VNC viewer "
name.dash db 0, " " .dash db 0, " "
I_END: I_END:
@ -308,27 +331,34 @@ servername rb 64+1
socketnum dd ? socketnum dd ?
datapointer dd ? datapointer dd ?
rectangles dw ? rectangles dw ?
rectangle: rectangle:
.width dw ? .x dd ?
.height dw ? .y dd ?
.x dw ? .width dd ?
.y dw ? .height dd ?
subrectangles dd ?
subrectangle:
.x dd ?
.y dd ?
.width dd ?
.height dd ?
screen: ; Remote screen resolution screen: ; Remote screen resolution
.height dw ? .height dw ?
.width dw ? .width dw ?
serveraddr rb 65536 serveraddr rb 65536
receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc) receive_buffer rb RECEIVE_BUFFER_SIZE
framebuffer_data rb 1024*1024*3 ; framebuffer framebuffer_data rb 1024*1024*3 ; framebuffer
rb 0x1000 rb 0x1000
thread_stack: thread_stack:
rb 0x1000 rb 0x1000
IM_END: IM_END: