IRCC: better chat support, some bugfixes, some new bugs

git-svn-id: svn://kolibrios.org@3981 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-10-07 14:02:05 +00:00
parent 4b110267ea
commit 26381ac6e6
9 changed files with 348 additions and 145 deletions

View File

@ -220,8 +220,7 @@ print_character:
mov [pos], eax
newdata:
mov eax, [window_print]
or [eax + window.flags], FLAG_UPDATED
call window_is_updated
popa
ret

View File

@ -1,3 +1,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
draw_window:
pusha
@ -47,7 +59,7 @@ draw_window:
mov ecx, TOP_Y SHL 16 + TOP_Y
mcall
mov edi, [window_open]
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .not_channel
@ -81,8 +93,7 @@ draw_window:
call [edit_box_draw]
; tabs
call draw_windownames
call draw_windowtabs
popa
ret
@ -93,7 +104,7 @@ redraw_channel_list:
; First, calculate scrollbar
mov ebx, [window_open]
mov ebx, [window_active]
mov eax, [ebx + window.users] ; number of users in the open window
mov [scroll1.max_area], eax
@ -138,7 +149,6 @@ redraw_channel_list:
print_channel_list:
pusha
; Now, draw the usernames themselves
; first, draw an invisible button
mov ebx, [xsize]
@ -149,21 +159,21 @@ print_channel_list:
mov ecx, [ysize]
add ecx, TEXT_Y shl 16 - (TEXT_Y + 15) ;;;;; + 10???
push ecx ebx
mov edx, 50 + 1 shl 29 + 1 shl 30
mov edx, WINDOW_BTN_LIST + 1 shl 29 + 1 shl 30
mcall 8
; now draw rectangle to clear the names
; draw rectangle to clear previously printed names
pop ebx ecx
mov edx, [colors.work]
mcall 13
; now draw the names according with scrollbar position and window size
; now draw the names according to the scrollbar position and window size
mov eax, [scroll1.position]
xor edx, edx
mov ecx, MAX_NICK_LEN
mul ecx
mov edx, eax
mov eax, [window_open]
mov eax, [window_active]
mov ebp, [eax + window.selected]
add edx, [eax + window.data_ptr]
sub ebp, [scroll1.position]
@ -269,12 +279,17 @@ draw_channel_text:
pop ecx
loop .dct
mov eax, [window_active]
and [eax + window.flags], not FLAG_UPDATED ; clear the 'window is updated' flag
popa
ret
draw_windownames:
draw_windowtabs:
; Create the buttons
mov eax, 8
mov ebx, 5 shl 16 + 120
@ -283,7 +298,7 @@ draw_windownames:
mov edi, windows
.more_btn:
mov esi, [colors.work_button]
cmp [window_open], edi
cmp [window_active], edi
jne @f
not esi
and esi, 0x00ffffff
@ -295,22 +310,48 @@ draw_windownames:
cmp [edi + window.data_ptr], 0
jne .more_btn
; Draw the windownames onto the buttons
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
mov edi, windows
.more:
mov ecx, [colors.work_button_text]
test [edi + window.flags], FLAG_UPDATED
jz @f
mov ecx, 0x00aa0000 ; RED!
@@:
or ecx, 0x80000000 ; ASCIIZ string
lea edx, [edi + window.name]
mcall
add edx, sizeof.window
cmp byte[edx], 0
add edi, sizeof.window ; get ptr to next window
cmp [edi + window.data_ptr], 0
je .enough
add ebx, 125 shl 16
dec esi
jnz .more
.enough:
; Draw the close window button
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_SERVER ; dont let the user close server window
je @f
mov eax, 8
mov ebx, [xsize]
sub ebx, 12
shl ebx, 16
mov bx, 12
mov ecx, 6 shl 16 + 12
mov edx, WINDOW_BTN_CLOSE
; mov esi, [colors.work_button]
mov esi, 0x00aa0000 ; red !
mcall
@@:
ret

View File

