Stub for new IRC client.

git-svn-id: svn://kolibrios.org@3191 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-01-22 14:05:00 +00:00
parent 2c925a77a9
commit 5959abc989
8 changed files with 2613 additions and 0 deletions

View File

@ -0,0 +1,317 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_next_byte:
; Load next byte from the packet, translating to cp866 if necessary
; At input esi = pointer to data, edx = limit of data
; Output is either (translated) byte in al with CF set or CF cleared.
mov eax, [encoding]
jmp [get_byte_table+eax*4]
get_byte_cp866:
cmp esi, edx
jae .nothing
lodsb
.nothing:
ret
get_byte_cp1251:
cmp esi, edx
jae .nothing
lodsb
cmp al, 0x80
jb @f
and eax, 0x7F
mov al, [cp1251_table+eax]
@@:
stc
.nothing:
ret
get_byte_utf8:
; UTF8 decoding is slightly complicated.
; One character can occupy one or more bytes.
; The boundary in packets theoretically can be anywhere in data,
; so this procedure keeps internal state between calls and handles
; one byte at a time, looping until character is read or packet is over.
; Globally, there are two distinct tasks: decode byte sequence to unicode char
; and convert this unicode char to our base encoding (that is cp866).
; 1. Check that there are data.
cmp esi, edx
jae .nothing
; 2. Load byte.
lodsb
movzx ecx, al
; 3. Bytes in an UTF8 sequence can be of any of three types.
; If most significant bit is cleared, sequence is one byte and usual ASCII char.
; First byte of a sequence must be 11xxxxxx, other bytes are 10yyyyyy.
and al, 0xC0
jns .single_byte
jp .first_byte
; 4. This byte is not first in UTF8 sequence.
; 4a. Check that the sequence was started. If no, it is invalid byte
; and we simply ignore it.
cmp [utf8_bytes_rest], 0
jz get_byte_utf8
; 4b. Otherwise, it is really next byte and it gives some more bits of char.
mov eax, [utf8_char]
shl eax, 6
lea eax, [eax+ecx-0x80]
; 4c. Decrement number of bytes rest in the sequence.
; If it goes to zero, character is read, so return it.
dec [utf8_bytes_rest]
jz .got_char
mov [utf8_char], eax
jmp get_byte_utf8
; 5. If the byte is first in UTF8 sequence, calculate the number of leading 1s
; - it equals total number of bytes in the sequence; some other bits rest for
; leading bits in the character.
.first_byte:
mov eax, -1
@@:
inc eax
add cl, cl
js @b
mov [utf8_bytes_rest], eax
xchg eax, ecx
inc ecx
shr al, cl
mov [utf8_char], eax
jmp get_byte_utf8
; 6. If the byte is ASCII char, it is the character.
.single_byte:
xchg eax, ecx
.got_char:
; We got the character, now abandon a possible sequence in progress.
and [utf8_bytes_rest], 0
; Now second task. The unicode character is in eax, and now we shall convert it
; to cp866.
cmp eax, 0x80
jb .done
; 0x410-0x43F -> 0x80-0xAF, 0x440-0x44F -> 0xE0-0xEF, 0x401 -> 0xF0, 0x451 -> 0xF1
cmp eax, 0x401
jz .YO
cmp eax, 0x451
jz .yo
cmp eax, 0x410
jb .unrecognized
cmp eax, 0x440
jb .part1
cmp eax, 0x450
jae .unrecognized
sub al, (0x40-0xE0) and 0xFF
ret
.part1:
sub al, 0x10-0x80
.nothing:
.done:
ret
.unrecognized:
mov al, '?'
stc
ret
.YO:
mov al, 0xF0
stc
ret
.yo:
mov al, 0xF1
stc
ret
print_character:
pusha
cmp bl, 13 ; line beginning
jne nobol
mov ecx, [pos]
inc ecx
boll1:
dec ecx
mov eax, ecx
xor edx, edx
mov ebx, [textbox_width]
div ebx
test edx, edx
jnz boll1
mov [pos], ecx
jmp newdata
nobol:
cmp bl, 10 ; line down
jne nolf
addx1:
inc [pos]
mov eax, [pos]
xor edx, edx
mov ecx, [textbox_width]
div ecx
test edx, edx
jnz addx1
mov eax, [pos]
jmp cm1
nolf:
no_lf_ret:
cmp bl, 15 ; character
jbe newdata
mov eax, [irc_data]
shl eax, 8
mov al, bl
mov [irc_data], eax
mov eax, [pos]
;---- draw data
pusha
and ebx, 0xff
add eax, [text_start]
mov [eax], bl
popa
;---- draw data
mov eax, [pos]
inc eax
cm1:
mov ebx, [scroll+4]
imul ebx, [textbox_width]
cmp eax, ebx
jb noeaxz
mov esi, [text_start]
add esi, [textbox_width]
mov edi, [text_start]
mov ecx, ebx
rep movsb
mov esi, [text_start]
mov ecx, [textbox_width]
imul ecx, 61
add esi, ecx
mov edi, [text_start]
mov ecx, [textbox_width]
imul ecx, 60
add edi, ecx
mov ecx, ebx
rep movsb
mov eax, ebx
sub eax, [textbox_width]
noeaxz:
mov [pos], eax
newdata:
mov eax, [window_print]
or [eax + window.flags], FLAG_UPDATED
popa
ret
recode_to_cp866:
rep movsb
ret
recode_to_cp1251:
xor eax, eax
jecxz .nothing
.loop:
lodsb
cmp al,0x80
jb @f
mov al, [cp866_table-0x80+eax]
@@: stosb
loop .loop
.nothing:
ret
recode_to_utf8:
jecxz .nothing
.loop:
lodsb
cmp al, 0x80
jb .single_byte
and eax, 0x7F
mov ax, [utf8_table+eax*2]
stosw
loop .loop
ret
.single_byte:
stosb
loop .loop
.nothing:
ret
recode:
mov eax, [encoding]
jmp [recode_proc+eax*4]
encoding dd UTF8
recode_proc dd recode_to_cp866, recode_to_cp1251, recode_to_utf8
get_byte_table dd get_byte_cp866, get_byte_cp1251, get_byte_utf8
cp1251_table:
db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; 8
db '?','?','?','?','?',$F9,'?','?' , '?','?','?','?','?','?','?','?' ; 9
db '?',$F6,$F7,'?',$FD,'?','?','?' , $F0,'?',$F2,'?','?','?','?',$F4 ; A
db $F8,'?','?','?','?','?','?',$FA , $F1,$FC,$F3,'?','?','?','?',$F5 ; B
db $80,$81,$82,$83,$84,$85,$86,$87 , $88,$89,$8A,$8B,$8C,$8D,$8E,$8F ; C
db $90,$91,$92,$93,$94,$95,$96,$97 , $98,$99,$9A,$9B,$9C,$9D,$9E,$9F ; D
db $A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7 , $A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF ; E
db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; F
; 0 1 2 3 4 5 6 7 8 9 A B C D E F
utf8_table:
times 80h dw 0x98C3 ; default placeholder
; 0x80-0xAF -> 0x90D0-0xBFD0
repeat 0x30
store byte 0xD0 at utf8_table+2*(%-1)
store byte 0x90+%-1 at utf8_table+2*%-1
end repeat
; 0xE0-0xEF -> 0x80D1-0x8FD1
repeat 0x10
store byte 0xD1 at utf8_table+2*(0xE0-0x80+%-1)
store byte 0x80+%-1 at utf8_table+2*(0xE0-0x80+%)-1
end repeat
; 0xF0 -> 0x81D0, 0xF1 -> 0x91D1
store dword 0x91D181D0 at utf8_table+2*(0xF0-0x80)
cp866_table:
db $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7 , $C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF ; 8
db $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7 , $D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF ; 9
db $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7 , $E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF ; A
db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; B
db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; C
db '?','?','?','?','?','?','?','?' , '?','?','?','?','?','?','?','?' ; D
db $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7 , $F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF ; E
db $A8,$B8,$AA,$BA,$AF,$BF,$A1,$A2 , $B0,$95,$B7,'?',$B9,$A4,'?','?' ; F
; 0 1 2 3 4 5 6 7 8 9 A B C D E F

