From 35f6e3767bc8f5f500acf5933ae369744613da62 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Fri, 14 Aug 2015 13:30:03 +0000 Subject: [PATCH] VNC Viewer: support for 32bpp, bugfixes. git-svn-id: svn://kolibrios.org@5722 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/network/vncc/copyrect.inc | 4 +- programs/network/vncc/gui.inc | 2 + programs/network/vncc/network.inc | 82 ++++++++++++++++-------------- programs/network/vncc/raw.inc | 11 +++- programs/network/vncc/rre.inc | 36 +++++++------ programs/network/vncc/trle.inc | 76 ++++++++++++++++++++++++--- programs/network/vncc/vncc.asm | 20 ++++---- programs/network/vncc/zrle.inc | 73 ++++++++++++++++++++++++-- 8 files changed, 227 insertions(+), 77 deletions(-) diff --git a/programs/network/vncc/copyrect.inc b/programs/network/vncc/copyrect.inc index e911fe9c75..71e228f76c 100644 --- a/programs/network/vncc/copyrect.inc +++ b/programs/network/vncc/copyrect.inc @@ -33,13 +33,13 @@ encoding_CopyRect: movzx ebx, word[esi] ; [src.x] xchg bl, bh 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+eax*3] ; esi = framebuffer_data+([screen.width]*[src.y]+[src.x])*3 mov eax, [rectangle.y] movzx ebx, [screen.width] mul ebx ; [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 + lea edi, [framebuffer+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3 movzx eax, [screen.width] sub eax, [rectangle.width] diff --git a/programs/network/vncc/gui.inc b/programs/network/vncc/gui.inc index 9f358b1f17..63905277b3 100644 --- a/programs/network/vncc/gui.inc +++ b/programs/network/vncc/gui.inc @@ -234,6 +234,8 @@ draw_gui: mcall 18, 18, [thread_id] ; kill thread .ok: and [URLbox.flags], not ed_disabled + mov [USERbox.size], 0 + mov [PASSbox.size], 0 mov [status], STATUS_CONNECT inc [update_gui] jmp .loop diff --git a/programs/network/vncc/network.inc b/programs/network/vncc/network.inc index 04b7323224..1f72ea3ad3 100644 --- a/programs/network/vncc/network.inc +++ b/programs/network/vncc/network.inc @@ -71,8 +71,10 @@ thread_start: je err_connect ; Verify handshake from server - call wait_for_data - cmp dword[receive_buffer], "RFB " + call read_data + cmp eax, 12 + jb err_proto + cmp dword[esi], "RFB " jne err_proto add esi, 12 @@ -89,7 +91,9 @@ thread_start: mcall send, [socketnum], HandShake, 12, 0 ; VNC 3.3 protocol: server decides security type - call wait_for_data + call read_data + cmp eax, 4 + jb err_proto lodsd cmp eax, 0x00000000 je err_handshake @@ -101,6 +105,10 @@ thread_start: vnc_security: + lea eax, [esi+8] + cmp [datapointer], eax + jb err_proto + push esi ; pointer to message mov dword[password], 0 @@ -196,53 +204,62 @@ vnc_security: securityresult: ; Wait for SecurityResult from server - call wait_for_data - cmp dword[receive_buffer], 0 ; OK + call read_data + cmp eax, 4 + jb err_proto + cmp dword[esi], 0 ; OK jne err_login initialize: DEBUGF 1, "Sending ClientInit\n" mcall send, [socketnum], ClientInit, 1, 0 - call wait_for_data ; now the server should send init message + call read_data ; now the server should send init message + cmp eax, ServerInit.name + jb err_proto - DEBUGF 1, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \ - [receive_buffer+framebuffer.pixelformat.bpp]:1, \ - [receive_buffer+framebuffer.pixelformat.depth]:1, \ - [receive_buffer+framebuffer.pixelformat.big_endian]:1, \ - [receive_buffer+framebuffer.pixelformat.true_color]:1 + DEBUGF 2, "Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n", \ + [esi+ServerInit.pixelformat.bpp]:1, \ + [esi+ServerInit.pixelformat.depth]:1, \ + [esi+ServerInit.pixelformat.big_endian]:1, \ + [esi+ServerInit.pixelformat.true_color]:1 - mov eax, dword[receive_buffer+framebuffer.width] + mov eax, dword[esi+ServerInit.width] 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 +; Set main window caption to servername + mov ecx, dword[esi+ServerInit.name_length] + bswap ecx + add esi, ServerInit.name + lea eax, [esi+ecx] + cmp [datapointer], eax + jb err_proto + cmp ecx, 64 ; Limit name length to 64 chars + jbe @f + mov ecx, 64 + @@: + mov edi, servername + rep movsb + mov byte[edi], 0 + mov [name.dash], "-" + 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 +else if BITS_PER_PIXEL = 24 mcall send, [socketnum], SetPixelFormat24, 20, 0 +else + mcall send, [socketnum], SetPixelFormat32, 20, 0 end if DEBUGF 1, "Sending encoding info\n" mcall send, [socketnum], SetEncodings, SetEncodings.length, 0 -; 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 @@ -443,17 +460,6 @@ read_data: jmp .more - -wait_for_data: ; FIXME: add timeout - mcall recv, [socketnum], receive_buffer, 4096, 0 ; MSG_DONTWAIT - cmp eax, -1 - je err_sock - test eax, eax - jz err_disconnected - mov esi, receive_buffer - ret - - err_disconnected: mov [status], STATUS_DISCONNECTED inc [update_gui] @@ -465,6 +471,8 @@ err_dns: mcall -1 err_sock: +; TODO: distinguish between different socket errors! + DEBUGF 2, "Socket error: %u\n", ebx mov [status], STATUS_SOCK_ERR inc [update_gui] mcall -1 diff --git a/programs/network/vncc/raw.inc b/programs/network/vncc/raw.inc index 6c3839e3ac..b84635c5c1 100644 --- a/programs/network/vncc/raw.inc +++ b/programs/network/vncc/raw.inc @@ -23,6 +23,8 @@ if BITS_PER_PIXEL = 16 shl eax, 1 else if BITS_PER_PIXEL = 24 lea eax, [eax*2+eax] +else if BITS_PER_PIXEL = 32 + shl eax, 2 end if @@: push eax @@ -39,7 +41,7 @@ end if movzx ebx, [screen.width] mul ebx ; [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 + lea edi, [framebuffer+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3 movzx eax, [screen.width] sub eax, [rectangle.width] @@ -92,6 +94,13 @@ else if BITS_PER_PIXEL = 16 jnz .pixelloop else if BITS_PER_PIXEL = 24 rep movsb +else if BITS_PER_PIXEL = 32 + .pixelloop: + movsw + movsb + inc esi + dec ecx + jnz .pixelloop end if add edi, ebp diff --git a/programs/network/vncc/rre.inc b/programs/network/vncc/rre.inc index fb10d18fd2..7120d55f86 100644 --- a/programs/network/vncc/rre.inc +++ b/programs/network/vncc/rre.inc @@ -12,16 +12,16 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -pixel_to_24bpp: ; returns in ecx +load_pixel_rre: ; returns in ecx push eax -; @@: -; lea eax, [esi+BYTES_PER_PIXEL] -; cmp [datapointer], eax -; jae @f -; call read_data.more -; jmp @b -; @@: + @@: + lea eax, [esi+BYTES_PER_PIXEL] + cmp [datapointer], eax + jae @f + call read_data.more + jmp @b + @@: if BITS_PER_PIXEL = 8 @@ -65,14 +65,18 @@ else if BITS_PER_PIXEL = 16 shl cl, 3 and cx, 0x00f8 ; blue -else +else if BITS_PER_PIXEL = 24 - xor ecx, ecx - mov cx, [esi] - shl ecx, 8 - mov cl, [esi+2] + mov ecx, [esi] + and ecx, 0x00ffffff add esi, 3 +else if BITS_PER_PIXEL = 32 + + mov ecx, [esi] + and ecx, 0x00ffffff + add esi, 4 + end if pop eax @@ -97,13 +101,13 @@ encoding_RRE: DEBUGF 1, "%u subrectangles\n", eax ; Get background color - call pixel_to_24bpp + call load_pixel_rre ; Calculate first pixel pos 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 + lea edi, [framebuffer+eax*3] ; edi = framebuffer_data+([screen.width]*[rectangle.y]+[rectangle.x])*3 ; Calculate offset between two rows of pixels movzx eax, [screen.width] @@ -142,7 +146,7 @@ encoding_RRE: @@: ; Get subrectangle color - call pixel_to_24bpp + call load_pixel_rre ; Get coordinates xor eax, eax diff --git a/programs/network/vncc/trle.inc b/programs/network/vncc/trle.inc index e2cee6d40d..5ed1c61f4a 100644 --- a/programs/network/vncc/trle.inc +++ b/programs/network/vncc/trle.inc @@ -20,7 +20,7 @@ create_palette: DEBUGF 1, "Loading palette of %u colors\n", dl mov edi, palette .loop: - call pixel_to_24bpp + call load_pixel_trle mov [edi], ecx add edi, 4 dec dl @@ -30,6 +30,71 @@ create_palette: ret +load_pixel_trle: ; returns in ecx + + push eax + @@: + lea eax, [esi+BYTES_PER_PIXEL] + cmp [datapointer], eax + jae @f + call read_data.more + jmp @b + @@: + +if BITS_PER_PIXEL = 8 + + push ebx + + mov bl, 36 + mov al, [esi] + and al, 7 + mul bl + mov ch, al ; red + + mov al, [esi] + shr al, 3 + and al, 7 + mul bl + mov cl, al ; green + + mov bl, 85 + mov al, [esi] + shr al, 6 + and al, 3 + mul bl + shl ecx, 8 + mov cl, al ; blue + + inc esi + pop ebx + +else if BITS_PER_PIXEL = 16 + + lodsw + mov cl, ah + and al, 0xf8 ; red + + mov cx, ax + shl cx, 5 + and ch, 0xfc ; green + shl ecx, 8 + + mov cl, al + shl cl, 3 + and cx, 0x00f8 ; blue + +else ; 32 BPP gets packed to 24 BPP + + mov ecx, [esi] + and ecx, 0x00ffffff + add esi, 3 + +end if + pop eax + + ret + + encoding_TRLE: DEBUGF 1, "TRLE\n" @@ -62,7 +127,7 @@ encoding_TRLE: mul ebx add eax, [rectangle.x] add eax, [subrectangle.x] - lea edi, [framebuffer_data+eax*3] + lea edi, [framebuffer+eax*3] ; Calculate offset between two rows of pixels movzx eax, [screen.width] @@ -197,8 +262,7 @@ encoding_TRLE: jmp .next_tile .rle_reload: - ; load pixel value - call pixel_to_24bpp + call load_pixel_trle @@: lea eax, [esi+1] @@ -447,7 +511,7 @@ encoding_TRLE: .raw_line: mov ebx, [subrectangle.width] .raw_pixel: - call pixel_to_24bpp + call load_pixel_trle mov word[edi], cx shr ecx, 16 add edi, 2 @@ -465,7 +529,7 @@ encoding_TRLE: ; Single color tile .solid: DEBUGF 1, "Solid tile\n" - call pixel_to_24bpp + call load_pixel_trle mov eax, ecx shr eax, 16 diff --git a/programs/network/vncc/vncc.asm b/programs/network/vncc/vncc.asm index 25f2c633f6..46adc9acad 100644 --- a/programs/network/vncc/vncc.asm +++ b/programs/network/vncc/vncc.asm @@ -17,7 +17,7 @@ format binary as "" __DEBUG__ = 1 __DEBUG_LEVEL__ = 2 -BITS_PER_PIXEL = 8 ; 8, 16 24 +BITS_PER_PIXEL = 32 ; 8, 16, 24 or 32 SERVERADDRLEN = 4096 use32 @@ -40,7 +40,7 @@ include "../../struct.inc" include "../../develop/libraries/box_lib/trunk/box_lib.mac" include "../../network.inc" -struct pixel_format +struct PixelFormat bpp db ? depth db ? big_endian db ? @@ -54,12 +54,12 @@ struct pixel_format padding rb 3 ends -struct framebuffer +struct ServerInit width dw ? height dw ? - pixelformat pixel_format + pixelformat PixelFormat name_length dd ? - name rb 256 + name db ? ends xpos = 4 @@ -156,7 +156,7 @@ redraw: draw_framebuffer: DEBUGF 1, "Drawing framebuffer\n" - mcall 7, framebuffer_data, dword[screen], 0 + mcall 7, framebuffer, dword[screen], 0 mov [update_framebuffer], 0 mainloop: @@ -275,15 +275,15 @@ ClientInit db 0 ; not shared SetPixelFormat32 db 0 ; setPixelformat db 0, 0, 0 ; padding .bpp db 32 ; bits per pixel -.depth db 32 ; depth +.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_shif db 0 ; red-shift +.red_shift db 16 ; red-shift .green_shift db 8 ; green-shift -.blue_shift db 16 ; blue-shift +.blue_shift db 0 ; blue-shift db 0, 0, 0 ; padding SetPixelFormat24 db 0 ; setPixelformat @@ -479,7 +479,7 @@ keys rd 32*2 ; DES keys for VNC authentication sz_err_security_c rb 512+1 receive_buffer rb RECEIVE_BUFFER_SIZE -framebuffer_data rb 1280*1024*3 ; framebuffer +framebuffer rb 1280*1024*3 ; framebuffer rb 0x1000 thread_stack: diff --git a/programs/network/vncc/zrle.inc b/programs/network/vncc/zrle.inc index ce49f5d208..07264a8286 100644 --- a/programs/network/vncc/zrle.inc +++ b/programs/network/vncc/zrle.inc @@ -12,6 +12,68 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +load_pixel_zrle: ; returns in ecx + + push eax + +; TODO: check for buffer underrun! + +if BITS_PER_PIXEL = 8 + + push ebx + + mov bl, 36 + mov al, [esi] + and al, 7 + mul bl + mov ch, al ; red + + mov al, [esi] + shr al, 3 + and al, 7 + mul bl + mov cl, al ; green + + mov bl, 85 + mov al, [esi] + shr al, 6 + and al, 3 + mul bl + shl ecx, 8 + mov cl, al ; blue + + inc esi + pop ebx + +else if BITS_PER_PIXEL = 16 + + lodsw + mov cl, ah + and al, 0xf8 ; red + + mov cx, ax + shl cx, 5 + and ch, 0xfc ; green + shl ecx, 8 + + mov cl, al + shl cl, 3 + and cx, 0x00f8 ; blue + +else ; 32 BPP gets packed to 24 BPP + + mov ecx, [esi] + and ecx, 0x00ffffff + add esi, 3 + +end if + pop eax + + ret + + + deflate_callback: mov eax, [deflate_length] mov ecx, [esp+8] @@ -19,6 +81,8 @@ deflate_callback: mov eax, [deflate_buffer] ret 8 + + encoding_ZRLE: DEBUGF 2, "ZRLE\n" @@ -102,7 +166,7 @@ encoding_ZRLE: mul ebx add eax, [rectangle.x] add eax, [subrectangle.x] - lea edi, [framebuffer_data+eax*3] + lea edi, [framebuffer+eax*3] ; Calculate offset between two rows of pixels movzx eax, [screen.width] @@ -219,8 +283,7 @@ encoding_ZRLE: jmp .next_tile .rle_reload: - ; load pixel value - call pixel_to_24bpp + call load_pixel_zrle ;;; @@ -454,7 +517,7 @@ encoding_ZRLE: .raw_line: mov ebx, [subrectangle.width] .raw_pixel: - call pixel_to_24bpp + call load_pixel_zrle mov word[edi], cx shr ecx, 16 add edi, 2 @@ -472,7 +535,7 @@ encoding_ZRLE: ; Single color tile .solid: DEBUGF 1, "Solid tile\n" - call pixel_to_24bpp + call load_pixel_zrle mov eax, ecx shr eax, 16