@ -66,6 +66,8 @@ TIMESTAMP = 3 ; 3 = hh:mm:ss, 2 = hh:mm, 0 = no timestamp
MAX_WINDOWNAME_LEN = 256
WINDOW_BTN_START = 100
WINDOW_BTN_CLOSE = 2
WINDOW_BTN_LIST = 3
SCROLLBAR_WIDTH = 12
@ -126,7 +128,7 @@ 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+EVM_MOUSE_FILTER
mcall 40, EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_STACK+EVM_MOUSE+EVM_MOUSE_FILTER
; load libraries
stdcall dll.Load, @IMPORT
@ -182,12 +184,13 @@ START:
; 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
invoke ini.get_str, path, str_user, str_quitmsg, quit_msg, 250, default_quit
; Welcome user
mov esi, str_welcome
call print_text2
call draw_window ;;; FIXME (gui is not correctly drawn first time)
call draw_window ;;; FIXME (gui is not correctly drawn first time because of window sizes)
redraw:
call draw_window
@ -211,7 +214,7 @@ still:
call process_network_event
mov edx, [window_open]
mov edx, [window_active]
test [edx + window.flags], FLAG_UPDATED
jz .no_update
and [edx + window.flags], not FLAG_UPDATED
@ -226,14 +229,23 @@ still:
button:
mcall 17 ; get id
shr eax, 8
ror eax, 8
cmp ax, 1 ; close program
je exit
cmp ax, 50
cmp ax, WINDOW_BTN_CLOSE
jne @f
call window_close
jmp still
@@:
cmp ax, WINDOW_BTN_LIST
jne @f
push eax
mcall 37, 1 ; Get mouse position
sub ax, TEXT_Y
mov bl, 10
@ -241,11 +253,27 @@ button:
and eax, 0x000000ff
inc eax
add eax, [scroll1.position]
mov ebx, [window_open]
mov ebx, [window_active]
mov [ebx + window.selected], eax
call print_channel_list
pop eax
test eax, 1 shl 25 ; Right mouse button pressed?
jz still
; Right mouse BTN was pressed, open chat window
mov ebx, [window_active]
mov eax, [ebx + window.selected]
dec eax
imul eax, MAX_NICK_LEN
mov ebx, [ebx + window.data_ptr]
lea esi, [ebx + window_data.names + eax]
call window_open
push [window_print]
pop [window_active]
call redraw
jmp still
@@:
@ -262,12 +290,20 @@ button:
add edx, windows
cmp [edx + window.data_ptr], 0
je exit
mov [window_open], edx
mov [window_active], edx
call window_refresh
call draw_window
jmp still
exit:
cmp [socketnum], 0
je @f
mov esi, quit_msg
call cmd_usr_quit_server
@@:
mcall -1
@ -290,7 +326,7 @@ main_window_key:
push dword edit1
call [edit_box_draw]
mov edx, [window_open]
mov edx, [window_active]
mov edx, [edx + window.data_ptr]
add edx, window_data.text
call draw_channel_text
@ -348,9 +384,11 @@ 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
default_nick db 'kolibri_user', 0
default_real db 'Kolibri User', 0
default_quit db 'KolibriOS forever', 0
str_welcome db 10
db ' ______________________ __ __ __',10
@ -397,7 +435,7 @@ irc_data dd 0x0 ; encoder
textbox_width dd 80 ; in characters, not pixels ;)
pos dd 66 * 11 ; encoder
window_open dd windows
window_active dd windows
window_print dd windows
scroll dd 1
@ -460,6 +498,7 @@ irc_server_name rb MAX_SERVER_NAME
user_nick rb MAX_NICK_LEN
user_real_name rb MAX_REAL_LEN
quit_msg rb 250
windows rb MAX_WINDOWS*sizeof.window

View File

@ -1,6 +1,7 @@
[user]
nick = kolibri_user
realname = tetten
partmsg = KolibriOS forever
[colors]
action1 = 0x000000aa

View File