View File

@ -0,0 +1,241 @@
draw_window:
pusha
mcall 9, thread_info, -1 ; get current window size
mov eax, dword[thread_info+42] ; window xsize
mov ebx, dword[thread_info+46] ; ysize
mov edx, dword[thread_info+62] ; work area xsize
mov esi, dword[thread_info+66] ; ysize
sub eax, edx
sub ebx, esi
cmp edx, WIN_MIN_X
jae .x_ok
mov edx, WIN_MIN_X
.x_ok:
mov [xsize], edx
add edx, eax
cmp esi, WIN_MIN_Y
jae .y_ok
mov esi, WIN_MIN_Y
.y_ok:
mov [ysize], esi
add esi, ebx
mcall 67, -1, -1 ; set the new sizes
mcall 12, 1
xor eax, eax ; draw window
mov ebx, WIN_MIN_X
mov ecx, WIN_MIN_Y
mov edx, [colors.work]
add edx, 0x33000000
mov edi, str_programname
mcall
mov ebx, [xsize]
mov ecx, [ysize]
sub cx, 35
push cx
shl ecx, 16
pop cx
mov edx, [colors.work_graph]
mcall 38 ; draw line
mov ecx, TOP_Y SHL 16 + TOP_Y
mcall
mov edi, [window_open]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .not_channel
mov ebx, [xsize]
sub ebx, 100
push bx
shl ebx, 16
pop bx
mov ecx, [ysize]
add ecx, TOP_Y SHL 16 -(15+20)
mcall
call print_channel_list
.not_channel:
mov edx, [edi + window.data_ptr]
add edx, window_data.text
call draw_channel_text
; editbox
mov eax, [ysize]
sub eax, 30 ;;;;;;
mov [edit1.top], eax
mov eax, [xsize]
sub eax, 10 ;;;;;;
mov [edit1.width], eax
push dword edit1
call [edit_box_draw]
; scrollbar
mov eax, [ysize]
sub eax, TOP_Y + 35 ;;;;
mov [scroll1.y_size], ax
mov eax, [xsize]
sub eax, SCROLLBAR_WIDTH
mov [scroll1.x_pos], ax
mov [scroll1.all_redraw], 1
push dword scroll1
call [scrollbar_v_draw]
call draw_windownames
mcall 12, 2
popa
ret
print_channel_list:
pusha
mov eax, 13 ; draw rectangle (clear list)
mov ebx, [xsize]
sub ebx, 95
shl ebx, 16
push ebx
mov bx, 90 ; x size ;;; FIXME
mov ecx, TEXT_Y shl 16 + 12*10 ; y size ;;; FIXME
mov edx, [colors.work]
mcall
mov eax, 4 ; draw text
pop ebx
mov bx, TEXT_Y
mov ecx, [colors.work_text]
or ecx, 0x80000000 ; ASCIIZ string
mov edx, [window_open]
mov edx, [edx + window.data_ptr]
add edx, window_data.names
mov edi, MAX_CHANNELS
.loop:
mcall
add edx, MAX_NICK_LEN ; next name
add ebx, 10 ; height distance between lines
dec edi
jnz .loop
popa
ret
draw_channel_text:
pusha
mov eax, 4 ; draw text
mov ebx, TEXT_X shl 16 + TEXT_Y
mov ecx, 12 ; 12 lines max ?
mov esi, [textbox_width]
.dct:
pusha
mov cx, bx
shl ecx, 16
mov cx, 9 ; character height
mov eax, 13 ; draw rectangle
mov ebx, TEXT_X shl 16
mov bx, word[textbox_width]
imul bx, 6 ; character width
mov edx, [colors.work]
mcall
popa
push ecx
mov ecx, [colors.work_text]
cmp word[edx], '* '
jne .no_red
mov ecx, 0x00aa0000
jmp .draw
.no_red:
cmp word[edx], '**'
jne .no_light_blue
cmp byte[edx+2], '*'
jne .no_light_blue
mov ecx, 0x000000aa
jmp .draw
.no_light_blue:
cmp byte[edx], '#'
jne .no_blue
mov ecx, 0x0000aa00
; jmp .draw
.no_blue:
.draw:
mcall
add edx, [textbox_width]
add ebx, 10 ; height distance between lines
pop ecx
loop .dct
popa
ret
draw_windownames:
mov eax, 8
mov ebx, 5 shl 16 + 120
mov ecx, 12 shl 16 + 12
mov edx, WINDOW_BTN_START
mov edi, windows
.more_btn:
mov esi, [colors.work_button]
cmp [window_open], edi
jne @f
not esi
and esi, 0x00ffffff
@@:
mcall
inc edx
add ebx, 125 shl 16
add edi, sizeof.window
cmp [edi + + window.data_ptr], 0
jne .more_btn
mov eax, 4
mov ebx, 10 shl 16 + 15
mov ecx, [colors.work_button_text]
or ecx, 0x80000000 ; ASCIIZ string
lea edx, [windows + window.name]
mov esi, MAX_WINDOWS
.more:
mcall
add edx, sizeof.window
cmp byte[edx], 0
je .enough
add ebx, 125 shl 16
dec esi
jnz .more
.enough:
ret

View File

@ -0,0 +1,449 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IRC client for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org, ;;
;; text encoder/decoder by Clevermouse. ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
version equ '0.1'
; connection status
STATUS_DISCONNECTED = 0
STATUS_RESOLVING = 1
STATUS_CONNECTING = 2
STATUS_CONNECTED = 3
; window flags
FLAG_UPDATED = 1 shl 0
FLAG_CLOSE = 1 shl 1
; window types
WINDOWTYPE_SERVER = 0
WINDOWTYPE_CHANNEL = 1
WINDOWTYPE_CHAT = 2
WINDOWTYPE_LIST = 3
WINDOWTYPE_DCC = 4
; supported encodings
CP866 = 0
CP1251 = 1
UTF8 = 2
; settings
USERCMD_MAX_SIZE = 400
WIN_MIN_X = 600
WIN_MIN_Y = 200
TEXT_X = 5
TEXT_Y = 45
TOP_Y = 40
MAX_WINDOWS = 20
MAX_NICK_LEN = 32
MAX_REAL_LEN = 32 ; realname
MAX_SERVER_NAME = 256
MAX_CHANNEL_LEN = 40
MAX_CHANNELS = 37
MAX_COMMAND_LEN = 512
TIMESTAMP = 3 ; 3 = hh:mm:ss, 2 = hh:mm, 0 = no timestamp
MAX_WINDOWNAME_LEN = 256
WINDOW_BTN_START = 100
SCROLLBAR_WIDTH = 12
format binary as ""
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 1 ; header version
dd START ; program start
dd I_END ; program image size
dd IM_END+2048 ; required amount of memory
dd IM_END+2048
dd 0
dd path
include "../macros.inc"
include "../proc32.inc"
include "../dll.inc"
include "../network.inc"
include "../struct.inc"
include '../../../../../programs/develop/libraries/box_lib/trunk/box_lib.mac'
struct window
data_ptr dd ? ; zero if not used
flags db ?
type db ?
name rb MAX_WINDOWNAME_LEN
ends
struct window_data
text rb 120*60
title rb 256
names rb 1200
namespos dd ?
usertext rb 256
usertextlen dd ?
ends
include "encodings.inc"
include "window.inc" ; also contains text print routines
include "serverparser.inc"
include "userparser.inc"
include "socket.inc"
include "gui.inc"
START:
mcall 68, 11 ; init heap so we can allocate memory dynamically
; wanted events
mcall 40, EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_STACK + EVM_MOUSE
; load libraries
stdcall dll.Load, @IMPORT
test eax, eax
jnz exit
; find path to main settings file (ircc.ini)
mov edi, path ; Calculate the length of zero-terminated string
xor al, al
mov ecx, 1024
repne scasb
dec edi
mov eax, '.ini'
stosd
xor al, al
stosb
; Fill the window buffer with zeros
mov edi, windows
mov ecx, (sizeof.window*MAX_WINDOWS+3)/4
xor eax, eax
rep stosd
; clear command area too
mov edi, servercommand
mov ecx, 600/4
rep stosd
; allocate window data block
call window_create
mov ebx, windows
mov [ebx + window.data_ptr], eax
mov [ebx + window.flags], 0
mov [ebx + window.type], WINDOWTYPE_SERVER
add eax, window_data.text
mov [text_start], eax
call window_refresh
; get system colors
mcall 48, 3, colors, 40
; set edit box and scrollbar colors
mov eax, [colors.work]
mov [scroll1.bg_color], eax
mov eax, [colors.work_button]
mov [scroll1.front_color], eax
mov eax, [colors.work_text]
mov [scroll1.line_color], eax
; get settings from ini
invoke ini.get_str, path, str_user, str_nick, user_nick, MAX_NICK_LEN, default_nick
invoke ini.get_str, path, str_user, str_real, user_real_name, MAX_REAL_LEN, default_real
; Welcome user
mov esi, str_welcome
call print_text2
call draw_window ;;; FIXME (gui is not correctly drawn first time)
redraw:
call draw_window
still:
; wait here for event
mcall 10
dec eax
jz redraw
dec eax
jz main_window_key
dec eax
jz button
cmp al, 3
je mouse
call process_network_event
mov edx, [window_open]
test [edx + window.flags], FLAG_UPDATED
jz .no_update
and [edx + window.flags], not FLAG_UPDATED
mov edx, [edx + window.data_ptr]
add edx, window_data.text
call draw_channel_text
.no_update:
call print_channel_list
jmp still
button:
mcall 17 ; get id
shr eax, 8
cmp ax, 1 ; close program
je exit
sub ax, WINDOW_BTN_START
jb exit
cmp ax, MAX_WINDOWS
ja exit
mov dx, sizeof.window
mul dx
shl edx, 16
mov dx, ax
add edx, windows
cmp [edx + window.data_ptr], 0
je exit
mov [window_open], edx
call window_refresh
call draw_window
jmp still
exit:
mcall -1
main_window_key:
mcall 2
push dword edit1
call [edit_box_key]
cmp ah, 13 ; enter
jne no_send2
call user_parser
mov [edit1.size], 0
mov [edit1.pos], 0
push dword edit1
call [edit_box_draw]
mov edx, [window_open]
mov edx, [edx + window.data_ptr]
add edx, window_data.text
call draw_channel_text
jmp still
no_send2:
jmp still
mouse:
push dword edit1
call [edit_box_mouse]
push dword scroll1
call [scrollbar_v_mouse]
jmp still
; DATA AREA
encoding_text:
db 'CP866 '
db 'CP1251'
db 'UTF-8 '
encoding_text_len = 6
action_header db '*** ', 0
action_header_short db '* ', 0
ctcp_header db '-> [',0
ctcp_version db '] VERSION',10,0
ctcp_ping db '] PING',10,0
ctcp_time db '] TIME',10,0
has_left_channel db ' has left ', 0
joins_channel db ' has joined ', 0
is_now_known_as db ' is now known as ', 0
has_quit_irc db ' has quit IRC', 0
sets_mode db ' sets mode ', 0
kicked db ' is kicked from ', 0
str_talking db 'Now talking in ',0
str_topic db 'Topic is ',0
str_setby db 'Set by ',0
str_version db 'VERSION '
str_programname db 'KolibriOS IRC client ', version, 0
str_user db 'user', 0
str_nick db 'nick', 0
str_real db 'realname', 0
str_email db 'email', 0
default_nick db 'kolibri_user', 0
default_real db 'Kolibri User', 0
str_welcome db 10
db '.______________________ .__ .__ __',10
db '| \______ \_ ___ \ ____ | | |__| ____ _____/ |_',10
db '| || _/ \ \/ _/ ___\| | | |/ __ \ / \ __\',10
db '| || | \ \____ \ \___| |_| \ ___/| | \ |',10
db '|___||____|_ /\______ / \___ >____/__|\___ >___| /__|',10
db ' \/ \/ \/ \/ \/',10
db 10
db 'Welcome to IRC client ',version,' for KolibriOS',10
db 10
db 'Type /help for help',10,0
str_nickchange db 10,'Nickname is now ',0
str_realchange db 10,'Real name is now ',0
str_dotnewline db '.',10, 0
str_newline db 10, 0
str_connecting db 10,'* Connecting to ',0
str_help db 10,'following commands are available:',10
db 10
db '/nick <nick> : change nickname to <nick>',10
db '/real <real name> : change real name to <real name>',10
db '/server <address> : connect to server <address>',10
db '/code <code> : change codepage to cp866, cp1251, or utf8',10,0
str_1 db ' -',0
str_2 db '- ',0
str_sockerr db 'Socket Error',10,0
str_dnserr db 'Unable to resolve hostname.',10,0
str_refused db 'Connection refused',10,0
sockaddr1:
dw AF_INET4
.port dw 0x0b1a ; 6667
.ip dd 0
rb 10
status dd STATUS_DISCONNECTED
channel_line_sun dd 0x9999ff
channel_line_shadow dd 0x666699
index_list_2 dd 0x0000ff
text_start dd ? ; pointer to current textbox data
irc_data dd 0x0 ; encoder
textbox_width dd 80 ; in characters, not pixels ;)
pos dd 66 * 11 ; encoder
window_open dd windows
window_print dd windows
scroll dd 1
dd 12
align 4
@IMPORT:
library network, 'network.obj',\
libini, 'libini.obj',\
boxlib, 'box_lib.obj'
import network,\
getaddrinfo, 'getaddrinfo',\
freeaddrinfo, 'freeaddrinfo',\
inet_ntoa, 'inet_ntoa'
import libini,\
ini.get_str, 'ini_get_str',\
ini.get_int, 'ini_get_int'
import boxlib,\
edit_box_draw ,'edit_box' ,\
edit_box_key ,'edit_box_key' ,\
edit_box_mouse ,'edit_box_mouse' ,\
scrollbar_v_draw ,'scrollbar_v_draw' ,\
scrollbar_v_mouse,'scrollbar_v_mouse'
usercommand db '/server chat.freenode.net', 0
rb MAX_COMMAND_LEN
I_END:
; width, left, top
edit1 edit_box 0, 5, 0, 0xffffff, 0x6f9480, 0, 0, 0, USERCMD_MAX_SIZE, usercommand, mouse_dd, ed_focus, 25, 25
; xsize, xpos, ysize, ypos, max, cur, pos, bgcol, frcol, linecol
scroll1 scrollbar SCROLLBAR_WIDTH, 300, 150, TOP_Y, 10, 100, 0, 0, 0, 0, 0, 5
main_PID dd ? ; identifier of main thread
utf8_bytes_rest dd ? ; bytes rest in current UTF8 sequence
utf8_char dd ? ; first bits of current UTF8 character
gai_reqdata rb 32 ; buffer for getaddrinfo_start/process
ip_list dd ? ; will be filled as pointer to addrinfo list
packetbuf rb 1024 ; buffer for packets to server
path rb 1024
socketnum dd ?
servercommand rb 600
thread_info rb 1024
xsize dd ?
ysize dd ?
colors system_colors
irc_server_name rb MAX_SERVER_NAME
user_nick rb MAX_NICK_LEN
user_real_name rb MAX_REAL_LEN
windows rb MAX_WINDOWS*sizeof.window
mouse_dd dd ?
IM_END:

