Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 260 → Rev 264

/programs/network/VNCclient/vnc.asm
File deleted
/programs/network/VNCclient/VNCclient.asm
0,0 → 1,336
;
;
; VNC Client for kolibrios by hidnplayr
;
;
; WORK IN PROGRESS...
;
; FEEL FREE TO CONTRIBUTE !
;
; hidnplayr@gmail.com
;
 
use32
 
org 0x0
 
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd IM_END ; memory for app
dd IM_END ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
 
__DEBUG__ equ 1
__DEBUG_LEVEL__ equ 1
 
STRLEN = 64 ; password and server max length
xpos = 4 ; coordinates of image
ypos = 22 ;
 
TIMEOUT = 60 ; timeout in seconds
BUFFER = 1500 ; Buffer size for DNS
 
include 'fdo.inc'
include 'ETH.INC'
include 'logon.inc'
include 'raw.inc'
include 'copyrect.inc'
include 'thread.inc'
 
 
START: ; start of execution
 
call red_logon
 
mov eax,40 ; Report events
mov ebx,00000000b ; Only Stack
int 0x40
 
mov eax,67 ; resize the window (hide it)
xor ebx,ebx
mov ecx,ebx
mov edx,ebx
mov esi,ebx
int 0x40
 
mov eax,51
mov ebx,1
mov ecx,thread_start
mov edx,thread_stack
int 0x40
 
DEBUGF 1,'Thread created: %u\n',eax
 
@@:
mov eax,5
mov ebx,10
int 0x40
 
cmp byte[thread_ready],0
je @r
 
mov eax,40 ; report events
mov ebx,100111b ; mouse, button, key, redraw
int 0x40
 
mov eax,67 ; resize the window
mov ebx,10
mov ecx,10
mov edx,dword[framebuffer]
bswap edx
movzx esi,dx
shr edx,16
add edx,2*xpos
add esi,ypos+xpos
int 0x40
 
mainloop:
eth.socket_status [socket],eax
cmp al,TCB_CLOSE_WAIT
je close
 
mov eax,23 ; wait for event with timeout
mov ebx,50 ; 0,5 s
int 0x40
 
cmp eax,1
je redraw
cmp eax,2 ; key
je key
cmp eax,3 ; button
je button
cmp eax,6 ; mouse
je mouse
 
call drawbuffer
 
jmp mainloop
 
key:
DEBUGF 1,'Sending key event\n'
 
mov eax,2
int 0x40
mov byte[keyevent.key+3],ah
 
eth.write_tcp [socket],8,keyevent
 
jmp mainloop
 
mouse:
DEBUGF 1,'Sending mouse event\n'
 
mov eax,37
mov ebx,1
int 0x40
 
sub eax,xpos*65536+ypos
bswap eax
mov word[pointerevent.x],ax
shr eax,16
mov word[pointerevent.y],ax
 
mov eax,37
mov ebx,2
int 0x40
 
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 byte[pointerevent.mask],al
 
eth.write_tcp [socket],6,pointerevent
 
jmp mainloop
 
redraw:
 
DEBUGF 1,'Drawing window\n'
 
mov eax,12
mov ebx,1
int 0x40
 
mov eax,0 ; draw window
mov ebx,dword[framebuffer]
bswap ebx
movzx ecx,bx
shr ebx,16
add ebx,2*xpos
add ecx,ypos+xpos
mov edx,0x03ffffff
mov esi,0x80555599
mov edi,0x00ffffff
int 0x40
 
mov eax,4 ; label
mov ebx,9*65536+8
mov ecx,0x10ffffff
mov edx,name
mov esi,[name_length]
bswap esi
int 0x40
 
call drawbuffer
 
mov eax,12
mov ebx,2
int 0x40
 
jmp mainloop
 
drawbuffer:
 
mov eax,7
mov ebx,framebuffer_data
mov ecx,dword[screen]
mov edx,xpos*65536+ypos
int 0x40
 
ret
 
 
button: ; button
mov eax,17 ; get id
int 0x40
 
close:
call read_data
; eth.close_tcp [socket] ; We're done, close the socket ;;; BUG WHEN CLOSING SOCKET !!
DEBUGF 1,'Socket closed\n'
 
mov eax,-1
int 0x40
 
no_rfb:
DEBUGF 1,'This is no vnc server!\n'
jmp close
 
invalid_security:
DEBUGF 1,'Security error: %s\n',receive_buffer+5
jmp close
 
 
; DATA AREA
 
include_debug_strings ; ALWAYS present in data section
 
handshake db 'RFB 003.003',0x0a
shared db 0
beep db 0x85,0x25,0x85,0x40,0
 
pixel_format32 db 0 ; setPixelformat
rb 3 ; 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
rb 3 ; padding
 
pixel_format16 db 0 ; setPixelformat
rb 3 ; 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
rb 3 ; padding
 
pixel_format8 db 0 ; setPixelformat
rb 3 ; 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
rb 3 ; padding
 
encodings db 2 ; setEncodings
rb 1 ; padding
db 1,0 ; number of encodings
db 0,0,0,0 ; raw encoding (DWORD, Big endian order)
db 1,0,0,0 ; Copyrect encoding
 
fbur db 3 ; frame buffer update request
.inc db 0 ; incremental
.x dw 0
.y dw 0
.width dw 0
.height dw 0
 
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
 
I_END:
 
framebuffer:
.width dw ?
.height dw ?
pixelformat:
.bpp db ?
.depth db ?
.big_endian db ?
.true_color db ?
.red_max dw ?
.green_max dw ?
.blue_max dw ?
.red_shift db ?
.green_shift db ?
.blue_shift db ?
.padding rb 3
name_length dd ?
name rb 256
 
server_ip dd 0
server_port dd 0
socket dd 0
datapointer dd 0
 
frame:
.width dw 0
.height dw 0
.x dw 0
.y dw 0
 
screen:
.height dw 0
.width dw 0
 
thread_ready db 0
 
dnsMsg:
receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc)
framebuffer_data rb 1024*768*3 ; framebuffer
 
thread_stack rb 0x1000
 
IM_END:
 
 
/programs/network/VNCclient/raw.inc
1,40 → 1,33
encoding_raw:
DEBUGF 1,'FRAME: RAW\n'
DEBUGF 1,'RAW\n'
 
mov ax,[screen.width] ;
mov bx,[frame.y] ;
mov ax,[frame.y] ;
mov bx,[screen.width] ;
mul bx ;
DEBUGF 1,'screen.width*frame.y=%u\n',ax
mov bx,3 ;
mul bx ;
shl edx,16 ;
mov dx,ax ;
mov ebx,edx ; mov ebx,[screen.width]*[frame.y]*3
push ebx
DEBUGF 1,'screen.width*frame.y*3=%u\n',edx
mov ax,[frame.x] ;
mov bx,3 ;
mul bx ;
shl edx,16 ;
mov dx,ax ;
pop ebx
add ebx,edx ; add ebx,[frame.x]*3
add ebx,framebuffer_data ; add ebx,framebuffer_data
push ebx
DEBUGF 1,'frame.x*3=%u\n',edx
mov dx,ax ; [screen.width]*[frame.y]
movzx eax,[frame.x]
add edx,eax ; [screen.width]*[frame.y]+[frame.x]
 
mov eax,3 ;
mul edx ; ([screen.width]*[frame.y]+[frame.x])*3
 
add eax,framebuffer_data ;
push eax ; framebuffer_data+([screen.width]*[frame.y]+[frame.x])*3
 
mov ax,[frame.width] ;
mov bx,3 ;
mul bx ;
shl edx,16 ;
mov dx,ax ;
DEBUGF 1,'frame.width*3=%u\n',edx
pop ebx
add edx,ebx ; mov edx,ebx+[frame.width]*3
mov dx,ax ; [frame.width]*3
 
push ebx
pop eax ;
add edx,eax ; framebuffer_data+([screen.width]*[frame.y]+[frame.x])*3+[frame.width]*3
push eax ;
push edx ;
 
mov ax,[frame.height] ;
dec ax ;
mov bx,3 ;
mul bx ;
mov bx,[screen.width] ;
43,72 → 36,87
mov dx,ax ;
mov ecx,edx ;
pop edx ;
DEBUGF 1,'frame.height*screen.width*3=%u\n',ecx
add ecx,edx ; mov ecx,edx+[frame.height]*[screen.width]*3
add ecx,edx ; mov ecx,edx+([frame.height]-1)*[screen.width]*3
pop ebx
 
DEBUGF 1,'FRAME: framebuffer:%u ebx:%u ecx:%u edx:%u\n',framebuffer_data,ebx,ecx,edx
 
.pixelloop32:
cmp ebx,ecx
jge next_rectangle
 
add esi,2 ; 32 bit code RAW
; add esi,2 ; 32 bit code RAW - OK
; mov al,[esi] ;
; mov [ebx],al ;
; inc ebx ;
; dec esi ;
; ;
; mov al,[esi] ;
; mov [ebx],al ;
; inc ebx ;
; dec esi ;
; ;
; mov al,[esi] ;
; mov [ebx],al ;
; inc ebx ;
; add esi,4 ;
 
; push ecx ; 16 bit code RAW
; mov cl,51
;
; mov ax,[esi] ;
; xchg al,ah
; and al,00011111b ;
; xchg al,ah
; mul cl
; mov [ebx],al ;
; inc ebx ;
;
; mov ax,[esi] ;
; xchg al,ah
; shr ax,5 ;
; xchg al,ah
; and al,00011111b ;
; mul cl
; mov [ebx],al ;
; inc ebx ;
;
; mov ax,[esi] ;
; xchg al,ah
; shr ax,10 ;
; and al,00011111b ;
; mul cl
; mov [ebx],al ;
; inc ebx ;
;
; inc esi ;
; inc esi ;
; pop ecx
 
push ecx ; 8 bit code RAW - OK
mov cl,85 ;
;
mov al,[esi] ;
shr al,4 ;
and al,3 ;
mul cl ;
mov [ebx],al ;
inc ebx ;
dec esi ;
;
mov al,[esi] ;
shr al,2 ;
and al,3 ;
mul cl ;
mov [ebx],al ;
inc ebx ;
dec esi ;
;
mov al,[esi] ;
mov [ebx],al ;
and al,3 ;
mul cl ;
mov byte[ebx],al ;
inc ebx ;
add esi,4 ;
inc esi ;
pop ecx ;
 
; mov ax,[esi] ; 16 bit code RAW
; and ax,32
; mov [ebx],al
; inc ebx
;
; mov ax,[esi]
; shr ax,5
; and ax,32
; mov [ebx],al
; inc ebx
;
; mov ax,[esi]
; shr ax,10
; and ax,64
; mov [ebx],al
; inc ebx
; inc esi
; inc esi
 
 
; mov al,[esi] ; 8 bit code RAW
; and al,7 ;
; mov byte[ebx],0xff;al ;
; inc ebx ;
; ;
; mov al,[esi] ;
; shr al,3 ;
; and al,7 ;
; mov [ebx],al ;
; inc ebx ;
; ;
; mov al,[esi] ;
; shr al,6 ;
; and al,3 ;
; mov [ebx],al ;
; inc ebx ;
; ;
; inc esi ;
 
 
cmp ebx,edx
jl .pixelloop32
 
/programs/network/VNCclient/thread.inc
0,0 → 1,188
thread_start:
DEBUGF 1,'I am the thread!\n'
 
mov eax,40 ; Report events
mov ebx,10000000b ; Only Stack
int 0x40
 
resolve first,[server_ip] ; the input window putted the server @ 'first', resolve it into a real ip
mov [server_port],5900 ; no port input for now, only standard port 5900
 
DEBUGF 1,'connecting to %u.%u.%u.%u:%u\n',1[server_ip],1[server_ip+1],1[server_ip+2],1[server_ip+3],4[server_port]
eth.search_port 1000,edx ; Find a free port starting from 1001 and store in edx
eth.open_tcp edx,[server_port],[server_ip],1,[socket] ; open socket
DEBUGF 1,'Socket opened: %u (port %u)\n',[socket],ecx
 
call read_data
cmp dword[receive_buffer+1],'RFB '
jne no_rfb
eth.write_tcp [socket],12,handshake
DEBUGF 1,'Sending handshake: protocol version\n'
 
call read_data
mov eax,receive_buffer+1
mov eax,[eax]
bswap eax
cmp eax,0
je invalid_security
cmp eax,1
je no_security
cmp eax,2
je vnc_security
 
jmp close
 
vnc_security:
mov byte[mode],1
call red_logon
 
no_security:
eth.write_tcp [socket],1,shared
DEBUGF 1,'Sending handshake: shared session?\n'
 
eth.wait_for_data [socket],TIMEOUT*10,close
eth.read_data [socket],framebuffer,[datapointer],IM_END-receive_buffer ; now the server should send init message
DEBUGF 1,'Serverinit: bpp:%u depth:%u bigendian:%u truecolor:%u\n',1[pixelformat.bpp],1[pixelformat.depth],1[pixelformat.big_endian],1[pixelformat.true_color]
mov eax,dword[framebuffer]
bswap eax
mov dword[screen],eax
 
eth.write_tcp [socket],20,pixel_format8
DEBUGF 1,'Sending pixel format\n'
call read_data
 
; eth.write_tcp [socket],8,encodings
; DEBUGF 1,'Sending encoding info\n'
; call read_data
 
mov eax,dword[framebuffer.width]
mov dword[fbur.width],eax
 
mov byte[thread_ready],1
 
request_rfb:
mov byte[fbur.inc],2 ;;;;;;;;
eth.write_tcp [socket],10,fbur ;;;;;;;;;
 
thread_loop:
eth.wait_for_data [socket],1000,thread_loop
 
call read_data ; Read the data into the buffer
 
mov eax,[datapointer] ; at least 2 bytes should be received
sub eax,receive_buffer
cmp eax,1
jle mainloop
 
DEBUGF 1,'Data received, %u bytes\n',eax
 
cmp byte[receive_buffer],0
je framebufferupdate
 
cmp byte[receive_buffer],1
je setcolourmapentries
 
cmp byte[receive_buffer],2
je bell
 
cmp byte[receive_buffer],3
je servercuttext
 
jmp thread_loop
 
 
framebufferupdate:
mov ax,word[receive_buffer+2]
xchg al,ah
mov di,ax
DEBUGF 1,'Framebufferupdate: %u frames\n',di
mov esi,receive_buffer+4
jmp rectangle_loop
 
next_rectangle:
call drawbuffer
 
dec di
test di,di
jz request_rfb
 
rectangle_loop:
mov edx,[esi]
bswap edx
mov ebx,edx
shr edx,16
mov [frame.x],dx
mov [frame.y],bx
add esi,4
mov ecx,[esi]
bswap ecx
mov eax,ecx
shr ecx,16
mov [frame.width],cx
mov [frame.height],ax
add esi,4
mov eax,[esi]
add esi,4
 
mov ebx,esi
sub ebx,receive_buffer+12
DEBUGF 1,'frame: width=%u height=%u x=%u y=%u offset:%u encoding:',2[frame.width],2[frame.height],2[frame.x],2[frame.y],ebx
 
cmp eax,0
je encoding_raw
cmp eax,1
je encoding_copyrect
cmp eax,2
je encoding_RRE
cmp eax,5
je encoding_hextile
cmp eax,16
je encoding_ZRLE
 
mov ebx,esi
sub ebx,receive_buffer+8
DEBUGF 1,'\nunknown encoding: %u (offset %u)\n',eax,ebx
jmp bell
jmp thread_loop
 
encoding_RRE:
DEBUGF 1,'RRE\n'
 
jmp next_rectangle
 
encoding_hextile:
DEBUGF 1,'hextile\n'
 
jmp next_rectangle
 
encoding_ZRLE:
DEBUGF 1,'ZRLE\n'
 
jmp next_rectangle
 
 
setcolourmapentries:
DEBUGF 1,'Server sended SetColourMapEntries message\n'
 
jmp thread_loop
 
 
bell:
mov eax,55
mov ebx,eax
mov esi,beep
int 0x40
 
jmp thread_loop
 
 
servercuttext:
DEBUGF 1,'Server cut text\n'
 
jmp thread_loop
 
 
 
read_data:
eth.read_data [socket],receive_buffer,[datapointer],IM_END-receive_buffer
ret