@ -134,100 +134,6 @@ skip_nick:
ret
align 4
find_window: ; esi is ptr to windowname
push esi
mov edi, esi
call compare_to_nick
jne .nochat
mov esi, servercommand+1
.nochat:
; now search for window in list
mov ebx, windows
mov [window_print], ebx ; set first window (server window) as default output window
.scanloop:
cmp [ebx + window.data_ptr], 0
je .create_it
push esi
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
repe cmpsb
pop esi
cmp byte[edi-1], 0
je .got_it
add ebx, sizeof.window
; TODO: check buffer limits ?
jmp .scanloop
; create channel window - search for empty slot
.create_it:
mov ebx, windows
mov ecx, MAX_WINDOWS
.scanloop2:
cmp [ebx + window.data_ptr], 0
je .free_found
add ebx, sizeof.window
dec ecx
jnz .scanloop2
; Error: no more available windows!
jmp .just_skip
.free_found:
push ebx
call window_create
pop ebx
test eax, eax
jz .just_skip
mov [ebx + window.data_ptr], eax
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
call window_set_name
mov [window_open], ebx
mov [window_print], ebx
call window_refresh
call draw_windownames
jmp .just_skip
; found it!
.got_it:
mov [window_print], ebx
call window_refresh
.just_skip:
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
cmp al, ':'
je .skip2
dec esi
.quit:
ret
cmd_328:
cmd_421:
@ -307,7 +213,7 @@ cmd_ping:
cmd_privmsg:
add esi, 8 ; skip 'PRIVMSG '
call find_window ; esi now points to end of destination name
call window_open ; esi now points to end of destination name
cmp byte[esi], 1
je cmd_ctcp
@ -368,6 +274,8 @@ end if
ret
cmd_ctcp:
inc esi
@ -520,7 +428,7 @@ cmd_part:
add esi, 5 ; skip 'PART '
push esi
call skip_nick
call find_window
call window_open
pop esi
; Is it me who parted?
@ -595,7 +503,7 @@ cmd_join:
call window_set_name
mov [window_open], ebx
mov [window_active], ebx
mov [window_print], ebx
call window_refresh
@ -619,7 +527,7 @@ cmd_join:
.no_new_window:
push esi
call find_window
call window_open
mov esi, action_header
call print_text2
@ -726,7 +634,7 @@ cmd_kick:
; find the channel user has been kicked from
push esi
call skip_nick
call find_window
call window_open
mov esi, action_header_short
call print_text2
@ -806,7 +714,7 @@ cmd_353: ; channel usernames reply
call skip_nick
inc esi ; channel type '*', '=' or '@'
inc esi ; ' '
call find_window
call window_open
; now find window ptr and check if this is the first 353 message
mov ebx, [window_print]
@ -843,7 +751,7 @@ cmd_366: ; channel usernames end
add esi, 4 ; skip '366 '
call skip_nick
call find_window
call window_open
mov ebx, [window_print]
and [ebx + window.flags], not FLAG_RECEIVING_NAMES
@ -857,7 +765,7 @@ cmd_topic:
add esi, 4 ; skip '332 '
call skip_nick
call find_window
call window_open
push esi
mov esi, action_header
@ -879,7 +787,7 @@ cmd_333:
add esi, 4 ; skip '333 '
call skip_nick ;;;;
call find_window
call window_open
; mov ecx, 2 ; number of spaces to find ;;; CHECKME
; .loop:

View File

@ -111,7 +111,7 @@ socket_write_userinfo:
dec ecx
jnz .loop
.done:
mov ax, 0x0d0a
mov ax, 0x0a0d
stosw
mov eax, 'USER'
@ -144,7 +144,7 @@ socket_write_userinfo:
dec ecx
jnz .loop3
.done3:
mov ax, 0x0d0a
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf]

View File