View File

@ -0,0 +1,8 @@
[user]
nick = kolibri_user
realname = tetten
[colors]
action1 = 0x000000aa
action2 = 0x0000aa00
action3 = 0x00aa0000

View File

@ -0,0 +1,882 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
server_parser:
mov esi, servercommand
cmp byte [esi], ':'
jne .parse
.spaceloop:
lodsb
test al, al
jz .fail
cmp al, ' '
jne .spaceloop
.parse:
mov eax, [esi]
or eax, 0x20202020
mov edi, server_commands
mov ecx, server_commands.number
.loop:
scasd
je .got_cmd
add edi, 4
dec ecx
jnz .loop
.fail:
ret
.got_cmd:
jmp dword[edi+4]
server_commands:
dd '328 ', cmd_328
dd '332 ', cmd_topic
dd '333 ', cmd_333 ; nickname and time of topic
dd '353 ', cmd_353 ; name reply
dd '366 ', cmd_366 ; end of names list
dd '372 ', cmd_372 ; motd
dd '375 ', cmd_375 ; start of motd
dd '376 ', cmd_376 ; end of motd
dd '421 ', cmd_421 ; unknown command
dd 'join', cmd_join
dd 'kick', cmd_kick
dd 'mode', cmd_mode
dd 'nick', cmd_nick
dd 'part', cmd_part
dd 'ping', cmd_ping
dd 'priv', cmd_privmsg
dd 'quit', cmd_quit
dd 'noti', cmd_notice
.number = ($ - server_commands) / 8
compare_to_nick:
push esi
mov ecx, MAX_NICK_LEN
mov esi, user_nick
.loop:
lodsb
cmp al, ' '
jbe .done
cmp al, 'a'
jb .ok
cmp al, 'z'
ja .ok
sub al, 0x20
.ok:
mov bl, byte[edi]
cmp bl, 'a'
jb .ok2
cmp bl, 'z'
ja .ok2
sub bl, 0x20
.ok2:
cmp bl, al
jne .not_equal
inc edi
dec ecx
jnz .loop
.done:
xor eax, eax
pop esi
ret
.not_equal:
or eax, -1
pop esi
ret
find_window:
; mov [window_print],
ret
cmd_328:
cmd_421:
cmd_372:
cmd_375:
cmd_376:
add esi, 4
jmp cmd_notice.loop
cmd_notice:
cmp byte[servercommand], ':'
jne .gogogo
mov byte [esi-1], 0
push esi
mov esi, str_1
call print_text2
mov esi, servercommand+1
call print_text2
mov esi, str_2
call print_text2
pop esi
.gogogo:
add esi, 6
.loop:
inc esi
cmp byte [esi], 0
je .fail
cmp byte [esi], 10 ; newline
je server_parser.parse
cmp byte [esi], ' '
jne .loop
.loop2:
inc esi
cmp byte [esi], 0
je .fail
cmp byte [esi], ' '
je .loop2
cmp byte [esi], ':'
je .loop2
call print_text2
mov esi, str_newline
call print_text2
.fail:
ret
cmd_ping:
; Just change PING to PONG
mov dword[esi], 'PONG'
; Find the end of the command
lea edi, [esi + 5]
xor al, al
repne scasb
; Now send it back
mov edx, esi
mov esi, edi
mov word [esi], 0x0d0a
inc esi
inc esi
sub esi, edx
mcall send, [socketnum], , , 0
ret
cmd_privmsg:
; Check if it was destined for me privately
mov edi, servercommand+1
call compare_to_nick
;;; je .private
; If not, find the correct window ???
; now find the end of nick
mov edi, esi
.loop:
inc edi
cmp byte [edi], 0
je .fail
cmp byte [edi], ' '
jne .loop
.loop2:
inc edi
cmp byte [edi], 0
je .fail
cmp byte [edi], ' '
je .loop2
cmp byte [edi], ':'
je .loop2
cmp byte [edi], 1
je cmd_ctcp
; Action?
cmp dword[edi+1], 'ACTI'
je .action
; nope, just plain old privmsg
if TIMESTAMP
call print_timestamp
end if
push edi
mov bl, '<'
call print_character
mov eax, servercommand+1
mov dl, '!'
call print_text
mov bl, '>'
call print_character
mov bl, ' '
call print_character
pop esi
call print_text2
mov bl, 10
call print_character
.fail:
ret
.action:
push edi
if TIMESTAMP
call print_timestamp
end if
mov esi, action_header_short
call print_text2
mov eax, servercommand+1
mov dl, ' '
call print_text
mov bl, ' '
call print_character
pop esi
add esi, 8
call print_text2
mov bl, 10
call print_character
ret
cmd_ctcp:
cmp dword[edi+1], 'VERS'
je .version
cmp dword[edi+1], 'TIME'
je .time
cmp dword[edi+1], 'PING'
je .ping
ret
.time:
lea esi, [edi+1]
mov byte [edi+5], ' '
add edi, 6
; TODO: add system date (fn 29) in human readable format
mcall 3 ; get system time
mov ecx, 3
.timeloop:
mov bl, al
shr al, 4
add al, '0'
stosb
mov al, bl
and al, 0x0f
add al, '0'
stosb
dec ecx
jz .timedone
mov al, ':'
stosb
shr eax, 8
jmp .timeloop
.timedone:
xor al, al
stosb
call ctcp_reply
if TIMESTAMP
call print_timestamp
end if
mov esi, ctcp_header
call print_text2
mov esi, servercommand+1
call print_text2
mov esi, ctcp_time
call print_text2
ret
.version:
mov esi, str_version
call ctcp_reply
if TIMESTAMP
call print_timestamp
end if
mov esi, ctcp_header
call print_text2
mov esi, servercommand+1
call print_text2
mov esi, ctcp_version
call print_text2
ret
.ping:
lea esi, [edi+1]
call ctcp_reply
if TIMESTAMP
call print_timestamp
end if
mov esi, ctcp_header
call print_text2
mov esi, servercommand+1
call print_text2
mov esi, ctcp_ping
call print_text2
ret
ctcp_reply:
push esi
mov dword [usercommand], 'NOTI'
mov dword [usercommand+4], 'CE '
mov esi, servercommand+1
mov edi, usercommand+7
.nickloop:
lodsb
cmp al, '!'
je .done
cmp al, ' '
je .done
test al, al
je .fail
stosb
jmp .nickloop
.done:
mov byte [esi-1], 0
mov ax, ' :'
stosw
mov al, 1
stosb
pop esi
.replyloop:
lodsb
cmp al, 1
jbe .done2
stosb
jmp .replyloop
.done2:
mov al, 1
stosb
mov ax, 0x0a0d
stosw
lea esi, [edi - usercommand]
mcall send, [socketnum], usercommand, , 0
.fail:
ret
cmd_part:
; Is it me who parted?
mov edi, servercommand+1
call compare_to_nick
jne .dont_close
; yes, close the window
mov edi, [window_print]
mov [edi + window.flags], FLAG_UPDATED + FLAG_CLOSE
ret
; somebody else parted, just print message
.dont_close:
push esi
mov esi, action_header
call print_text2
mov eax, servercommand+1
mov dl, '!'
mov cl, ' '
call print_text
mov esi, has_left_channel
call print_text2
pop esi
call print_text2
ret
cmd_join:
; compare nick: did we join a channel?
mov edi, servercommand+1
call compare_to_nick
jne .no_new_window
; create channel window - search for empty slot
mov ebx, windows
mov ecx, MAX_WINDOWS
.loop:
cmp [ebx + window.data_ptr], 0
je .free_found
add ebx, sizeof.window
dec ecx
jnz .loop
; Error: no more available windows!! ;;;;; TODO
.fail:
ret
.free_found:
push ebx
call window_create
pop ebx
test eax, eax
jz .fail
mov [ebx + window.data_ptr], eax
mov [ebx + window.type], WINDOWTYPE_CHANNEL
mov [ebx + window.flags], 0
call window_set_name
mov [window_open], ebx
mov [window_print], ebx
call window_refresh
push esi
mov esi, action_header
call print_text2
mov esi, str_talking
call print_text2
pop eax
mov dl, ' '
call print_text
mov esi, str_dotnewline
call print_text2
call draw_window
ret
.no_new_window:
push esi
call window_set_name
mov esi, action_header
call print_text2
mov eax, servercommand+1
mov dl, ' '
call print_text
mov esi, joins_channel
call print_text2
pop esi
call print_text2
mov esi, str_newline
call print_text2
ret
cmd_nick: ; FIXME
push esi
; test for change of my nick
mov esi, servercommand+1
mov edi, user_nick
mov ecx, MAX_NICK_LEN
rep cmpsb
cmp byte[edi-1], 0
jne .notmy
cmp byte[esi-1], '!'
jne .notmy
; yes, this is my nick, set to new
pop esi
or ecx, -1
mov edi, esi
xor eax, eax
repne scasb
neg ecx
cmp ecx, MAX_NICK_LEN
jb @f
mov ecx, MAX_NICK_LEN
@@:
mov edi, user_nick
rep movsb
.notmy:
; replace nick in all lists of users
mov ebx, windows
.channels:
mov esi, [ebx + window.data_ptr]
lea esi, [esi + window_data.names]
;;;;; mov edx, [esi + window_data.nameslen]
add edx, esi
.nicks:
mov edi, servercommand+1
cmp byte[esi], '@'
jne @f
inc esi
@@:
cmp esi, edx
jae .srcdone
lodsb
cmp al, ' '
je .srcdone
scasb
je @b
@@:
cmp esi, edx
jae .nextchannel
lodsb
cmp al, ' '
jne @b
.nextnick:
cmp esi, edx
jae .nextchannel
lodsb
cmp al, ' '
jz .nextnick
dec esi
jmp .nicks
.srcdone:
cmp byte [edi], '!'
jne .nextnick
; here we have esi -> end of nick which must be replaced to [servercommand_position]+6
lea edx, [edi-servercommand-1]
sub esi, edx
or ecx, -1
xor eax, eax
; mov edi, [servercommand_position] ;;;;; FIXME
repnz scasb
not ecx
dec ecx
push ecx
cmp ecx, edx
jb .decrease
jz .copy
.increase:
; new nick is longer than the old
push esi
lea edi, [ebx+120*10] ;;;;;;
lea esi, [edi+edx]
sub esi, ecx
mov ecx, esi
sub ecx, [esp]
dec esi
dec edi
std
rep movsb
cld
pop esi
jmp .copy
.decrease:
; new nick is shorter than the old
push esi
lea edi, [esi+ecx]
add esi, edx
lea ecx, [ebx+120*10]
sub ecx, edi
rep movsb
pop esi
.copy:
; copy nick
mov edi, esi
dec edi
; mov esi, [servercommand_position] ;;;;; FIXME
pop ecx
sub edx, ecx
sub [ebx-4], edx
rep movsb
mov al, ' '
stosb
.nextchannel:
add ebx, sizeof.window
cmp ebx, windows + sizeof.window*MAX_WINDOWS
jb .channels
; mov [text_start], window_text + 120*80
new_all_channels3:
mov esi, action_header_short
call print_text2
mov eax, servercommand+1
mov dl,'!'
call print_text
mov esi,is_now_known_as
call print_text2
; mov esi,[servercommand_position] ;;;;; FIXME
call print_text2
;;; call notify_channel_thread
; go to next window (and check if its a channel!)
; add [text_start], 120*80
; cmp [text_start], I_END+120*80*20
; jb new_all_channels3
ret
cmd_kick:
; Is it me who got kicked?
mov edi, servercommand+1
call compare_to_nick
jne .not_me
; TODO: mark channel as disconnected
.not_me:
; find the channel user has been kicked from
push esi
mov esi, action_header_short
call print_text2
mov eax, servercommand+1
mov dl,'!'
call print_text
mov esi, kicked
call print_text2
pop esi
call print_text2
ret
cmd_quit:
mov esi, action_header
call print_text2
mov eax, servercommand+1
mov dl, '!'
call print_text
mov esi, has_quit_irc
call print_text2
ret
cmd_mode:
push esi
mov esi, action_header_short
call print_text2
mov eax, servercommand+1
mov dl, ' '
call print_text
mov esi, sets_mode
call print_text2
pop esi
call print_text2
mov esi, str_newline
call print_text2
ret
cmd_353: ; channel usernames reply
; TODO: mark a bit that we are receiving names
; first, find the channel name
.loop1:
lodsb
cmp al, '#'
je .got_channel
test al, al
jnz .loop1
ret
.got_channel:
; call find_channel ;;;; ASSUME current channel for now
mov ebx, [window_print]
mov ebx, [ebx + window.data_ptr]
lea edi, [ebx + window_data.names]
lea edx, [edi + MAX_NICK_LEN]
; now find the semicolon separating channelname and usernames
.loop2:
lodsb
cmp al, ':'
je .namesloop
test al, al
jnz .loop2
ret
.namesloop:
; now the names list begins, separated with spaces
lodsb
test al, al
jz .done
cmp al, ' '
jz .next
stosb
jmp .namesloop
.next:
mov edi, edx
add edx, MAX_NICK_LEN
;;; cmp edi, .. ; Check for buffer overflow
jmp .namesloop
.done:
call print_channel_list
ret
cmd_366: ; channel usernames end
; TODO: clear the bit that we are receiving names
ret
cmd_topic:
.loop:
lodsb
test al, al
je .fail
cmp al, ':'
jne .loop
push esi
mov esi, action_header
call print_text2
mov esi, str_topic
call print_text2
pop esi
call print_text2
mov esi, str_newline
call print_text2
.fail:
ret
cmd_333:
; TODO: check channelname and change pointer accordingly
mov ecx, 3 ; number of spaces to find
.loop:
lodsb
test al, al
je .fail
cmp al, ' '
jne .loop
dec ecx
jnz .loop ; find some more spaces
push esi
mov esi, action_header
call print_text2
mov esi, str_setby
call print_text2
pop esi
call print_text2
mov esi, str_newline
call print_text2
.fail:
ret

