cf59000c24
git-svn-id: svn://kolibrios.org@4380 a494cfbc-eb01-0410-851d-a64ba20cac60
440 lines
11 KiB
NASM
440 lines
11 KiB
NASM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2010-2013. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;; Synergyc.asm - Synergy client for KolibriOS ;;
|
|
;; ;;
|
|
;; Written by hidnplayr@kolibrios.org ;;
|
|
;; ;;
|
|
;; GNU GENERAL PUBLIC LICENSE ;;
|
|
;; Version 2, June 1991 ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
format binary as ""
|
|
|
|
BUFFERSIZE = 1024
|
|
DEFAULTPORT = 24800
|
|
|
|
use32
|
|
org 0x0
|
|
|
|
db 'MENUET01' ; signature
|
|
dd 1 ; header version
|
|
dd start ; entry point
|
|
dd i_end ; initialized size
|
|
dd mem+0x1000 ; required memory
|
|
dd mem+0x1000 ; stack pointer
|
|
dd 0 ; parameters
|
|
dd path ; path
|
|
|
|
include '../../macros.inc'
|
|
purge mov,add,sub
|
|
include '../../proc32.inc'
|
|
include '../../dll.inc'
|
|
|
|
include '../../network.inc'
|
|
|
|
start:
|
|
|
|
mov edi, path ; Calculate the length of zero-terminated string
|
|
xor al, al
|
|
mov ecx, 1024
|
|
repne scasb
|
|
dec edi
|
|
mov esi, filename ; append the path with '.ini'
|
|
movsd
|
|
movsb
|
|
|
|
mcall 68, 11
|
|
mcall 66, 1, 1
|
|
|
|
stdcall dll.Load, @IMPORT
|
|
test eax, eax
|
|
jnz exit
|
|
|
|
push 1
|
|
call [con_start]
|
|
|
|
push title
|
|
push 25
|
|
push 80
|
|
push 25
|
|
push 80
|
|
call [con_init]
|
|
|
|
push str0
|
|
call [con_write_asciiz]
|
|
|
|
restart:
|
|
|
|
invoke ini.get_str, path, str_remote, str_ip, buffer_ptr, 16, 0
|
|
test eax, eax
|
|
jnz error
|
|
|
|
invoke ini.get_int, path, str_remote, str_port, DEFAULTPORT
|
|
xchg al, ah
|
|
mov [sockaddr1.port], ax
|
|
|
|
push str1
|
|
call [con_write_asciiz]
|
|
|
|
push buffer_ptr
|
|
call [con_write_asciiz]
|
|
|
|
push newline
|
|
call [con_write_asciiz]
|
|
|
|
mcall socket, AF_INET4, SOCK_STREAM, 0
|
|
cmp eax, -1
|
|
je error
|
|
mov [socketnum], eax
|
|
|
|
; resolve name
|
|
push esp ; reserve stack place
|
|
push esp ; ptr to result
|
|
push 0 ; addrinfo hints
|
|
push 0 ; servname
|
|
push buffer_ptr ; hostname
|
|
call [getaddrinfo]
|
|
pop esi
|
|
; test for error
|
|
test eax, eax
|
|
jnz error
|
|
|
|
mov eax, [esi+addrinfo.ai_addr]
|
|
mov eax, [eax+sockaddr_in.sin_addr]
|
|
mov [sockaddr1.ip], eax
|
|
|
|
mcall connect, [socketnum], sockaddr1, 18
|
|
test eax, eax
|
|
jnz error
|
|
|
|
push str7
|
|
call [con_write_asciiz]
|
|
|
|
mcall 40, EVM_STACK
|
|
|
|
login:
|
|
call wait_for_data
|
|
|
|
push buffer_ptr + 4
|
|
call [con_write_asciiz]
|
|
|
|
cmp dword [buffer_ptr], 11 shl 24 ; length of string
|
|
jne error
|
|
cmp dword [buffer_ptr + 4], 'Syne'
|
|
jne error
|
|
cmp word [buffer_ptr + 8], 'rg'
|
|
jne error
|
|
cmp byte [buffer_ptr + 10], 'y'
|
|
jne error
|
|
|
|
push str2
|
|
call [con_write_asciiz]
|
|
|
|
lea edi, [buffer_ptr + 11 + 4 + 4]
|
|
invoke ini.get_str, path, str_local, str_name, edi, 255, 0
|
|
xor al , al
|
|
mov ecx, 256
|
|
repne scasb
|
|
sub edi, buffer_ptr + 1 + 4
|
|
mov esi, edi
|
|
bswap edi
|
|
mov dword [buffer_ptr], edi
|
|
mov edi, esi
|
|
sub edi, 11 + 4
|
|
bswap edi
|
|
mov dword [buffer_ptr + 11 + 4], edi
|
|
add esi, 4
|
|
|
|
mcall send, [socketnum], buffer_ptr, , 0
|
|
|
|
mainloop:
|
|
call wait_for_data
|
|
mov edi, buffer_ptr
|
|
|
|
.command:
|
|
push eax edi
|
|
|
|
cmp dword [edi + 4], 'QINF' ; query screen info
|
|
je .qinf
|
|
|
|
cmp dword [edi + 4], 'CALV' ; alive ?
|
|
je .calv
|
|
|
|
cmp dword [edi + 4], 'CINN' ; mouse moved into screen
|
|
je .cinn
|
|
|
|
cmp dword [edi + 4], 'DCLP' ; Clipboard event
|
|
je .dclp
|
|
|
|
cmp dword [edi + 4], 'DMMV' ; Mouse moved
|
|
je .dmmv
|
|
|
|
cmp dword [edi + 4], 'COUT' ; leave screen
|
|
je .cout
|
|
|
|
cmp dword [edi + 4], 'DMDN' ; mouse button down
|
|
je .dmdn
|
|
|
|
cmp dword [edi + 4], 'DMUP' ; mouse button released
|
|
je .dmup
|
|
|
|
cmp dword [edi + 4], 'CNOP' ; no operation
|
|
je .next
|
|
|
|
cmp dword [edi + 4], 'CIAK' ; resolution changed?
|
|
je .ciak
|
|
|
|
; cmp dword [edi + 4], 'DMWM' ; mouse wheel moved
|
|
; je .dmwm
|
|
|
|
cmp dword [edi + 4], 'DKDN' ; Key pressed
|
|
je .dkdn
|
|
|
|
cmp dword [edi + 4], 'DKUP' ; key up
|
|
je .dkup
|
|
|
|
cmp dword [edi + 4], 'DKRP' ; key auto repeat
|
|
je .dkrp
|
|
|
|
push str3
|
|
call [con_write_asciiz]
|
|
|
|
mov byte[edi+8],0
|
|
add edi, 4
|
|
push edi
|
|
call [con_write_asciiz]
|
|
|
|
push newline
|
|
call [con_write_asciiz]
|
|
|
|
.next:
|
|
pop edi eax
|
|
|
|
mov ecx, dword [edi]
|
|
bswap ecx
|
|
add ecx, 4
|
|
sub eax, ecx
|
|
jle mainloop
|
|
add edi, ecx
|
|
jmp .command
|
|
|
|
|
|
.qinf:
|
|
mcall 14 ; get screen info
|
|
add eax, 0x00010001
|
|
bswap eax
|
|
mov dword [screeninfo.size], eax
|
|
mcall send, [socketnum], screeninfo, screeninfo.length, 0 ; send client name
|
|
jmp .next
|
|
|
|
|
|
.calv:
|
|
mcall send, [socketnum], calv, calv.length, 0 ; keepalive
|
|
|
|
jmp .next
|
|
|
|
|
|
.cinn:
|
|
mov edx, [edi + 8]
|
|
bswap edx
|
|
mcall 18, 19, 4
|
|
; ignore sequence number and modify key mask for now
|
|
push str6
|
|
call [con_write_asciiz]
|
|
jmp .next
|
|
|
|
.dclp:
|
|
|
|
jmp .next
|
|
|
|
.dmmv:
|
|
mov edx, [edi + 8]
|
|
bswap edx
|
|
mcall 18, 19, 4
|
|
mcall send, [socketnum], cnop, cnop.length, 0 ; reply with NOP
|
|
jmp .next
|
|
|
|
.cout:
|
|
; TODO: hide cursor
|
|
push str8
|
|
call [con_write_asciiz]
|
|
jmp .next
|
|
|
|
.dmdn:
|
|
movzx eax, byte[edi + 8]
|
|
cmp eax, 5
|
|
ja .next
|
|
movzx eax, [mousecodes + eax]
|
|
or [mousestate], eax
|
|
mcall 18, 19, 5, [mousestate]
|
|
mcall send, [socketnum], cnop, cnop.length, 0 ; reply with NOP
|
|
jmp .next
|
|
|
|
.dmup:
|
|
movzx eax, byte[edi + 8]
|
|
cmp eax, 5
|
|
ja .next
|
|
movzx eax, [mousecodes + eax]
|
|
not eax
|
|
and [mousestate], eax
|
|
mcall 18, 19, 5, [mousestate]
|
|
mcall send, [socketnum], cnop, cnop.length, 0 ; reply with NOP
|
|
jmp .next
|
|
|
|
.ciak:
|
|
jmp .next
|
|
|
|
; .dmwm:
|
|
; jmp .next
|
|
|
|
.dkdn:
|
|
movzx edx, word[edi + 8 + 4] ; key button
|
|
rol dx, 8
|
|
mcall 72, 1, 2 ; send key
|
|
jmp .next
|
|
|
|
.dkrp:
|
|
movzx edx, word[edi + 8 + 6]
|
|
rol dx, 8
|
|
mcall 72, 1, 2 ; send key
|
|
jmp .next
|
|
|
|
.dkup:
|
|
movzx edx, word[edi + 8 + 4]
|
|
rol dx, 8
|
|
add edx, 128
|
|
mcall 72, 1, 2 ; send key
|
|
|
|
jmp .next
|
|
|
|
error:
|
|
push str_err
|
|
call [con_write_asciiz]
|
|
|
|
wait_for_key:
|
|
call [con_getch2]
|
|
|
|
mcall close, [socketnum]
|
|
|
|
push 1
|
|
call [con_exit]
|
|
exit:
|
|
|
|
mcall -1
|
|
|
|
|
|
wait_for_data:
|
|
mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
|
|
inc eax
|
|
jz error
|
|
dec eax
|
|
jz closed
|
|
|
|
cmp eax, 8
|
|
jb wait_for_data ; FIXME
|
|
|
|
ret
|
|
|
|
closed:
|
|
|
|
push str_cls
|
|
call [con_write_asciiz]
|
|
|
|
mcall close, [socketnum]
|
|
|
|
mcall 5, 200
|
|
|
|
jmp restart
|
|
|
|
|
|
|
|
; data
|
|
title db 'Synergy client',0
|
|
str0 db 'Welcome to the software KM switch for KolibriOS.',10,10,0
|
|
str1 db 'Connecting to: ',0
|
|
str7 db 'Connected!',10,0
|
|
str2 db 10,'Handshake received',10,0
|
|
str3 db 'Unsupported command: ',0
|
|
newline db 10,0
|
|
str6 db 'Entering screen',10,0
|
|
str8 db 'Leaving screen',10,0
|
|
str_err db 'Uh-Oh.. some error occured !',10,'Press any key to quit.',0
|
|
str_cls db 'Server disconnected',10,0
|
|
|
|
screeninfo:
|
|
dd (screeninfo.length - 4) shl 24
|
|
db 'DINF'
|
|
dw 0 ; coordinate of leftmost pixel
|
|
dw 0 ; coordiante of topmost pixel
|
|
.size:
|
|
dw 0 ; width
|
|
dw 0 ; height
|
|
|
|
dw 0 ; size of warp zone
|
|
|
|
dw 0xb88b ; x position of the mouse on the secondary screen (no idea what it means)
|
|
dw 0xbcfb ; y position of the mouse on the secondary screen
|
|
.length = $ - screeninfo
|
|
|
|
calv:
|
|
dd (4) shl 24
|
|
db 'CALV'
|
|
.length = $ - calv + 8 ; also send cnop
|
|
|
|
cnop:
|
|
dd (4) shl 24
|
|
db 'CNOP'
|
|
.length = $ - cnop
|
|
|
|
mousecodes db 0, 1b, 100b, 10b, 1000b, 10000b
|
|
mousestate dd 0
|
|
|
|
|
|
sockaddr1:
|
|
dw AF_INET4
|
|
.port dw 0
|
|
.ip dd 0
|
|
rb 10
|
|
|
|
filename db '.ini', 0
|
|
str_local db 'local', 0
|
|
str_name db 'name', 0
|
|
str_remote db 'remote', 0
|
|
str_port db 'port', 0
|
|
str_ip db 'ip', 0
|
|
|
|
; import
|
|
align 16
|
|
@IMPORT:
|
|
|
|
library console, 'console.obj',\
|
|
network, 'network.obj',\
|
|
libini, 'libini.obj'
|
|
|
|
import network,\
|
|
getaddrinfo, 'getaddrinfo'
|
|
|
|
import console, \
|
|
con_start, 'START',\
|
|
con_init, 'con_init',\
|
|
con_write_asciiz, 'con_write_asciiz',\
|
|
con_exit, 'con_exit',\
|
|
con_gets, 'con_gets',\
|
|
con_cls, 'con_cls',\
|
|
con_getch2, 'con_getch2',\
|
|
con_set_cursor_pos, 'con_set_cursor_pos'
|
|
|
|
import libini,\
|
|
ini.get_str, 'ini_get_str',\
|
|
ini.get_int, 'ini_get_int'
|
|
|
|
align 4
|
|
i_end:
|
|
socketnum dd ?
|
|
buffer_ptr rb BUFFERSIZE
|
|
path rb 4096
|
|
mem: |