From 872ac43496b1461deee7b918077345796492ef32 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Tue, 4 Aug 2015 16:29:37 +0000 Subject: [PATCH] VNC viewer: better keyboard support, selectable pixelformat at compile time (8bpp/16bpp/24bpp), bugfixes. git-svn-id: svn://kolibrios.org@5677 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/network/vncc/keymap.inc | 121 ++++++++++++++++++++++++++++++ programs/network/vncc/network.inc | 74 +++++++++++++----- programs/network/vncc/raw.inc | 57 +++++++++----- programs/network/vncc/rre.inc | 37 +++++++-- programs/network/vncc/vncc.asm | 74 +++++++++++++----- 5 files changed, 299 insertions(+), 64 deletions(-) create mode 100644 programs/network/vncc/keymap.inc diff --git a/programs/network/vncc/keymap.inc b/programs/network/vncc/keymap.inc new file mode 100644 index 0000000000..6372923d3f --- /dev/null +++ b/programs/network/vncc/keymap.inc @@ -0,0 +1,121 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +generate_keymap: + +; Read keymaps from kernel + mcall 26, 2, 1, keymap+128 + mcall 26, 2, 2, keymap_shift+128 + mcall 26, 2, 3, keymap_alt+128 + + mov esi, keymap+128 + mov edi, keymap + mov ecx, 128 + call convert_keymap + + mov esi, keymap_shift+128 + mov edi, keymap_shift + mov ecx, 128 + call convert_keymap + + mov esi, keymap_alt+128 + mov edi, keymap_alt + mov ecx, 128 + call convert_keymap + + ret + + + +convert_keymap: + .loop: + lodsb + + cmp al, 0x08 ; Backspace + jne @f + mov ax, 0x08ff + jmp .next + @@: + cmp al, 0x09 ; Tab + jne @f + mov ax, 0x09ff + jmp .next + @@: + cmp al, 0x0d ; Enter + jne @f + mov ax, 0x0dff + jmp .next + @@: + cmp al, 0x1b ; Escape + jne @f + mov ax, 0x1bff + jmp .next + @@: + cmp al, 0x34 ; Insert + jne @f + mov ax, 0x63ff + jmp .next + @@: + cmp al, 0xb6 ; Delete + jne @f + mov ax, 0xffff + jmp .next + @@: + cmp al, 0xb4 ; Home + jne @f + mov ax, 0x50ff + jmp .next + @@: + cmp al, 0xb5 ; End + jne @f + mov ax, 0x57ff + jmp .next + @@: + cmp al, 0xb8 ; PgUp + jne @f + mov ax, 0x55ff + jmp .next + @@: + cmp al, 0xb7 ; PgDown + jne @f + mov ax, 0x56ff + jmp .next + @@: + cmp al, 0xb0 ; Left + jne @f + mov ax, 0x51ff + jmp .next + @@: + cmp al, 0xb2 ; Up + jne @f + mov ax, 0x52ff + jmp .next + @@: + cmp al, 0xb3 ; Right + jne @f + mov ax, 0x53ff + jmp .next + @@: + cmp al, 0xb1 ; Down + jne @f + mov ax, 0x54ff + jmp .next + @@: + + shl ax, 8 + .next: + stosw + dec ecx + jnz .loop + ret \ No newline at end of file diff --git a/programs/network/vncc/network.inc b/programs/network/vncc/network.inc index 64ae0c96b3..c9978931f0 100644 --- a/programs/network/vncc/network.inc +++ b/programs/network/vncc/network.inc @@ -83,11 +83,17 @@ no_security: mov dword[screen], eax DEBUGF 1, "Screen width=%u, height=%u\n", [screen.width]:2, [screen.height]:2 - mcall send, [socketnum], SetPixelFormat8, 20, 0 DEBUGF 1, "Sending pixel format\n" +if BITS_PER_PIXEL = 8 + mcall send, [socketnum], SetPixelFormat8, 20, 0 +else if BITS_PER_PIXEL = 16 + mcall send, [socketnum], SetPixelFormat16, 20, 0 +else + mcall send, [socketnum], SetPixelFormat24, 20, 0 +end if - mcall send, [socketnum], SetEncodings, 12, 0 DEBUGF 1, "Sending encoding info\n" + mcall send, [socketnum], SetEncodings, 12, 0 ; Set main window caption to servername mov ecx, dword[receive_buffer+framebuffer.name_length] @@ -126,7 +132,6 @@ thread_loop: cmp al, 3 je servercuttext - DEBUGF 2, "Unknown server command: %u\n", al jmp thread_loop @@ -201,8 +206,35 @@ setcolourmapentries: DEBUGF 1, "Server sent SetColourMapEntries message\n" - ; TODO + @@: + lea eax, [esi+5] + cmp [datapointer], eax + jae @f + call read_data.more + jmp @b + @@: + inc esi ; padding + + xor eax, eax + lodsw ; first color (just ignore for now) + + lodsw ; number of colors (use to find end of message) + xchg al, ah + lea eax, [eax*2+eax] + shl eax, 1 + @@: + push eax + add eax, esi + cmp [datapointer], eax + jae @f + call read_data.more + pop eax + jmp @b + @@: + pop eax + + add esi, eax ; Just skip it for now. jmp thread_loop @@ -248,36 +280,40 @@ read_data: mov esi, receive_buffer .more: push ebx ecx edx esi edi - mcall recv, [socketnum], [datapointer], 4096, 0 + neg esi + add esi, receive_buffer + RECEIVE_BUFFER_SIZE + jz .buffer_end_reached + xor edi, edi + mcall recv, [socketnum], [datapointer] pop edi esi edx ecx ebx cmp eax, -1 - je err_disconnected + je err_sock + test eax, eax + jz err_disconnected add [datapointer], eax -; Check for buffer overflow - cmp [datapointer], receive_buffer + RECEIVE_BUFFER_SIZE - jbe @f + ret + + .buffer_end_reached: ; Buffer is full, first needed data by program is pointed to by esi. - ; Move all remaining data, starting from esi, to begin of buffer + ; Move all usefull data 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 + mov [datapointer], edi ; new end of data + mov esi, receive_buffer ; new start of data + jmp .more + wait_for_data: ; FIXME: add timeout - mcall recv, [socketnum], receive_buffer, 4096, 0 + mcall recv, [socketnum], receive_buffer, 4096, 0 ; MSG_DONTWAIT cmp eax, -1 - je err_disconnected + je err_sock test eax, eax - jz wait_for_data + jz err_disconnected ret diff --git a/programs/network/vncc/raw.inc b/programs/network/vncc/raw.inc index 2c22be009a..990a85d513 100644 --- a/programs/network/vncc/raw.inc +++ b/programs/network/vncc/raw.inc @@ -19,15 +19,21 @@ encoding_raw: mov eax, [rectangle.width] mov ebx, [rectangle.height] mul ebx - add eax, esi +if BITS_PER_PIXEL = 16 + shl eax, 1 +else if BITS_PER_PIXEL = 24 + lea eax, [eax*2+eax] +end if @@: + push eax + add eax, esi cmp [datapointer], eax jae @f - push eax call read_data.more pop eax jmp @b @@: + pop eax mov eax, [rectangle.y] movzx ebx, [screen.width] @@ -40,39 +46,56 @@ encoding_raw: sub eax, [rectangle.width] lea ebp, [eax*3] ; ebp = ([screen.width]-[rectangle.width])*3 - mov bl, 85 - mov edx, [rectangle.height] .lineloop: mov ecx, [rectangle.width] +if BITS_PER_PIXEL = 24 + lea ecx, [ecx*2+ecx] +end if +if BITS_PER_PIXEL = 8 .pixelloop: + mov bl, 85 mov al, [esi] - shr al, 4 + shr al, 6 and al, 3 mul bl - stosb - + stosb ; blue + mov bl, 36 mov al, [esi] - shr al, 2 - and al, 3 + shr al, 3 + and al, 7 mul bl - stosb - + stosb ; green mov al, [esi] - and al, 3 + and al, 7 mul bl - stosb - + stosb ; red inc esi dec ecx jnz .pixelloop +else if BITS_PER_PIXEL = 16 + .pixelloop: + lodsw + mov bx, ax + shl al, 3 + and al, 0xf8 + stosb ; blue + mov ax, bx + shr ax, 3 + and al, 0xfc + stosb ; green + mov al, bh + and al, 0xf8 + stosb ; red + dec ecx + jnz .pixelloop +else if BITS_PER_PIXEL = 24 + rep movsb +end if add edi, ebp dec edx jnz .lineloop jmp next_rectangle - - - diff --git a/programs/network/vncc/rre.inc b/programs/network/vncc/rre.inc index 20437fb609..072d3c84e9 100644 --- a/programs/network/vncc/rre.inc +++ b/programs/network/vncc/rre.inc @@ -13,29 +13,50 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pixel_to_24bpp: ; returns in ecx, destroys eax, ebx +if BITS_PER_PIXEL = 8 ; Convert pixel to 24BPP mov bl, 85 mov al, [esi] - shr al, 4 + shr al, 6 and al, 3 mul bl - mov cl, al + mov ch, al ; blue + mov bl, 36 mov al, [esi] - shr al, 2 - and al, 3 + shr al, 3 + and al, 7 mul bl - mov ch, al + mov cl, al ; green mov al, [esi] - and al, 3 + and al, 7 mul bl - shl ecx, 8 + shr ecx, 8 + mov cl, al ; red + inc esi +else if BITS_PER_PIXEL = 16 + lodsw mov cl, al + shl cl, 3 + and cx, 0x00f8 ; blue + shl ecx, 16 + mov cx, ax + shl cx, 5 + and ch, 0xfc ; green + mov cl, ah + and al, 0xf8 ; red +else + xor ecx, ecx + mov cx, [esi] + shr ecx, 8 + mov cl, [esi+2] + add esi, 3 +end if ret encoding_RRE: - DEBUGF 1,"RRE\n" + DEBUGF 2,"RRE\n" @@: lea eax, [esi+5] diff --git a/programs/network/vncc/vncc.asm b/programs/network/vncc/vncc.asm index 746fbff526..2f091802ca 100644 --- a/programs/network/vncc/vncc.asm +++ b/programs/network/vncc/vncc.asm @@ -17,6 +17,8 @@ format binary as "" __DEBUG__ = 1 __DEBUG_LEVEL__ = 2 +BITS_PER_PIXEL = 8 ; 8, 16 24 + use32 org 0x0 @@ -81,6 +83,7 @@ STATUS_SECURITY_ERR = 15 STATUS_LIB_ERR = 16 STATUS_THREAD_ERR = 17 +include "keymap.inc" include "gui.inc" include "network.inc" include "raw.inc" @@ -114,7 +117,8 @@ START: mcall 40, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_KEY + EVM_REDRAW + EVM_BUTTON mcall 66, 1, 1 ; Switch keyboard to scancode mode - mcall 26, 2, 1, keymap ; Read keymap + + call generate_keymap redraw: mcall 12, 1 @@ -151,6 +155,9 @@ mainloop: jmp mainloop key: + mcall 66, 3 + mov ebx, eax + mcall 2 cmp ah, 224 ; ext je mainloop ;; TODO @@ -162,18 +169,28 @@ key: @@: mov byte[KeyEvent.down], al - shr eax, 8 - and al, 0x7f - mov al, [keymap+eax] - mov byte[KeyEvent.key+3], al - - DEBUGF 1, "Sending key: 0x%x\n", al + shr eax, 7 + and eax, 0x000000fe + test ebx, 100000b ; alt? + jz @f + add eax, 512 + jmp .key + @@: + test ebx, 11b ; shift? + jz @f + add eax, 256 + @@: + .key: + mov ax, [keymap+eax] + mov word[KeyEvent.key+2], ax + DEBUGF 1, "Sending key: 0x%x\n", ax mcall send, [socketnum], KeyEvent, 8, 0 jmp mainloop + mouse: -; DEBUGF 1, "Sending mouse event\n" +; DEBUGF 1, "Sending pointer event\n" mcall 37, 1 ; get mouse pos bswap eax @@ -193,6 +210,7 @@ mouse: button: mcall 17 ; get id + mcall close, [socketnum] mcall -1 @@ -218,32 +236,46 @@ SetPixelFormat32 db 0 ; setPixelformat .blue_shift db 16 ; blue-shift db 0, 0, 0 ; padding +SetPixelFormat24 db 0 ; setPixelformat + db 0, 0, 0 ; padding +.bpp db 24 ; bits per pixel +.depth db 24 ; 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_shift db 16 ; red-shift +.green_shift db 8 ; green-shift +.blue_shift db 0 ; 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 +.depth db 16 ; 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 +.green_max db 0, 63 ; green-max .blue_max db 0, 31 ; blue-max -.red_shif db 0 ; red-shift +.red_shift db 11 ; red-shift .green_shift db 5 ; green-shift -.blue_shift db 10 ; blue-shift +.blue_shift db 0 ; blue-shift db 0, 0, 0 ; padding SetPixelFormat8 db 0 ; setPixelformat db 0, 0, 0 ; padding .bpp db 8 ; bits per pixel -.depth db 6 ; depth +.depth db 8 ; 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 +.red_max db 0, 7 ; red-max +.green_max db 0, 7 ; 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 +.red_shift db 0 ; red-shift +.green_shift db 3 ; green-shift +.blue_shift db 6 ; blue-shift db 0, 0, 0 ; padding SetEncodings db 2 ; setEncodings @@ -371,12 +403,14 @@ screen: ; Remote screen resolution .height dw ? .width dw ? -keymap rb 128 +keymap rw 128 +keymap_shift rw 128 +keymap_alt rw 128 username rb 128 password rb 128 serveraddr rb 65536 receive_buffer rb RECEIVE_BUFFER_SIZE -framebuffer_data rb 1024*1024*3 ; framebuffer +framebuffer_data rb 1280*1024*3 ; framebuffer rb 0x1000 thread_stack: