Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4476 → Rev 4477

/programs/network/ircc/ircc.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; IRC client for KolibriOS ;;
13,7 → 13,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
version equ '0.15'
version equ '0.16'
 
; connection status
STATUS_DISCONNECTED = 0
52,7 → 52,7
 
MAX_WINDOWS = 20
MAX_USERS = 4096
TEXT_BUFFERSIZE = 4096;*1024
TEXT_BUFFERSIZE = 1024*1024
 
MAX_NICK_LEN = 32
MAX_REAL_LEN = 32 ; realname
97,7 → 97,7
include "../../dll.inc"
include "../../network.inc"
include "../../struct.inc"
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
include "../../develop/libraries/box_lib/trunk/box_lib.mac"
 
struct window
data_ptr dd ?
169,7 → 169,7
 
; allocate window data block
mov ebx, windows
call window_create
call window_create_textbox
test eax, eax
jz error
mov [ebx + window.type], WINDOWTYPE_SERVER
202,14 → 202,22
mov esi, str_welcome
call print_text2
 
call draw_window ; Draw window a first time, so we can figure out skin size
; Check if parameter contains an URL
cmp byte[param], 0
je @f
mov esi, param
mov ecx, 1024
call cmd_usr_server.now
@@:
 
; Draw window a first time, so we can figure out skin size
call draw_window
 
redraw:
call draw_window
 
still:
; wait here for event
mcall 10
mainloop:
mcall 10 ; wait for event
 
dec eax
jz redraw
235,7 → 243,7
call draw_channel_list
.no_update:
 
jmp still
jmp mainloop
 
button:
 
248,7 → 256,7
cmp ax, WINDOW_BTN_CLOSE
jne @f
call cmd_usr_close_window
jmp still
jmp mainloop
 
@@:
cmp ax, WINDOW_BTN_LIST
270,8 → 278,10
 
pop eax
test eax, 1 shl 25 ; Right mouse button pressed?
jz still
jz mainloop
 
; TODO: check if selected nick is my nick!
 
; Right mouse BTN was pressed, open chat window
mov ebx, [window_active]
mov eax, [ebx + window.selected]
284,7 → 294,7
pop [window_active]
call redraw
 
jmp still
jmp mainloop
 
@@:
sub ax, WINDOW_BTN_START
306,7 → 316,7
mov [scroll2.position], 1 ;;; FIXME
call draw_window
 
jmp still
jmp mainloop
 
exit:
 
332,7 → 342,7
; cmp ah, 178
; jne .no_up
;
; jmp still
; jmp mainloop
;
;
; .no_up:
339,7 → 349,7
; cmp ah, 177
; jne .no_down
;
; jmp still
; jmp mainloop
;
; .no_down:
cmp ah, 13 ; enter
357,15 → 367,19
 
call draw_channel_text
 
jmp still
jmp mainloop
no_send2:
 
jmp still
jmp mainloop
 
mouse:
push dword edit1
call [edit_box_mouse]
 
; mcall 37, 7
; movsx eax, ax
; add [scroll2.position], eax
 
; TODO: check if scrollbar is active?
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
386,7 → 400,7
jbe @f
push dword scroll2
call [scrollbar_mouse]
; mov edi, [window_active]
mov edi, [window_active]
mov edx, [scroll2.position]
sub edx, [edi + window.text_line_print]
je @f
393,7 → 407,7
call draw_channel_text.scroll_to_pos
@@:
 
jmp still
jmp mainloop
 
 
; DATA AREA
417,35 → 431,46
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', 10, 0
 
sets_mode db ' sets mode ', 0
kicked db ' is kicked from ', 0
str_nickchange db 'Nickname is now ', 0
str_realchange db 'Real name is now ', 0
str_talking db 'Now talking in ',0
str_topic db 'Topic is ',0
str_topic db 'Topic is "', 0
str_topic_end db '".', 10, 0
str_setby db 'Set by ',0
str_reconnect db 'Connection reset by user.',10,0
 
str_version db 'VERSION '
str_programname db 'KolibriOS IRC client ', version, 0
str_connecting db 3, '3* Connecting to ', 0
str_sockerr db 3, '5* Socket error', 10, 0
str_dnserr db 3, '5* Unable to resolve hostname', 10, 0
str_refused db 3, '5* Connection refused', 10, 0
str_disconnected db 3, '5* Server disconnected', 10, 0
str_reconnect db 3, '5* Connection reset by user', 10, 0
str_notconnected db 3, '5* Not connected to server', 10, 0
 