View File

@ -0,0 +1,240 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
socket_connect:
; cmp [status], STATUS_CONNECTED ; TODO
; je disconnect
; ignore if status is not "disconnected"
cmp [status], STATUS_DISCONNECTED
jne .nothing
mov esi, str_connecting
call print_text2
mov esi, irc_server_name
call print_text2
mov esi, str_dotnewline
call print_text2
; update status
inc [status] ; was STATUS_DISCONNECTED, now STATUS_RESOLVING
; resolve name
push esp ; reserve stack place
push esp ; fourth parameter
push 0 ; third parameter
push 0 ; second parameter
push irc_server_name
call [getaddrinfo]
pop esi
; test for error
test eax, eax
jnz .fail_dns
; fill in ip in sockstruct
mov eax, [esi + addrinfo.ai_addr]
mov eax, [eax + sockaddr_in.sin_addr]
mov [sockaddr1.ip], eax
; free allocated memory
push esi
call [freeaddrinfo]
; update status
inc [status]
; connect
mcall socket, AF_INET4, SOCK_STREAM, 0
cmp eax, -1
jz .fail
mov [socketnum], eax
mcall connect, [socketnum], sockaddr1, 18
cmp eax, -1
jz .fail_refused
.nothing:
ret
.fail:
mov [status], STATUS_DISCONNECTED
mov esi, str_sockerr
call print_text2
ret
.fail_dns:
mov [status], STATUS_DISCONNECTED
mov esi, str_dnserr
call print_text2
ret
.fail_refused:
mov [status], STATUS_DISCONNECTED
mov esi, str_refused
call print_text2
ret
socket_write_userinfo:
; create packet in packetbuf
mov edi, packetbuf
mov eax, 'NICK'
stosd
mov al, ' '
stosb
mov esi, user_nick
mov ecx, MAX_NICK_LEN
.loop:
lodsb
test al, al
jz .done
stosb
dec ecx
jnz .loop
.done:
mov ax, 0x0d0a
stosw
mov eax, 'USER'
stosd
mov al, ' '
stosb
mov esi, user_nick
mov ecx, MAX_NICK_LEN
.loop2:
lodsb
test al, al
jz .done2
stosb
dec ecx
jnz .loop2
.done2:
mov eax, ' 8 *'
stosd
mov ax, ' :'
stosw
mov al, ' '
stosb
mov esi, user_real_name
mov ecx, MAX_REAL_LEN
.loop3:
lodsb
test al, al
jz .done3
stosb
dec ecx
jnz .loop3
.done3:
mov ax, 0x0d0a
stosw
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
ret
process_network_event:
; values for status: 0, 1, 2, 3
mov eax, [status]
dec eax
; 0 = STATUS_DISCONNECTED - do nothing
; (ignore network events if we are disconnected from network)
js .nothing
; 1 = STATUS_RESOLVING
jz .nothing
; 2 = STATUS_CONNECTING
dec eax
jz .connecting
; 3 = STATUS_CONNECTED
jmp .connected
.nothing:
ret
.connecting:
call socket_write_userinfo
; The connection has been established, change status from "connecting" to "connected".
inc [status]
.connected:
call read_incoming_data
ret
disconnect:
cmp [status], STATUS_DISCONNECTED
je .nothing
mcall close, [socketnum]
mov [status], STATUS_DISCONNECTED
.nothing:
ret
read_incoming_data:
pusha
; TODO: read more data if we receive one full packet
.nextpacket:
mcall recv, [socketnum], packetbuf, 1024 ; read a packet
inc eax ; check if we got one
jz .done
dec eax
jz .done
; ok we have data, now feed it to the recoder
lea edx, [packetbuf + eax] ; edx = end pointer
mov esi, packetbuf ; esi = start pointer
.nextcommand:
mov edi, servercommand
.byteloop:
call get_next_byte ; reads byte from [esi] to al
jnc .nextpacket ; if CF is set, we need more data
cmp al, 10
je .got_command
stosb
jmp .byteloop
; we have a command, call the serverparser
.got_command:
mov byte[edi-1], 0 ; mark the end of the command
push esi edx
call server_parser
pop edx esi
jmp .nextcommand
.done:
popa
ret

View File

@ -0,0 +1,313 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
user_parser:
mov eax, [edit1.size]
mov word [usercommand + eax], 0x0a0d ; terminate the line
cmp byte[usercommand], '/' ; is it a server command ?
je server_command
; Ignore data commands when not connected.
cmp [status], STATUS_CONNECTED
jne sdts_ret
; Ok, we said something, print it to our textbox
if TIMESTAMP
call print_timestamp
end if
mov bl, '<'
call print_character
mov esi, user_nick
call print_text2
mov bl,'>'
call print_character
mov bl,' '
call print_character
mov eax, [edit1.size]
mov byte[usercommand + eax],0
mov esi, usercommand
call print_text2
mov bl, 10
call print_character
; and now send it to the server
mov dword[packetbuf], 'priv'
mov dword[packetbuf+4], 'msg '
mov esi, [window_print]
add esi, window.name
mov edi, packetbuf+8
mov ecx, MAX_WINDOWNAME_LEN
.loop:
lodsb
test al, al
jz .done
stosb
dec ecx
jnz .loop
.done:
mov ax, ' :'
stosw
mov esi, usercommand
mov ecx, [edit1.size]
inc ecx
call recode
mov al, 10
stosb
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
sdts_ret:
ret
user_commands:
dd 'nick', cmd_usr_nick
dd 'real', cmd_usr_real
dd 'serv', cmd_usr_server
dd 'help', cmd_usr_help
dd 'code', cmd_usr_code
; TODO: All other commands require a connection to the server.
dd 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit
.number = ($ - user_commands) / 8
server_command:
mov eax, dword[usercommand+1]
or eax, 0x20202020
mov edi, user_commands
mov ecx, user_commands.number
.loop:
scasd
je .got_cmd
add edi, 4
dec ecx
jnz .loop
jmp cmd_usr_send ; If none of the previous commands, just send to server
.got_cmd:
jmp dword[edi]
cmd_usr_quit:
cmp [edit1.size], 5
je .ok
jb cmd_usr_send
cmp byte[usercommand+5], ' '
jne cmd_usr_send
.ok:
call cmd_usr_send
mcall close, [socketnum]
mov ecx, MAX_WINDOWS
mov edi, windows
.loop:
mov [edi+window.flags], FLAG_CLOSE
; call notify_channel_thread
add edi, sizeof.window
dec ecx
jnz .loop
ret
cmd_usr_nick:
cmp [edit1.size], 5
je .justprint
cmp byte[usercommand+5], ' '
jne cmd_usr_send
mov ecx, MAX_NICK_LEN
mov esi, usercommand+6
mov edi, user_nick
.loop:
lodsb
cmp al, 13
je .done
stosb
dec ecx
jnz .loop
.done:
xor al, al
stosb
cmp [socketnum], 0
je .justprint
lea esi, [edi - usercommand]
mcall send, [socketnum], usercommand+1, , 0
.justprint:
mov esi, str_nickchange
call print_text2
mov esi, user_nick
call print_text2
mov esi, str_dotnewline
call print_text2
ret
cmd_usr_real:
cmp byte[usercommand+5], ' '
jne cmd_usr_send
mov ecx, MAX_REAL_LEN
mov esi, usercommand+6
mov edi, user_real_name
.loop:
lodsb
cmp al, 13
je .done
stosb
dec ecx
jnz .loop
.done:
xor al, al
stosb
mov esi, str_realchange
call print_text2
mov esi, user_real_name
call print_text2
mov esi, str_dotnewline
call print_text2
ret
cmd_usr_server:
mov eax, dword[usercommand+5] ; check for 'er ', we only checked 'serv'
or eax, 0x00002020
and eax, 0x00ffffff
cmp eax, 'er '
jne cmd_usr_send
mov ecx, [edit1.size] ; ok now set the address
sub ecx, 8
mov esi, usercommand+8
push esi
mov edi, irc_server_name
rep movsb
xor al, al
stosb
pop esi
; set it also in window name
mov ebx, [window_print]
call window_set_name
; now connect
call socket_connect
ret
cmd_usr_quer:
mov ecx, MAX_WINDOWS
mov ebx, windows
.loop:
cmp [ebx + window.data_ptr], 0
je .found
add ebx, sizeof.window
dec ecx
jnz .loop
; error: no available channels ! FIXME
ret
.found:
call window_create
test eax, eax
jz .error
mov [ebx + window.data_ptr], eax
mov esi, usercommand+7
call window_set_name
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
.error:
ret
cmd_usr_help:
mov esi, str_help
call print_text2
ret
cmd_usr_code:
; TODO
ret
cmd_usr_send:
mov esi, usercommand+1
mov ecx, [edit1.size]
inc ecx
mov edi, packetbuf
call recode
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
ret

View File

@ -0,0 +1,163 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
window_create:
; allocate the window data block
mcall 68, 12, sizeof.window_data
test eax, eax
jz .fail
; fill it with all zeros
push eax
mov edi, eax
mov ecx, (sizeof.window_data+3)/4
xor eax, eax
rep stosd
pop eax
.fail:
ret
window_set_name: ; esi = ptr to name, ebx = window ptr
pusha
; Skip heading spaces
.spaceloop:
cmp byte[esi], ' '
jne .done
inc esi
jmp .spaceloop
.done:
; Now copy it
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
.loop:
lodsb
cmp al, 10
jbe .addzero
stosb
dec ecx
jnz .loop
.addzero:
xor al, al
stosb
call draw_windownames ; redraw it
popa
ret
window_find: ; esi is ptr to windowname
; mov [current_window],
; call reset_gui
.fail:
ret
window_refresh:
; set the correct buffer pointers ; FIXME: what is it good for?
mov eax, [textbox_width] ;
imul eax, 11 ;
mov [pos], eax ;
mov eax, [window_open]
mov eax, [eax + window.data_ptr]
add eax, window_data.text
mov [text_start], eax
ret
print_text: ; eax = start ptr
; dl = end char
pusha
ptr2:
mov bl, [eax]
cmp bl, dl
je ptr_ret
cmp bl, 0
je ptr_ret
call print_character
inc eax
jmp ptr2
ptr_ret:
popa
ret
print_text2: ; esi = ptr to ASCIIZ string
pusha
.loop:
lodsb
test al, al
jz .done
mov bl, al
call print_character
jmp .loop
.done:
popa
ret
if TIMESTAMP
print_timestamp:
pusha
mcall 3 ; get system time
mov bl, '['
call print_character
mov ecx, TIMESTAMP
.loop:
mov bl, al
shr bl, 4
add bl, '0'
call print_character
mov bl, al
and bl, 0x0f
add bl, '0'
call print_character
dec ecx
jz .done
mov bl, ':'
call print_character
shr eax, 8
jmp .loop
.done:
mov bl, ']'
call print_character
mov bl, ' '
call print_character
popa
ret
end if