@ -28,7 +28,7 @@ user_parser:
; TODO: dont send if it's a server window?
push [window_open] ; print to the current window
push [window_active] ; print to the current window
pop [window_print]
call window_refresh
@ -42,9 +42,9 @@ user_parser:
mov esi, user_nick
call print_text2
mov bl,'>'
mov bl, '>'
call print_character
mov bl,' '
mov bl, ' '
call print_character
mov eax, [edit1.size]
@ -61,7 +61,7 @@ user_parser:
mov dword[packetbuf], 'priv'
mov dword[packetbuf+4], 'msg '
mov esi, [window_open]
mov esi, [window_active]
add esi, window.name
mov edi, packetbuf+8
mov ecx, MAX_WINDOWNAME_LEN
@ -103,6 +103,7 @@ user_commands:
; TODO: All other commands require a connection to the server.
dd 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit
dd 'part', cmd_usr_part
.number = ($ - user_commands) / 8
@ -132,14 +133,13 @@ server_command:
cmd_usr_quit:
cmp [edit1.size], 5
je .ok
jb cmd_usr_send
cmp byte[usercommand+5], ' '
jne cmd_usr_send
mov esi, quit_msg
.ok:
call cmd_usr_send
cmp byte[usercommand+5], ' '
jne .default_msg
lea esi,[usercommand+6]
.default_msg:
call cmd_usr_quit_server
mcall close, [socketnum]
@ -155,6 +155,31 @@ cmd_usr_quit:
; esi = quit message
cmd_usr_quit_server:
; User wants to close a channel, send PART command to server
mov dword[packetbuf], 'QUIT'
mov word[packetbuf+4], ' :'
lea edi, [packetbuf+6]
; Append our quit msg
@@:
lodsb
stosb
test al, al
jnz @r
; end the command with a CRLF
dec edi
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
ret
cmd_usr_nick:
@ -305,6 +330,46 @@ cmd_usr_code:
; User typed a part command
cmd_usr_part:
cmp byte[usercommand+5], 13 ; parameters given?
jne cmd_usr_send
mov esi, [window_active] ; window is not a server window?
cmp [esi + window.type], WINDOWTYPE_SERVER
je @f
call window_close ; OK, close currently open (channel/chat/..) window
@@:
ret
; Send part command to server
; esi must point to channel name (ASCIIZ)
cmd_usr_part_channel:
; User wants to close a channel, send PART command to server
mov dword[packetbuf], 'PART'
mov byte[packetbuf+4], ' '
lea edi, [packetbuf+5]
@@:
lodsb
stosb
test al, al
jnz @r
; end the command with a CRLF
dec edi
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
ret
; The user typed some undefined command, just recode it and send to the server
cmd_usr_send:
mov esi, usercommand+1

View File

@ -1,3 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; esi is ptr to nick

View File

@ -55,7 +55,7 @@ window_set_name: ; esi = ptr to name, ebx = window ptr
xor al, al
stosb
call draw_windownames ; redraw it
call draw_windowtabs ; redraw it
popa
@ -78,7 +78,8 @@ window_refresh:
ret
window_updated:
window_is_updated:
mov edi, [window_print]
test [edi + window.flags], FLAG_UPDATED
@ -88,11 +89,150 @@ window_updated:
; now play a sound :)
call draw_windowtabs ; highlight updated tabs
.skip:
ret
window_close:
; If current window is a channel, send part command to server
mov esi, [window_active]
cmp [esi + window.type], WINDOWTYPE_CHANNEL
jne .not_channel
lea esi, [esi + window.name]
call cmd_usr_part_channel
.not_channel:
; Remove the window (overwrite current structure with trailing ones)
mov edi, [window_active]
push [edi + window.data_ptr] ; remember data ptr so we can free it later
lea esi, [edi + sizeof.window]
mov ecx, windows + MAX_WINDOWS*sizeof.window
sub ecx, esi
rep movsb
; Completely zero the trailing window block (there will always be one!)
mov ecx, sizeof.window
xor al, al
rep stosb
; free the window data block
pop ecx
mcall 68, 13
; We closed this window so we need to show another
mov edi, [window_active]
cmp [edi + window.data_ptr], 0
jne @f
sub edi, sizeof.window
mov [window_active], edi
mov [window_print], edi
@@:
; At last, redraw everything
call draw_window
ret
; 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
window_open:
push esi
mov edi, esi
call compare_to_nick
jne .nochat
mov esi, servercommand+1
.nochat:
; now search for window in list
mov ebx, windows
mov [window_print], ebx ; set first window (server window) as default output window
.scanloop:
cmp [ebx + window.data_ptr], 0
je .create_it
push esi
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
repe cmpsb
pop esi
cmp byte[edi-1], 0
je .got_it
add ebx, sizeof.window
; TODO: check buffer limits ?
jmp .scanloop
; create channel window - search for empty slot
.create_it:
mov ebx, windows
mov ecx, MAX_WINDOWS
.scanloop2:
cmp [ebx + window.data_ptr], 0
je .free_found
add ebx, sizeof.window
dec ecx
jnz .scanloop2
; Error: no more available windows!
jmp .just_skip
.free_found:
push ebx
call window_create
pop ebx
test eax, eax
jz .just_skip
mov [ebx + window.data_ptr], eax
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
call window_set_name
mov [window_print], ebx
call window_refresh
call draw_windowtabs
jmp .just_skip
; found it!
.got_it:
mov [window_print], ebx
call window_refresh
.just_skip:
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
cmp al, ':'
je .skip2
dec esi
.quit:
ret
print_text: ; eax = start ptr
; dl = end char
pusha