str_user db 'user', 0
str_nick db 'nick', 0
str_real db 'realname', 0
str_email db 'email', 0
str_quitmsg db 'quitmsg', 0
str_dotnewline db '.',10, 0
str_newline db 10, 0
str_1 db 3, '13 -', 0
str_2 db '- ', 0
 
default_nick db 'kolibri_user', 0
default_real db 'Kolibri User', 0
default_quit db 'KolibriOS forever', 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_welcome db 3,'3 ___',3,'7__________',3,'6_________ ',3,'4 __ __ __',10
db 3,'3| \',3,'7______ \',3,'6_ ___ \ ',3,'4 ____ | | |__| ____ _____/ |_',10
db 3,'3| |',3,'7| _/',3,'6 \ \/ ',3,'4 _/ ___\| | | |/ __ \ / \ __\',10
db 3,'3| |',3,'7| | \',3,'6 \____',3,'4 \ \___| |_| \ ___/| | \ |',10
db 3,'3|___|',3,'7|____|_ /\',3,'6______ /',3,'4 \___ >____/__|\___ >___| /__|',10
db 3, '3|___|', 3, '7|____|_ /', 3, '6\______ /', 3, '4 \___ >____/__|\___ >___| /__|', 10
db 3,'3 ',3,'7 \/ ',3,'6 \/ ',3,'4 \/ \/ \/',10
db 10
db 'Welcome to the KolibriOS IRC client v',version,10
452,24 → 477,18
db 10
db 'Type /help for help',10,10,0
 
str_nickchange db 'Nickname is now ',0
str_realchange db 'Real name is now ',0
str_dotnewline db '.',10, 0
str_newline db 10, 0
str_connecting db 3,'3* 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_version db 'VERSION '
str_programname db 'KolibriOS IRC client v', version, 0
 
str_1 db 3,'13 -',0
str_2 db '- ',0
str_user db 'user', 0
str_nick db 'nick', 0
str_real db 'realname', 0
str_email db 'email', 0
str_quitmsg db 'quitmsg', 0
 
str_sockerr db 'Socket Error',10,0
str_dnserr db 'Unable to resolve hostname.',10,0
str_refused db 'Connection refused',10,0
default_nick db 'kolibri_user', 0
default_real db 'Kolibri User', 0
default_quit db 'KolibriOS forever', 0
 
irc_colors dd 0xffffff ; 0 white
dd 0x000000 ; 1 black
490,7 → 509,7
 
sockaddr1:
dw AF_INET4
.port dw 0x0b1a ; 6667
.port dw 0x0b1a ; 6667 FIXMEEEEEE
.ip dd 0
rb 10
 
527,8 → 546,6
scrollbar_draw, 'scrollbar_v_draw',\
scrollbar_mouse,'scrollbar_v_mouse'
 
I_END:
 
; width, left, top
edit1 edit_box 0, 0, 0, 0xffffff, 0x6f9480, 0, 0, 0, USERCMD_MAX_SIZE, usercommand, mouse_dd, ed_focus, 25, 25
; xsize, xpos, ysize, ypos, btn_height, max, cur, pos, bgcol, frcol, linecol
538,34 → 555,34
usercommand db '/server chat.freenode.net', 0
rb MAX_COMMAND_LEN
 
I_END:
 
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
param rb 1024
 
socketnum dd ?
 
servercommand rb 600
 
thread_info rb 1024
xsize dd ?
ysize dd ?
mouse_dd dd ?
 
colors system_colors
 
irc_server_name rb MAX_SERVER_NAME
irc_server_name rb MAX_SERVER_NAME ; TODO: move this server URL into window struct
socketnum dd ? ; TODO: same for socket
 
user_nick rb MAX_NICK_LEN
user_real_name rb MAX_REAL_LEN
quit_msg rb 250
 
diff16 "windows", 0, $ + 1*sizeof.window ;+ 6
windows rb MAX_WINDOWS*sizeof.window
 
mouse_dd dd ?
 
IM_END:
 
 
/programs/network/ircc/serverparser.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
60,6 → 60,7
dd '375 ', cmd_375 ; start of motd
dd '376 ', cmd_376 ; end of motd
dd '421 ', cmd_421 ; unknown command
dd '433 ', cmd_433 ; nickname already in use
dd 'join', cmd_join
dd 'kick', cmd_kick
dd 'mode', cmd_mode
83,6 → 84,8
lodsb
cmp al, ' '
jbe .done
test al, al
jz .done
cmp al, 'a'
jb .ok
cmp al, 'z'
116,24 → 119,23
 
 
align 4
skip_nick:
skip_parameter:
 
; First: skip the NICK (maybe we should verify it?)
.nick:
; First: skip the parameter
.part1:
lodsb
cmp al, ' '
je .skip
je .part2
cmp al, ':'
je .skip
jmp .nick
jne .part1
 
; skip all leading spaces and semicolons
.skip:
; Now, skip all trailing spaces and semicolons
.part2:
lodsb
cmp al, ' '
je .skip
je .part2
cmp al, ':'
je .skip
je .part2
dec esi
 
ret
147,6 → 149,7
cmd_372:
cmd_375:
cmd_376:
cmd_433:
add esi, 4
jmp cmd_notice.loop
 
228,11 → 231,27
cmp eax, 'msg '
jne .fail
add esi, 8 ; skip 'PRIVMSG '
call window_open ; esi now points to end of destination name
 
mov edi, esi
call compare_to_nick
jne .channel
 
; private chat message
push esi
mov esi, servercommand+1
call window_open
pop esi
call skip_parameter ; our own nickname
 
cmp byte[esi], 1 ; Client to Client protocol?
je cmd_ctcp
 
jmp .print
 
.channel:
call window_open
 
.print:
; nope, just plain old privmsg, print it using '<nick> message' format
if TIMESTAMP
call print_timestamp
266,8 → 285,6
 
cmd_ctcp:
 
cmp byte [esi+4], ' '
jne .fail
inc esi
mov eax, dword[esi]
or eax, 0x20202020
280,8 → 297,8
je .ping
cmp eax, 'acti'
je .action
; cmp eax, 'dcc ' ; TODO
; je cmd_dcc
cmp eax, 'dcc ' ; TODO
je cmd_dcc
 
; Unknown CTCP command: TODO: just print to window??
 
413,6 → 430,9
 
.send:
 
call window_open
mov [ebx + window.type], WINDOWTYPE_DCC
 
ret
 
 
472,7 → 492,7
; Is it me who parted?
mov edi, servercommand+1
call compare_to_nick
jne .dont_close
jne .not_me
 
; yes, close the window (if its open)
call window_find
486,11 → 506,14
 
 
; somebody else parted, just print message
.dont_close:
.not_me:
push esi
call skip_nick
call window_open
 
if TIMESTAMP
call print_timestamp
end if
 
mov esi, part_header
call print_text2
 
525,37 → 548,19
; compare nick: did we join a channel?
mov edi, servercommand+1
call compare_to_nick
jne .no_new_window
jne .not_me
 
; 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
 
ret
 
.free_found:
call window_create
push esi
call window_open
test eax, eax
jz .fail
mov [ebx + window.type], WINDOWTYPE_CHANNEL
 
call window_set_name
 
mov [window_active], ebx
mov [window_print], ebx
 
if TIMESTAMP
call print_timestamp
end if
 
push esi
mov esi, join_header
call print_text2
 
573,7 → 578,7
 
ret
 
.no_new_window:
.not_me:
push esi
call window_open
 
601,8 → 606,10
mov esi, servercommand+1
call user_add
 
ret
 
.fail:
 
add esp, 4
ret
 
 
711,7 → 718,7
.not_me:
; find the channel user has been kicked from
push esi
call skip_nick
call skip_parameter
call window_open
 
if TIMESTAMP
802,18 → 809,7
call window_find
test ebx, ebx
jz .fail
 
; skip channel name
@@:
lodsb
test al, al
jz .fail
cmp al, 10
je .fail
cmp al, 13
je .fail
cmp al, ' '
jne @r
mov [window_print], ebx
push esi
 
if TIMESTAMP
846,7 → 842,7
cmd_353: ; channel usernames reply
 
add esi, 4 ; skip '353 '
call skip_nick
call skip_parameter
inc esi ; channel type '*', '=' or '@'
inc esi ; ' '
call window_open
885,7 → 881,7
cmd_366: ; channel usernames end
 
add esi, 4 ; skip '366 '
call skip_nick
call skip_parameter
call window_open
 
mov ebx, [window_print]
899,7 → 895,7
cmd_topic:
 
add esi, 4 ; skip '332 '
call skip_nick
call skip_parameter
call window_open
 
if TIMESTAMP
916,7 → 912,7
pop esi
call print_text2
 
mov esi, str_newline
mov esi, str_topic_end
call print_text2
 
ret
925,19 → 921,9
cmd_333:
 
add esi, 4 ; skip '333 '
call skip_nick ;;;;
call skip_parameter ;;;;
call window_open
 
; mov ecx, 2 ; number of spaces to find ;;; CHECKME
; .loop:
; lodsb
; test al, al
; je .fail
; cmp al, ' '
; jne .loop
; dec ecx
; jnz .loop ; find some more spaces
 
if TIMESTAMP
call print_timestamp
end if
967,7 → 953,7
add esi, 4
 
mov [window_print], windows ; FIXME
call skip_nick
call skip_parameter
mov eax, esi
mov dl, 13
call print_text
/programs/network/ircc/socket.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
100,7 → 100,6
ret
 
.reconnect:
 
if TIMESTAMP
call print_timestamp
end if
213,10 → 212,10
 
.nextpacket:
mcall recv, [socketnum], packetbuf, 1024, MSG_DONTWAIT ; read a packet
inc eax ; check if we got one
jz .done
inc eax ; check if we got any data
jz .done ; TODO: handle errors!
dec eax
jz .done ; TODO: check for errors!
jz .disconnected
 
; ok we have data, now feed it to the recoder
 
226,7 → 225,7
mov edi, servercommand
.byteloop:
call get_next_byte ; reads byte from [esi] to al
jnc .nextpacket ; if CF is set, we need more data
jnc .nextpacket ; if CF is set, we need more data (TODO: dont throw away old data!!!)
cmp al, 10
je .got_command
cmp al, 13
245,5 → 244,15
 
.done:
popa
ret
 
 
.disconnected:
mov esi, str_disconnected
call print_text2
 
mov [status], STATUS_DISCONNECTED
mcall close, [socketnum]
 
popa
ret
/programs/network/ircc/userparser.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
18,7 → 18,7
 
mov eax, [edit1.size]
test eax, eax
jz sdts_ret ; ignore empty commands
jz .ret ; ignore empty commands
mov word [usercommand + eax], 0x0a0d ; terminate the line
 
cmp byte[usercommand], '/' ; is it a server command ?
26,7 → 26,7
 
; Ignore data commands when not connected.
cmp [status], STATUS_CONNECTED
jne sdts_ret
jne .notconnected
 
; Ok, we said something, print it to our textbox
; TODO: dont send if it's a server window?
86,9 → 86,14
 
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
.ret:
 
sdts_ret:
ret
 
.notconnected:
mov esi, str_notconnected
call print_text2
 
ret
 
 
100,7 → 105,9
dd 'help', cmd_usr_help
dd 'code', cmd_usr_code
 
; All following commands require a connection to the server. TODO: verify connection
.number2 = ($ - user_commands) / 8
 
; All following commands require a connection to the server.
dd 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit
dd 'part', cmd_usr_part
113,11 → 120,14
 
server_command:
 
mov eax, dword[usercommand+1]
or eax, 0x20202020
mov eax, dword[usercommand+1] ; skip '/'
or eax, 0x20202020 ; convert to lowercase
 
mov edi, user_commands
mov ecx, user_commands.number
cmp [status], STATUS_CONNECTED
jne .loop
mov ecx, user_commands.number2
.loop:
scasd
je .got_cmd
124,12 → 134,20
add edi, 4
dec ecx
jnz .loop
 
cmp [status], STATUS_CONNECTED
jne .notconnected
 
jmp cmd_usr_send ; If none of the previous commands, just send to server
 
.got_cmd:
jmp dword[edi]
 
.notconnected:
mov esi, str_notconnected
call print_text2
 
ret
 
 
 
345,11 → 363,19
sub ecx, 8
 
mov esi, usercommand+8
.now:
push esi
mov edi, irc_server_name
rep movsb
.loop: ; copy until zero byte, or ecx reaches zero.
lodsb
stosb
test al, al
jz .done
dec ecx
jnz .loop
xor al, al
stosb
.done:
pop esi
 
; set it also in window name
364,32 → 390,9
 
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.type], WINDOWTYPE_CHAT
 
mov esi, usercommand+7
call window_set_name
call window_open
 
 
.error:
 
ret
 
 
470,6 → 473,7
ret
 
 
 
cmd_usr_ctcp:
 
cmp byte[usercommand+5], ' '
527,6 → 531,7
ret
 
 
 
; The user typed some undefined command, just recode it and send to the server
cmd_usr_send:
 
/programs/network/ircc/window.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
10,11 → 10,15
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; window_create_textbox
; Initialises the data structure for our multiline textbox
;
; in: window ptr in ebx
; out: eax = 0 on error
window_create:
; ecx, edi = destroyed
 
window_create_textbox:
 
push ebx
; allocate the window data block
mcall 68, 12, sizeof.window_data
47,24 → 51,22
ret
 
 
window_set_name: ; esi = ptr to name, ebx = window ptr
; window_set_name
; Fills in the window name in window structure
;
; IN: esi = ptr to name
; ebx = window ptr
; OUT: esi = ptr to next parameter
; ebx = window ptr
; eax, ecx, edx, edi = destroyed
 
pusha
window_set_name:
 
; 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, 0x21
cmp al, 0x21 ; name ends with 0, space or !
jbe .addzero
stosb
dec ecx
73,10 → 75,10
xor al, al
stosb
 
call draw_windowtabs ; redraw it
push esi ebx
call draw_windowtabs
pop ebx esi
 
popa
 
ret
 
 
133,11 → 135,16
ret
 
 
; window_find:
; search for a window with given name in the window list
;
; IN: esi = ptr to start of window name
; OUT: ebx = window ptr, or 0 if none found
; esi = ptr to end of window name, if window was found
 
window_find: ; esi = window name
; search for window in list
window_find:
 
mov ebx, windows
mov [window_print], ebx ; set first window (server window) as default output window
mov eax, MAX_WINDOWS
.scanloop:
push esi
146,16 → 153,12
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
repe cmpsb
cmp byte[edi-1], 0
cmp byte[edi-1], 0 ; last equall character was null? yes, the strings match!
je .got_it
cmp byte[edi], 0 ; we're at the end of string1.. ?
jne .try_next
cmp byte[esi-1], 0
je .got_it
cmp byte[esi-1], 10
je .got_it
cmp byte[esi-1], 13
je .got_it
cmp byte[esi-1], ' '
je .got_it
cmp byte[esi], 0x21 ; and the end of string2? yes!
jbe .got_it
.try_next:
pop esi
add ebx, sizeof.window
166,33 → 169,31
ret
 
.got_it:
pop esi ;;; TODO: dont reset ESI ?
mov [window_print], ebx
add esp, 4
ret
 
 
 
 
 
 
; window_open:
; open a window with a given name, if it does not exist, create it
; This procedure only affects window_print ptr, not window_active!
;
; esi = ptr to ASCIIZ windowname
; IN: esi = ptr to ASCIIZ windowname
; OUT: esi = ptr to next parameter
 
window_open:
 
push esi
; Skip heading spaces
lodsb
cmp al, ' '
je window_open
cmp al, ':'
je window_open
dec esi
 
mov edi, esi
call compare_to_nick
jne .nochat
 
mov esi, servercommand+1
.nochat:
 
call window_find
test ebx, ebx
jne .got_it
jnz .got_it
 
; create channel window - search for empty slot
.create_it:
199,45 → 200,31
mov ebx, windows
mov ecx, MAX_WINDOWS
.scanloop2:
cmp [ebx + window.data_ptr], 0
cmp [ebx + window.type], WINDOWTYPE_NONE
je .free_found
add ebx, sizeof.window
dec ecx
jnz .scanloop2
; Error: no more available windows!
jmp .got_it ; TODO: return error
jmp .error
 
.free_found:
call window_create
call window_create_textbox
test eax, eax
jz .got_it ; TODO: return error
jz .error
mov [ebx + window.type], WINDOWTYPE_CHAT ; FIXME: let caller handle this ?
 
call window_set_name
mov [window_print], ebx
 
call draw_windowtabs
 
.got_it:
pop esi
.skip1:
; skip text
lodsb
test al, al
jz .quit
cmp al, ' '
jne .skip1
dec esi
; now skip trailing spaces and semicolons
.skip2:
lodsb
test al, al
jz .quit
cmp al, ' '
je .skip2
je .got_it
cmp al, ':'
je .skip2
je .got_it
dec esi
 
.quit:
mov [window_print], ebx
ret
 
.error: ; TODO: return error?
ret