From ffa9fb98581312993c9307cadee30c1b611dc0d0 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Mon, 3 Aug 2015 18:07:56 +0000 Subject: [PATCH] VNC client: bugfixes, better GUI, error reporting. git-svn-id: svn://kolibrios.org@5668 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/network/vncc/copyrect.inc | 14 +- programs/network/vncc/gui.inc | 163 +++++++++ programs/network/vncc/logon.inc | 135 ------- .../network/vncc/{thread.inc => network.inc} | 154 +++++--- programs/network/vncc/raw.inc | 14 +- programs/network/vncc/rre.inc | 130 +++++++ programs/network/vncc/vncc.asm | 334 ++++++++++-------- 7 files changed, 588 insertions(+), 356 deletions(-) create mode 100644 programs/network/vncc/gui.inc delete mode 100644 programs/network/vncc/logon.inc rename programs/network/vncc/{thread.inc => network.inc} (64%) create mode 100644 programs/network/vncc/rre.inc diff --git a/programs/network/vncc/copyrect.inc b/programs/network/vncc/copyrect.inc index 0bb13c66a3..5f39e3eced 100644 --- a/programs/network/vncc/copyrect.inc +++ b/programs/network/vncc/copyrect.inc @@ -12,7 +12,7 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -encoding_copyrect: +encoding_CopyRect: DEBUGF 1,"CopyRect\n" @@ -35,22 +35,22 @@ encoding_copyrect: 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 - movzx eax, [rectangle.y] + mov eax, [rectangle.y] movzx ebx, [screen.width] mul ebx ; [screen.width]*[rectangle.y] - movzx ebx, [rectangle.x] + mov ebx, [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 movzx eax, [screen.width] - sub ax, [rectangle.width] + sub eax, [rectangle.width] lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3 cmp esi, edi ja .copy ; source pixels come before destination in buffer, copy backwards - movzx eax, [rectangle.height] + mov eax, [rectangle.height] movzx edx, [screen.width] mul edx lea eax, [eax*3-1] @@ -61,8 +61,8 @@ encoding_copyrect: std .copy: - movzx edx, [rectangle.height] - movzx ecx, [rectangle.width] + mov edx, [rectangle.height] + mov ecx, [rectangle.width] lea ecx, [ecx*3] .lineloop: push ecx diff --git a/programs/network/vncc/gui.inc b/programs/network/vncc/gui.inc new file mode 100644 index 0000000000..c7db265bb8 --- /dev/null +++ b/programs/network/vncc/gui.inc @@ -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 \ No newline at end of file diff --git a/programs/network/vncc/logon.inc b/programs/network/vncc/logon.inc deleted file mode 100644 index 68268871f8..0000000000 --- a/programs/network/vncc/logon.inc +++ /dev/null @@ -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: diff --git a/programs/network/vncc/thread.inc b/programs/network/vncc/network.inc similarity index 64% rename from programs/network/vncc/thread.inc rename to programs/network/vncc/network.inc index 1251e4312f..4a30fe57f7 100644 --- a/programs/network/vncc/thread.inc +++ b/programs/network/vncc/network.inc @@ -14,17 +14,15 @@ thread_start: - DEBUGF 1, "I am the thread!\n" - - mcall 40, 0 ; disable all events + mcall 40, 0 ; disable all events for this thread ; resolve name - push esp ; reserve stack place + push esp ; reserve stack place invoke getaddrinfo, serveraddr, 0, 0, esp pop esi ; test for error test eax, eax - jnz exit + jnz err_dns mov eax, [esi+addrinfo.ai_addr] mov eax, [eax+sockaddr_in.sin_addr] @@ -35,40 +33,37 @@ thread_start: [sockaddr1.ip+2]:1, [sockaddr1.ip+3]:1, \ [sockaddr1.port]:2 + invoke freeaddrinfo, esi + mcall socket, AF_INET4, SOCK_STREAM, 0 - test eax, eax - jz exit -;;; invoke freeaddrinfo, ?? + cmp eax, -1 + je err_sock + mov [socketnum], eax mcall connect, [socketnum], sockaddr1, 18 -;;; test eax, eax + cmp eax, -1 + je err_connect ; TODO: implement timeout call wait_for_data cmp dword[receive_buffer], "RFB " - jne no_rfb + jne err_proto 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" call wait_for_data - cmp dword[receive_buffer], 0x00000000 - je invalid_security - cmp dword[receive_buffer], 0x01000000 je no_security - cmp dword[receive_buffer], 0x02000000 je vnc_security - - DEBUGF 1, "Unknown security type\n" - jmp exit + jmp err_security vnc_security: - mov byte[mode], 1 - call logon + mov [status], STATUS_LOGIN + call draw_gui no_security: mcall send, [socketnum], ClientInit, 1, 0 @@ -83,26 +78,40 @@ no_security: [receive_buffer+framebuffer.pixelformat.true_color]:1 mov eax, dword[receive_buffer+framebuffer.width] - mov dword[fbur.width], eax + mov dword[FramebufferUpdateRequest.width], eax bswap eax mov dword[screen], eax 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" - mcall send, [socketnum], encodings, 12, 0 + mcall send, [socketnum], SetEncodings, 12, 0 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 - mov [fbur.inc], 0 + mov [FramebufferUpdateRequest.inc], 0 request_fbu: DEBUGF 1, "Requesting framebuffer update\n" - mcall send, [socketnum], fbur, 10, 0 - mov [fbur.inc], 1 + mcall send, [socketnum], FramebufferUpdateRequest, 10, 0 + mov [FramebufferUpdateRequest.inc], 1 thread_loop: call read_data ; Read the data into the buffer @@ -147,17 +156,19 @@ rectangle_loop: jmp @b @@: - lodsd ; position - bswap eax - mov [rectangle.y], ax - shr eax, 16 - mov [rectangle.x], ax - - lodsd ; size - bswap eax - mov [rectangle.height], ax - shr eax, 16 - mov [rectangle.width], ax + xor eax, eax + lodsw + xchg al, ah + mov [rectangle.x], eax + lodsw + xchg al, ah + mov [rectangle.y], eax + lodsw + xchg al, ah + mov [rectangle.width], eax + lodsw + xchg al, ah + mov [rectangle.height], eax lodsd ; encoding DEBUGF 1, "rectangle: width=%u height=%u x=%u y=%u encoding: ",\ @@ -166,9 +177,9 @@ rectangle_loop: cmp eax, 0 je encoding_raw cmp eax, 1 - je encoding_copyrect -; cmp eax, 2 -; je encoding_RRE + je encoding_CopyRect + cmp eax, 2 + je encoding_RRE ; cmp eax, 5 ; je encoding_hextile ; cmp eax, 15 @@ -179,8 +190,6 @@ rectangle_loop: DEBUGF 1, "\nunknown encoding: %u\n", eax jmp thread_loop -;; jmp rectangle_loop - next_rectangle: push esi call drawbuffer @@ -245,30 +254,65 @@ read_data: mcall recv, [socketnum], [datapointer], 4096, 0 pop edi esi edx ecx ebx cmp eax, -1 - je .error - add [datapointer], eax ; TODO: check for buffer overflow + je err_disconnected + 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 je .more ret - .error: - DEBUGF 1, "Socket error!\n" - mcall -1 - ret - - wait_for_data: ; FIXME: add timeout mcall recv, [socketnum], receive_buffer, 4096, 0 cmp eax, -1 - je .error + je err_disconnected test eax, eax jz wait_for_data - 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 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 diff --git a/programs/network/vncc/raw.inc b/programs/network/vncc/raw.inc index 5d3b11f983..2c22be009a 100644 --- a/programs/network/vncc/raw.inc +++ b/programs/network/vncc/raw.inc @@ -16,8 +16,8 @@ encoding_raw: DEBUGF 1,"RAW\n" - movzx eax, [rectangle.width] - movzx ebx, [rectangle.height] + mov eax, [rectangle.width] + mov ebx, [rectangle.height] mul ebx add eax, esi @@: @@ -29,23 +29,23 @@ encoding_raw: jmp @b @@: - movzx eax, [rectangle.y] + mov eax, [rectangle.y] movzx ebx, [screen.width] mul ebx ; [screen.width]*[rectangle.y] - movzx ebx, [rectangle.x] + mov ebx, [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 movzx eax, [screen.width] - sub ax, [rectangle.width] + sub eax, [rectangle.width] lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3 mov bl, 85 - movzx edx, [rectangle.height] + mov edx, [rectangle.height] .lineloop: - movzx ecx, [rectangle.width] + mov ecx, [rectangle.width] .pixelloop: mov al, [esi] diff --git a/programs/network/vncc/rre.inc b/programs/network/vncc/rre.inc new file mode 100644 index 0000000000..20437fb609 --- /dev/null +++ b/programs/network/vncc/rre.inc @@ -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 \ No newline at end of file diff --git a/programs/network/vncc/vncc.asm b/programs/network/vncc/vncc.asm index 58761c996f..86c386caf9 100644 --- a/programs/network/vncc/vncc.asm +++ b/programs/network/vncc/vncc.asm @@ -3,7 +3,7 @@ ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; -;; vncc.asm - VNC client for KolibriOS ;; +;; VNC client for KolibriOS ;; ;; ;; ;; Written by hidnplayr@kolibrios.org ;; ;; ;; @@ -17,11 +17,6 @@ format binary as "" __DEBUG__ = 1 __DEBUG_LEVEL__ = 1 -xpos = 4 ; coordinates of image -ypos = 22 ; - -TIMEOUT = 5 ; timeout in seconds - use32 org 0x0 @@ -32,8 +27,7 @@ use32 dd I_END ; size of image dd IM_END ; memory for app dd IM_END ; esp - dd 0x0 , 0x0 ; I_Param , I_Path - + dd 0x0, 0x0 ; I_Param , I_Path include "../../macros.inc" include "../../debug-fdo.inc" @@ -65,34 +59,49 @@ struct framebuffer name rb 256 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 "copyrect.inc" -include "thread.inc" +include "rre.inc" START: mcall 68, 11 ; init heap -; load libraries +; Load libraries stdcall dll.Load, @IMPORT test eax, eax - jnz exit + jz @f + mov [status], STATUS_LIB_ERR + @@: - call logon +; Present the user with the GUI and wait for network connection + call draw_gui - 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 +; Create main window + mcall 71, 1, name ; reset window caption (add server name) mov edx, dword[screen] movzx esi, dx @@ -101,8 +110,27 @@ START: add esi, ypos+xpos mcall 67, 10, 10 ; resize the window + mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_KEY + EVM_REDRAW + EVM_BUTTON + +redraw: + mcall 12, 1 + + mov ebx, dword[screen] + movzx ecx, bx + shr ebx, 16 + mov edx, 0x74ffffff + mov edi, name + mcall 0 ; draw window + + call drawbuffer + + mcall 12, 2 + mainloop: - mcall 10 ; wait for event + cmp [status], STATUS_CONNECTED + jne draw_gui + + mcall 23, 100 ; Check for event with 1s timeout dec eax jz redraw @@ -114,166 +142,161 @@ mainloop: jz mouse jmp mainloop -key: +drawbuffer: + mcall 7, framebuffer_data, dword[screen], 0 + ret -; DEBUGF 1,"Sending key event\n" +key: +; DEBUGF 1, "Sending key event\n" mcall 2 - mov byte[keyevent.key+3], ah + mov byte[KeyEvent.key+3], ah - mcall send, [socketnum], keyevent, 8, 0 + mcall send, [socketnum], KeyEvent, 8, 0 jmp mainloop mouse: - -; DEBUGF 1,"Sending mouse event\n" +; DEBUGF 1, "Sending mouse event\n" mcall 37, 1 ; get mouse pos sub eax, xpos shl 16 + ypos bswap eax - mov [pointerevent.x], ax + mov [PointerEvent.x], ax shr eax, 16 - mov [pointerevent.y], ax + 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 + mov [PointerEvent.mask], al - mcall send, [socketnum], pointerevent, 6, 0 + mcall send, [socketnum], PointerEvent, 6, 0 jmp mainloop -redraw: - -; DEBUGF 1,"Drawing window\n" - - mcall 12, 1 - - mov ebx, dword[screen] - movzx ecx, bx - shr ebx, 16 - mov edx, 0x74ffffff - mov edi, name - mcall 0 ; draw window - - call drawbuffer - - mcall 12, 2 - - jmp mainloop - -drawbuffer: - mcall 7, framebuffer_data, dword[screen], 0 - ret - button: mcall 17 ; get id - -exit: - DEBUGF 1, "Closing time!\n" - mcall close, [socketnum] 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 -include_debug_strings ; ALWAYS present in data section +include_debug_strings -handshake db "RFB 003.003", 10 -ClientInit db 0 ; not shared -beep db 0x85, 0x25, 0x85, 0x40, 0 +HandShake db "RFB 003.003", 10 -pixel_format32 db 0 ; setPixelformat - db 0, 0, 0 ; padding -.bpp db 32 ; bits per pixel -.depth db 32 ; depth -.big_endian db 0 ; big-endian flag -.true_color db 1 ; true-colour flag -.red_max db 0, 255 ; red-max -.green_max db 0, 255 ; green-max -.blue_max db 0, 255 ; blue-max -.red_shif db 0 ; red-shift -.green_shift db 8 ; green-shift -.blue_shift db 16 ; blue-shift - db 0, 0, 0 ; padding +ClientInit db 0 ; not shared -pixel_format16 db 0 ; setPixelformat - db 0, 0, 0 ; padding -.bpp db 16 ; bits per pixel -.depth db 15 ; depth -.big_endian db 0 ; big-endian flag -.true_color db 1 ; true-colour flag -.red_max db 0, 31 ; red-max -.green_max db 0, 31 ; green-max -.blue_max db 0, 31 ; blue-max -.red_shif db 0 ; red-shift -.green_shift db 5 ; green-shift -.blue_shift db 10 ; blue-shift - db 0, 0, 0 ; padding +SetPixelFormat32 db 0 ; setPixelformat + db 0, 0, 0 ; padding +.bpp db 32 ; bits per pixel +.depth db 32 ; depth +.big_endian db 0 ; big-endian flag +.true_color db 1 ; true-colour flag +.red_max db 0, 255 ; red-max +.green_max db 0, 255 ; green-max +.blue_max db 0, 255 ; blue-max +.red_shif db 0 ; red-shift +.green_shift db 8 ; green-shift +.blue_shift db 16 ; blue-shift + db 0, 0, 0 ; padding -pixel_format8 db 0 ; setPixelformat - db 0, 0, 0 ; padding -.bpp db 8 ; bits per pixel -.depth db 6 ; depth -.big_endian db 0 ; big-endian flag -.true_color db 1 ; true-colour flag -.red_max db 0, 3 ; red-max -.green_max db 0, 3 ; green-max -.blue_max db 0, 3 ; blue-max -.red_shif db 0 ; red-shift -.green_shift db 2 ; green-shift -.blue_shift db 4 ; blue-shift - db 0, 0, 0 ; padding +SetPixelFormat16 db 0 ; setPixelformat + db 0, 0, 0 ; padding +.bpp db 16 ; bits per pixel +.depth db 15 ; depth +.big_endian db 0 ; big-endian flag +.true_color db 1 ; true-colour flag +.red_max db 0, 31 ; red-max +.green_max db 0, 31 ; green-max +.blue_max db 0, 31 ; blue-max +.red_shif db 0 ; red-shift +.green_shift db 5 ; green-shift +.blue_shift db 10 ; blue-shift + db 0, 0, 0 ; padding -encodings db 2 ; setEncodings - db 0 ; padding - db 0, 2 ; number of encodings - db 0, 0, 0, 0 ; raw encoding (DWORD, Big endian order) - db 0, 0, 0, 1 ; Copyrect encoding -; db 0, 0, 0, 2 ; RRE -; db 0, 0, 0, 5 ; HexTile -; db 0, 0, 0, 15 ; TRLE -; db 0, 0, 0, 16 ; ZRLE +SetPixelFormat8 db 0 ; setPixelformat + db 0, 0, 0 ; padding +.bpp db 8 ; bits per pixel +.depth db 6 ; depth +.big_endian db 0 ; big-endian flag +.true_color db 1 ; true-colour flag +.red_max db 0, 3 ; red-max +.green_max db 0, 3 ; green-max +.blue_max db 0, 3 ; blue-max +.red_shif db 0 ; red-shift +.green_shift db 2 ; green-shift +.blue_shift db 4 ; blue-shift + db 0, 0, 0 ; padding -fbur db 3 ; frame buffer update request -.inc db 0 ; incremental -.x dw 0 -.y dw 0 -.width dw 0 -.height dw 0 +SetEncodings db 2 ; setEncodings + db 0 ; padding + db 0, 2 ; number of encodings + db 0, 0, 0, 0 ; raw encoding (DWORD, Big endian order) + db 0, 0, 0, 1 ; Copyrect encoding +; db 0, 0, 0, 2 ; RRE +; db 0, 0, 0, 5 ; HexTile +; db 0, 0, 0, 15 ; TRLE +; db 0, 0, 0, 16 ; ZRLE -keyevent db 4 ; keyevent -.down db 0 ; down-flag - dw 0 ; padding -.key dd 0 ; key +FramebufferUpdateRequest db 3 +.inc db 0 ; incremental +.x dw 0 +.y dw 0 +.width dw 0 +.height dw 0 -pointerevent db 5 ; pointerevent -.mask db 0 ; button-mask -.x dw 0 ; x-position -.y dw 0 ; y-position +KeyEvent db 4 ; keyevent +.down db 0 ; down-flag + dw 0 ; padding +.key dd 0 ; key + +PointerEvent db 5 ; pointerevent +.mask db 0 ; button-mask +.x dw 0 ; x-position +.y dw 0 ; y-position sockaddr1: - dw AF_INET4 -.port dw 0x0c17 ; 5900 -.ip dd 0 - rb 10 + dw AF_INET4 +.port dw 0x0c17 ; 5900 +.ip dd 0 + rb 10 -thread_ready db 0 -mouse_dd dd ? +beep db 0x85, 0x25, 0x85, 0x40, 0 + +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 +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 align 4 @IMPORT: @@ -299,8 +322,8 @@ import box_lib,\ import archiver,\ deflate_unpack, "deflate_unpack" -name db "VNC client " -name.dash db 0, " " +name db "VNC viewer " +.dash db 0, " " I_END: @@ -308,27 +331,34 @@ servername rb 64+1 socketnum dd ? datapointer dd ? + rectangles dw ? rectangle: -.width dw ? -.height dw ? -.x dw ? -.y dw ? +.x dd ? +.y dd ? +.width dd ? +.height dd ? + +subrectangles dd ? + +subrectangle: +.x dd ? +.y dd ? +.width dd ? +.height dd ? screen: ; Remote screen resolution .height dw ? .width dw ? 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 rb 0x1000 thread_stack: - rb 0x1000 - IM_END: