kolibrios-fun/programs/network/synergyc/synergyc.asm
hidnplayr cf59000c24 Synergy client: support for right, middle, 4th and 5th mouse buttons
git-svn-id: svn://kolibrios.org@4380 a494cfbc-eb01-0410-851d-a64ba20cac60
2013-12-19 13:11:19 +00:00

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: