Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4101 → Rev 4143

/programs/network/ircc/encodings.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by CleverMouse ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
/programs/network/ircc/gui.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
10,8 → 11,9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
draw_window:
 
draw_window: ; Completely redraw the window, recalculate all coordinates and sizes
 
pusha
 
mcall 9, thread_info, -1 ; get current window size
37,6 → 39,12
add esi, ebx
mcall 67, -1, -1 ; set the new sizes
 
popa
 
.dont_resize:
 
pusha
 
mcall 12, 1
xor eax, eax ; draw window
mov ebx, WIN_MIN_X
49,39 → 57,76
 
mov ebx, [xsize]
mov ecx, [ysize]
sub cx, 15 ;;;;
sub cx, BOTTOM_Y ;;;;
push cx
shl ecx, 16
pop cx
mov edx, [colors.work_graph]
mcall 38 ; draw line
 
mcall 38 ; draw bottom line
mov ecx, TOP_Y SHL 16 + TOP_Y
mcall
mcall ; draw top line
 
; calculate available space for textbox and coordinates for scrollbars
mov eax, [ysize]
sub eax, TOP_Y + BOTTOM_Y - 1 ;;;;
mov [scroll2.y_size], ax
mov [scroll1.y_size], ax
sub eax, 4 ;;;;
xor edx, edx
mov ecx, FONT_HEIGHT
div ecx
mov [textbox_height], eax
mov [scroll2.cur_area], eax
mov [scroll1.cur_area], eax
 
mov eax, [xsize]
sub eax, SCROLLBAR_WIDTH
mov [scroll1.x_pos], ax
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne @f
sub eax, USERLIST_WIDTH + SCROLLBAR_WIDTH + 2
@@:
mov [scroll2.x_pos], ax
sub eax, 10
xor edx, edx
mov ecx, FONT_WIDTH
div ecx
mov [textbox_width], eax
 
; recalculate text line breaks (because height/width might have changed..)
mov edi, [window_active]
mov esi, [edi + window.text_start]
call text_insert_newlines
mov [edi + window.text_lines], edx
mov [edi + window.text_scanned], esi
 
; and redraw the textbox (and scrollbar if needed)
mov [scroll2.all_redraw], 1
call draw_channel_text
 
; Draw userlist if active window is a channel
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .not_channel
 
; draw a vertical separator line
; TODO: dont draw this if we draw textbox scrollbar ??
mov ebx, [xsize]
sub ebx, USERLIST_X + SCROLLBAR_WIDTH + 3
sub ebx, USERLIST_WIDTH + SCROLLBAR_WIDTH + 3
push bx
shl ebx, 16
pop bx
mov ecx, [ysize]
add ecx, TOP_Y SHL 16 -(15) ;;;;
mcall
add ecx, TOP_Y SHL 16 -(BOTTOM_Y) ;;;;
mov edx, [colors.work_graph]
mcall 38
 
call redraw_channel_list
 
mov [scroll1.all_redraw], 1
call draw_channel_list
.not_channel:
mov edx, [edi + window.data_ptr]
add edx, window_data.text
call draw_channel_text
 
; editbox
 
; draw editbox
mov eax, [ysize]
sub eax, 12 ;;;;;;
mov [edit1.top], eax
92,7 → 137,7
push dword edit1
call [edit_box_draw]
 
; tabs
; draw tabs
call draw_windowtabs
 
popa
100,31 → 145,15
 
 
 
redraw_channel_list:
draw_channel_list:
 
; First, calculate scrollbar
pusha
 
; Do we need a scrollbar?
mov ebx, [window_active]
mov eax, [ebx + window.users] ; number of users in the open window
mov eax, [ebx + window.users]
mov [scroll1.max_area], eax
 
mov eax, [ysize]
sub eax, TOP_Y + 15 ;;;;
push eax
mov [scroll1.y_size], ax
 
mov eax, [xsize]
sub eax, SCROLLBAR_WIDTH
mov [scroll1.x_pos], ax
 
pop eax ; scrollbar height
xor edx, edx
mov ecx, 10
div ecx
mov [scroll1.cur_area], eax
 
; Do we need a scrollbar?
cmp eax, [scroll1.max_area]
cmp [scroll1.cur_area], eax
jae .noscroll
 
; Is the current position greater then the max position?
132,42 → 161,37
ja @f
mov [scroll1.position], eax
@@:
 
; OK, draw the scrollbar
mov [scroll1.all_redraw], 1
 
push dword scroll1
call [scrollbar_v_draw]
call [scrollbar_draw]
 
jmp print_channel_list
; dont redraw scrollbar completely next time,
; unless draw_window asks us to by setting [scroll1.all_redraw] back to 1
mov [scroll1.all_redraw], 0
jmp .scroll_done
 
.noscroll:
mov [scroll1.position], 0
.scroll_done:
 
 
 
print_channel_list:
 
pusha
 
; first, draw an invisible button
; draw an invisible button, where the usernames will go
mov ebx, [xsize]
sub ebx, USERLIST_X + SCROLLBAR_WIDTH
sub ebx, USERLIST_WIDTH + SCROLLBAR_WIDTH
shl ebx, 16
push ebx
mov bx, USERLIST_X
mov bx, USERLIST_WIDTH
mov ecx, [ysize]
add ecx, TEXT_Y shl 16 - (TEXT_Y + 15) ;;;;; + 10???
add ecx, TEXT_Y shl 16 - (TEXT_Y + 16)
push ecx ebx
mov edx, WINDOW_BTN_LIST + 1 shl 29 + 1 shl 30
mcall 8
 
; draw rectangle to clear previously printed names
; draw a filled rectangle to clear previously printed names
pop ebx ecx
mov edx, [colors.work]
mcall 13
 
; now draw the names according to the 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
185,8 → 209,7
or ecx, 0x80000000 ; ASCIIZ string
mov eax, 4 ; draw text
 
mov edi, [ysize] ; Calculate how many names will fit on screen
sub edi, TEXT_Y + 15 ;+ 10 ;;;;;
mov edi, [textbox_height] ; how many names will fit on screen
.loop:
cmp byte[edx], 0 ; end of list?
je .done
196,7 → 219,7
; yes, highlight it
pusha
mov cx, bx
mov bx, USERLIST_X
mov bx, USERLIST_WIDTH
shl ecx, 16
mov cx, 10 - 1
mov edx, 0x00000055 ; blue!
214,10 → 237,10
mcall
 
.next:
add edx, MAX_NICK_LEN ; next name
add ebx, 10 ; height distance between lines
sub edi, 10
ja .loop
add edx, MAX_NICK_LEN
add ebx, FONT_HEIGHT
dec edi
jnz .loop
 
.done:
popa
/programs/network/ircc/ircc.asm
13,7 → 13,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
version equ '0.1'
version equ '0.15'
 
; connection status
STATUS_DISCONNECTED = 0
23,15 → 23,15
 
; window flags
FLAG_UPDATED = 1 shl 0
FLAG_CLOSE = 1 shl 1
FLAG_RECEIVING_NAMES = 1 shl 2
FLAG_RECEIVING_NAMES = 1 shl 1
 
; window types
WINDOWTYPE_SERVER = 0
WINDOWTYPE_CHANNEL = 1
WINDOWTYPE_CHAT = 2
WINDOWTYPE_LIST = 3
WINDOWTYPE_DCC = 4
WINDOWTYPE_NONE = 0
WINDOWTYPE_SERVER = 1
WINDOWTYPE_CHANNEL = 2
WINDOWTYPE_CHAT = 3
WINDOWTYPE_LIST = 4
WINDOWTYPE_DCC = 5
 
; supported encodings
CP866 = 0
42,15 → 42,17
USERCMD_MAX_SIZE = 400
 
WIN_MIN_X = 600
WIN_MIN_Y = 165
WIN_MIN_Y = 170
 
TEXT_X = 5
TEXT_Y = 30
TEXT_Y = TOP_Y + 2
 
TOP_Y = 25
TOP_Y = 24
BOTTOM_Y = 15
 
MAX_WINDOWS = 20
MAX_USERS = 4096
TEXT_BUFFERSIZE = 4096;*1024
 
MAX_NICK_LEN = 32
MAX_REAL_LEN = 32 ; realname
69,12 → 71,12
WINDOW_BTN_CLOSE = 2
WINDOW_BTN_LIST = 3
 
SCROLLBAR_WIDTH = 12
SCROLLBAR_WIDTH = 14
USERLIST_WIDTH = 100
 
USERLIST_X = 98
FONT_HEIGHT = 9
FONT_WIDTH = 6
 
TEXTBOX_LINES = 12
 
format binary as ""
 
use32
98,7 → 100,7
include '../../develop/libraries/box_lib/trunk/box_lib.mac'
 
struct window
data_ptr dd ? ; zero if not used
data_ptr dd ?
flags db ?
type db ?
name rb MAX_WINDOWNAME_LEN
105,18 → 107,24
users dd ?
users_scroll dd ?
selected dd ? ; selected user, 0 if none selected
 
text_start dd ? ; pointer to current textbox data
text_end dd ?
text_print dd ? ; pointer to first character to print on screen
text_line_print dd ? ; line number of that character
text_write dd ? ; write pointer
text_lines dd ? ; total number of lines
text_scanned dd ? ; pointer to beginning of unscanned data (we still need to count number of lines, insert newline characters,..)
 
ends
 
struct window_data
text rb 120*60
title rb 256
text rb TEXT_BUFFERSIZE
names rb MAX_NICK_LEN * MAX_USERS
usertext rb 256
usertextlen dd ?
ends
 
include "encodings.inc"
include "window.inc" ; also contains text print routines
include "window.inc"
include "serverparser.inc"
include "userparser.inc"
include "socket.inc"
160,14 → 168,12
rep stosd
 
; allocate window data block
mov ebx, windows
call window_create
mov ebx, windows
mov [ebx + window.data_ptr], eax
mov [ebx + window.flags], 0
test eax, eax
jz error
mov [ebx + window.type], WINDOWTYPE_SERVER
 
call window_refresh
 
; get system colors
mcall 48, 3, colors, 40
 
174,13 → 180,19
; set edit box and scrollbar colors
mov eax, [colors.work]
mov [scroll1.bg_color], eax
mov [scroll2.bg_color], eax
 
mov eax, [colors.work_button]
mov [scroll1.front_color], eax
mov [scroll2.front_color], eax
 
mov eax, [colors.work_text]
mov [scroll1.line_color], eax
mov [scroll2.line_color], eax
 
mov [scroll1.type], 1 ; 0 = simple, 1 = skinned
mov [scroll2.type], 1
 
; 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
190,13 → 202,12
mov esi, str_welcome
call print_text2
 
call draw_window ;;; FIXME (gui is not correctly drawn first time because of window sizes)
call draw_window ; Draw window a first time, so we can figure out skin size
 
redraw:
call draw_window
 
still:
 
; wait here for event
mcall 10
 
214,15 → 225,15
 
call process_network_event
 
mov edx, [window_active]
test [edx + window.flags], FLAG_UPDATED
mov edi, [window_active]
test [edi + 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
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .no_update
call draw_channel_list
.no_update:
call print_channel_list
 
jmp still
 
236,8 → 247,7
 
cmp ax, WINDOW_BTN_CLOSE
jne @f
 
call window_close
call cmd_usr_close_window
jmp still
 
@@:
248,7 → 258,7
 
mcall 37, 1 ; Get mouse position
sub ax, TEXT_Y
mov bl, 10
mov bl, FONT_HEIGHT
div bl
and eax, 0x000000ff
inc eax
256,7 → 266,7
mov ebx, [window_active]
mov [ebx + window.selected], eax
 
call print_channel_list
call draw_channel_list
 
pop eax
test eax, 1 shl 25 ; Right mouse button pressed?
283,15 → 293,17
cmp ax, MAX_WINDOWS
ja exit
 
; OK, time to switch to another window.
mov dx, sizeof.window
mul dx
shl edx, 16
mov dx, ax
add edx, windows
cmp [edx + window.data_ptr], 0
cmp [edx + window.type], WINDOWTYPE_NONE
je exit
mov [window_active], edx
call window_refresh
 
mov [scroll2.position], 1 ;;; FIXME
call draw_window
 
jmp still
304,6 → 316,8
call cmd_usr_quit_server
@@:
 
error:
 
mcall -1
 
 
315,11 → 329,26
push dword edit1
call [edit_box_key]
 
; cmp ah, 178
; jne .no_up
;
; jmp still
;
;
; .no_up:
; cmp ah, 177
; jne .no_down
;
; jmp still
;
; .no_down:
cmp ah, 13 ; enter
jne no_send2
 
call user_parser
 
mov eax, [edit1.size]
 
mov [edit1.size], 0
mov [edit1.pos], 0
 
326,9 → 355,6
push dword edit1
call [edit_box_draw]
 
mov edx, [window_active]
mov edx, [edx + window.data_ptr]
add edx, window_data.text
call draw_channel_text
 
jmp still
340,16 → 366,33
push dword edit1
call [edit_box_mouse]
 
; TODO: check if scrollbar is active
; TODO: check if scrollbar is active?
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne @f
push [scroll1.position]
push dword scroll1
call [scrollbar_v_mouse]
call [scrollbar_mouse]
pop eax
cmp eax, [scroll1.position] ; did the scrollbar move?
je @f
call print_channel_list
call draw_channel_list
@@:
 
; TODO: check if scrollbar is active?
mov edi, [window_active]
mov eax, [edi + window.text_lines]
cmp eax, [textbox_height]
jbe @f
push dword scroll2
call [scrollbar_mouse]
; mov edi, [window_active]
mov edx, [scroll2.position]
sub edx, [edi + window.text_line_print]
je @f
call draw_channel_text.scroll_to_pos
@@:
 
jmp still
 
 
361,9 → 404,16
db 'UTF-8 '
encoding_text_len = 6
 
action_header db '*** ', 0
action_header_short db '* ', 0
ctcp_header db '-> [',0
join_header db 3,'3* ', 0
quit_header db 3,'5* ', 0
nick_header db 3,'2* ', 0
kick_header db 3,'5* ', 0
mode_header db 3,'2* ', 0
part_header db 3,'5* ', 0
topic_header db 3,'3* ', 0
action_header db 3,'6* ', 0
ctcp_header db 3,'13-> [',0
msg_header db 3,'7-> *',0
ctcp_version db '] VERSION',10,0
ctcp_ping db '] PING',10,0
ctcp_time db '] TIME',10,0
376,6 → 426,7
str_talking db 'Now talking in ',0
str_topic db 'Topic is ',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
390,23 → 441,22
default_real db 'Kolibri User', 0
default_quit db 'KolibriOS forever', 0
 
str_welcome db 10
db ' ______________________ __ __ __',10
db '| \______ \_ ___ \ ____ | | |__| ____ _____/ |_',10
db '| || _/ \ \/ _/ ___\| | | |/ __ \ / \ __\',10
db '| || | \ \____ \ \___| |_| \ ___/| | \ |',10
db '|___||____|_ /\______ / \___ >____/__|\___ >___| /__|',10
db ' \/ \/ \/ \/ \/',10
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 10
db 'Welcome to IRC client ',version,' for KolibriOS',10
db 'Welcome to the KolibriOS IRC client v',version,10
db 10
db 'Type /help for help',10,0
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 10,'* Connecting to ',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
414,7 → 464,7
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_1 db 3,'13 -',0
str_2 db '- ',0
 
str_sockerr db 'Socket Error',10,0
421,6 → 471,23
str_dnserr db 'Unable to resolve hostname.',10,0
str_refused db 'Connection refused',10,0
 
irc_colors dd 0xffffff ; 0 white
dd 0x000000 ; 1 black
dd 0x00007f ; 2 blue (navy)
dd 0x009300 ; 3 green
dd 0xff0000 ; 4 red
dd 0x7f0000 ; 5 brown (maroon)
dd 0x9c009c ; 6 purple
dd 0xfc7f00 ; 7 olive
dd 0xffff00 ; 8 yellow
dd 0x00fc00 ; 9 light green
dd 0x009393 ; 10 teal
dd 0x00ffff ; 11 cyan
dd 0x0000fc ; 12 royal blue
dd 0xff00ff ; 13 pink
dd 0x7f7f7f ; 14 grey
dd 0xd4d0c4 ; 15 light grey (silver)
 
sockaddr1:
dw AF_INET4
.port dw 0x0b1a ; 6667
430,10 → 497,10
 
status dd STATUS_DISCONNECTED
 
text_start dd ? ; pointer to current textbox data
textbox_width dd 80 ; in characters, not pixels ;)
text_pos dd ? ; text writing cursor
 
textbox_height dd 12 ; in characters
textbox_width dd 78 ; in characters, not pixels ;)
 
window_active dd windows
window_print dd windows
 
457,21 → 524,20
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'
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, max, cur, pos, bgcol, frcol, linecol
scroll1 scrollbar SCROLLBAR_WIDTH, 300, 150, TOP_Y, 10, 100, 0, 0, 0, 0, 0, 1
scroll2 scrollbar SCROLLBAR_WIDTH, 300, 150, TOP_Y, 10, 100, 0, 0, 0, 0, 0, 1
; xsize, xpos, ysize, ypos, btn_height, max, cur, pos, bgcol, frcol, linecol
scroll1 scrollbar SCROLLBAR_WIDTH, 0, 0, TOP_Y, SCROLLBAR_WIDTH, 0, 0, 0, 0, 0, 0, 1
scroll2 scrollbar SCROLLBAR_WIDTH, 0, 0, TOP_Y, SCROLLBAR_WIDTH, 0, 0, 0, 0, 0, 0, 1
 
usercommand db '/server chat.freenode.net', 0
rb MAX_COMMAND_LEN
 
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
/programs/network/ircc/serverparser.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
48,7 → 49,9
 
dd '322 ', cmd_322 ; RPL_LIST
dd '323 ', cmd_323 ; RPL_LISTEND
dd '324 ', cmd_324 ;;;;
dd '328 ', cmd_328 ; RPL_CHANNEL_URL
dd '329 ', cmd_329
dd '332 ', cmd_topic
dd '333 ', cmd_333 ; nickname and time of topic
dd '353 ', cmd_353 ; name reply
110,6 → 113,8
pop esi
ret
 
 
 
align 4
skip_nick:
 
135,6 → 140,8
 
 
 
cmd_324:
cmd_329:
cmd_328:
cmd_421:
cmd_372:
149,11 → 156,16
jne .gogogo
 
mov byte [esi-1], 0
if TIMESTAMP
call print_timestamp
end if
 
push esi
mov esi, str_1
call print_text2
mov esi, servercommand+1
call print_text2
mov eax, servercommand+1
mov dl, '!'
call print_text
mov esi, str_2
call print_text2
pop esi
177,12 → 189,11
cmp byte [esi], ':'
je .loop2
 
.fail:
call print_text2
mov esi, str_newline
call print_text2
 
.fail:
 
ret
 
 
212,16 → 223,17
 
cmd_privmsg:
 
mov eax, dword[esi+4]
or eax, 0x20202020
cmp eax, 'msg '
jne .fail
add esi, 8 ; skip 'PRIVMSG '
call window_open ; esi now points to end of destination name
 
cmp byte[esi], 1
cmp byte[esi], 1 ; Client to Client protocol?
je cmd_ctcp
 
cmp dword[esi], 'ACTI' ; Action?
je .action
 
; nope, just plain old privmsg
; nope, just plain old privmsg, print it using '<nick> message' format
if TIMESTAMP
call print_timestamp
end if
249,45 → 261,32
.fail:
ret
 
.action:
add esi, 8
push esi
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
cmd_ctcp:
 
pop esi
call print_text2
 
mov bl, 10
call print_character
 
ret
 
 
 
cmd_ctcp:
cmp byte [esi+4], ' '
jne .fail
inc esi
mov eax, dword[esi]
or eax, 0x20202020
 
cmp dword[esi], 'VERS'
cmp eax, 'vers'
je .version
 
cmp dword[esi], 'TIME'
cmp eax, 'time'
je .time
 
cmp dword[esi], 'PING'
cmp eax, 'ping'
je .ping
cmp eax, 'acti'
je .action
; cmp eax, 'dcc ' ; TODO
; je cmd_dcc
 
; Unknown CTCP command: TODO: just print to window??
 
.fail:
 
ret
 
.time:
375,12 → 374,52
 
ret
 
.action:
add esi, 7
push esi
 
if TIMESTAMP
call print_timestamp
end if
 
mov esi, action_header
call print_text2
 
mov eax, servercommand+1 ; print nickname
mov dl, '!'
call print_text
 
mov bl, ' '
call print_character
 
pop esi
call print_text2 ; print message
 
mov bl, 10
call print_character
 
ret
 
 
cmd_dcc:
add esi, 4
mov eax, dword[esi]
or eax, 0x202020
 
cmp eax, 'send'
je .send
 
ret
 
.send:
 
ret
 
 
 
ctcp_reply:
 
push esi
 
mov dword [usercommand], 'NOTI'
mov dword [usercommand+4], 'CE '
 
425,11 → 464,10
 
 
cmd_part:
 
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'PART '
push esi
call skip_nick
call window_open
pop esi
 
; Is it me who parted?
mov edi, servercommand+1
436,16 → 474,24
call compare_to_nick
jne .dont_close
 
; yes, close the window
mov edi, [window_print]
mov [edi + window.flags], FLAG_UPDATED + FLAG_CLOSE
; yes, close the window (if its open)
call window_find
test ebx, ebx
jz @f
call window_close
@@:
.fail:
 
ret
 
 
; somebody else parted, just print message
.dont_close:
push esi
mov esi, action_header
call skip_nick
call window_open
 
mov esi, part_header
call print_text2
 
mov eax, servercommand+1
471,6 → 517,9
 
 
cmd_join:
 
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'JOIN '
 
; compare nick: did we join a channel?
488,27 → 537,26
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_active], ebx
mov [window_print], ebx
call window_refresh
 
if TIMESTAMP
call print_timestamp
end if
 
push esi
mov esi, action_header
mov esi, join_header
call print_text2
 
mov esi, str_talking
529,7 → 577,11
push esi
call window_open
 
mov esi, action_header
if TIMESTAMP
call print_timestamp
end if
 
mov esi, join_header
call print_text2
 
mov eax, servercommand+1
549,6 → 601,8
mov esi, servercommand+1
call user_add
 
.fail:
 
ret
 
 
555,52 → 609,63
 
 
cmd_nick:
; NOTE: This command applies to a user, and thus has no specific channel
 
cmp byte[esi+4], ' '
jne .fail
add esi, 5 ; skip 'NICK '
 
cmp byte[esi], ':' ; TODO: skip all spaces and semicolons?
cmp byte[esi], ':'
jne @f
inc esi
@@:
 
; Change the nick in the current userlist. TODO: check other channels too!
; Is it me who changed nick?
push esi
mov ebx, [window_print]
 
mov esi, servercommand+1
call user_remove
 
mov esi, [esp]
call user_add
 
call redraw_channel_list
 
; Is it me who changed nick?
mov edi, servercommand+1
call compare_to_nick
pop esi
jne .not_me
 
mov ecx, MAX_NICK_LEN-1
push esi
.copyloop:
mov esi, [esp]
@@:
lodsb
test al, al
jz .copydone
jz @f
cmp al, ' '
je .copydone
je @f
cmp al, 10
je @f
cmp al, 13
je @f
stosb
dec ecx
jnz .copyloop
.copydone:
jnz @r
@@:
xor al, al
stosb
pop esi
.not_me:
 
; Now print a message on the current channel
push esi
mov esi, action_header_short
mov ebx, windows
mov ecx, MAX_WINDOWS
.window_loop:
push ecx ebx
cmp [ebx + window.type], WINDOWTYPE_CHANNEL
jne .next_window
 
mov esi, servercommand+1
call user_remove
test edi, edi
jz .next_window
 
mov esi, [esp + 8]
call user_add
 
mov [window_print], ebx
 
if TIMESTAMP
call print_timestamp
end if
 
mov esi, nick_header
call print_text2
 
mov eax, servercommand+1
610,12 → 675,22
mov esi, is_now_known_as
call print_text2
 
pop esi
mov esi, [esp + 8] ; FIXME: dont print the 0x0a0d!!!
call print_text2
 
mov esi, str_newline
call print_text2
 
.next_window:
pop ebx ecx
add ebx, sizeof.window
dec ecx
jnz .window_loop
 
pop esi
 
.fail:
 
ret
 
 
622,6 → 697,9
 
 
cmd_kick:
 
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'KICK '
; Is it me who got kicked?
mov edi, servercommand+1
636,7 → 714,11
call skip_nick
call window_open
 
mov esi, action_header_short
if TIMESTAMP
call print_timestamp
end if
 
mov esi, kick_header
call print_text2
 
mov eax, servercommand+1
656,14 → 738,38
mov esi, servercommand+1
call user_remove
 
.fail:
 
ret
 
 
 
cmd_quit:
; NOTE: This command applies to a user, and thus has no specific channel
 
mov esi, action_header
cmp byte [esi+4], ' '
jne .fail
 
mov ebx, windows
mov ecx, MAX_WINDOWS
 
.window_loop:
push ecx
cmp [ebx + window.type], WINDOWTYPE_CHANNEL
jne .next_window
 
mov esi, servercommand+1
call user_remove
test edi, edi
jz .next_window
 
push ebx
mov [window_print], ebx
 
if TIMESTAMP
call print_timestamp
end if
 
mov esi, quit_header
call print_text2
 
mov eax, servercommand+1
673,11 → 779,17
mov esi, has_quit_irc
call print_text2
 
; TODO: check other channels on same server too!
mov ebx, [window_print]
mov esi, servercommand+1
call user_remove
; TODO: check if quit message was given, and print it to the window
pop ebx
.next_window:
pop ecx
add ebx, sizeof.window
dec ecx
jnz .window_loop
 
.fail:
 
 
ret
 
 
684,14 → 796,35
 
cmd_mode:
 
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'MODE '
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
push esi
mov esi, action_header_short
 
if TIMESTAMP
call print_timestamp
end if
 
mov esi, mode_header
call print_text2
 
mov eax, servercommand+1
mov dl, ' '
mov dl, '!'
call print_text
 
mov esi, sets_mode
705,6 → 838,8
 
;;; TODO: change username if needed
 
.fail:
 
ret
 
 
739,7 → 874,7
jmp .add
 
.done:
call redraw_channel_list
call draw_channel_list
 
ret
 
767,8 → 902,12
call skip_nick
call window_open
 
if TIMESTAMP
call print_timestamp
end if
 
push esi
mov esi, action_header
mov esi, topic_header
call print_text2
 
mov esi, str_topic
799,8 → 938,12
; dec ecx
; jnz .loop ; find some more spaces
 
if TIMESTAMP
call print_timestamp
end if
 
push esi
mov esi, action_header
mov esi, topic_header
call print_text2
 
mov esi, str_setby
819,18 → 962,20
.fail:
ret
 
cmd_322:
cmd_322: ; LIST
 
add esi, 4
 
mov [window_print], windows ; FIXME
call skip_nick
 
call print_text2
 
mov eax, esi
mov dl, 13
call print_text
mov esi, str_newline
call print_text2
 
ret
 
cmd_323:
cmd_323: ; LIST END
 
ret
/programs/network/ircc/socket.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
12,13 → 13,13
 
socket_connect:
 
; cmp [status], STATUS_CONNECTED ; TODO
; je disconnect
 
; ignore if status is not "disconnected"
cmp [status], STATUS_DISCONNECTED
jne .nothing
jne .reconnect
 
if TIMESTAMP
call print_timestamp
end if
mov esi, str_connecting
call print_text2
mov esi, irc_server_name
63,12 → 64,14
cmp eax, -1
jz .fail_refused
 
.nothing:
ret
 
.fail:
mov [status], STATUS_DISCONNECTED
 
if TIMESTAMP
call print_timestamp
end if
mov esi, str_sockerr
call print_text2
 
77,6 → 80,9
.fail_dns:
mov [status], STATUS_DISCONNECTED
 
if TIMESTAMP
call print_timestamp
end if
mov esi, str_dnserr
call print_text2
 
85,13 → 91,28
.fail_refused:
mov [status], STATUS_DISCONNECTED
 
if TIMESTAMP
call print_timestamp
end if
mov esi, str_refused
call print_text2
 
ret
 
.reconnect:
 
if TIMESTAMP
call print_timestamp
end if
mov esi, str_reconnect
call print_text2
 
mov esi, quit_msg
call cmd_usr_quit.with_message
 
jmp socket_connect
 
 
socket_write_userinfo:
 
; create packet in packetbuf
180,26 → 201,12
inc [status]
 
.connected:
call read_incoming_data
call socket_receive
ret
 
 
disconnect:
socket_receive:
 
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
/programs/network/ircc/textbox.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
10,6 → 11,71
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
text_insert_newlines: ; esi = ASCIIZ string
 
xor edx, edx ; number of lines of text
cmp byte[esi], 0
je .done
.next_line:
xor ebx, ebx
mov ecx, [textbox_width]
inc ecx
.more:
dec ecx
jz .end_of_line
lodsb ; get one character of the string
test al, al ; end of string?
jz .almost_done
cmp al, ' ' ; it's a space! remember its position
je .space
cmp al, 13 ; we already inserted a newline once, make it a space again
je .soft_nl
cmp al, 10 ; it's a newline, continue onto the next line
jne .more
inc edx
jmp .next_line
.soft_nl:
inc edx
mov byte[esi-1], ' '
mov ebx, esi
jmp .more
.space:
mov ebx, esi ; last detected space
jmp .more
.end_of_line:
inc edx
test ebx, ebx ; did we detect any spaces on this line?
jz .next_line ; no: just continue onto the next line
mov byte[ebx-1], 13 ; yes: replace last space on line with a soft newline
mov esi, ebx ; and continue parsing just after last space
jmp .next_line ;
.almost_done:
dec esi
.done:
 
ret
 
; When you set the direction flag before calling, you can also scan for previous line!
; in: esi
; out:esi
text_nextline:
 
mov ecx, [textbox_width]
.loop:
cmp byte[esi], 0
je .done
lodsb
cmp al, 10
je .done
cmp al, 13
je .done
dec ecx
jnz .loop
.done:
 
ret
 
 
print_text: ; eax = start ptr
; dl = end char
pusha
27,6 → 93,7
 
.done:
popa
 
ret
 
 
44,80 → 111,253
 
.done:
popa
 
ret
 
 
 
; Character in bl
print_character:
 
push esi edi
mov esi, [window_print]
mov edi, [esi + window.text_write]
mov byte[edi], bl
inc edi
cmp edi, [esi + window.text_end]
jae .uh_ow
mov [esi + window.text_write], edi
.continue:
or [esi + window.flags], FLAG_UPDATED
pop edi esi
 
ret
 
.uh_ow:
 
pusha
mov ecx, TEXTBOX_LINES
imul ecx, [textbox_width]
mov esi, [text_start]
mov edi, [esi + window.text_start]
mov [esi + window.text_print], edi
lea esi, [edi + TEXT_BUFFERSIZE/2]
call text_nextline
mov ecx, TEXT_BUFFERSIZE/8
rep movsd
mov esi, edi
call text_insert_newlines
 
cmp bl, 10 ; line down
je .linefeed
mov ebx, [window_print]
mov [ebx + window.text_lines], edx
mov [ebx + window.text_scanned], esi
mov [ebx + window.text_write], esi
mov [ebx + window.text_line_print], 0
popa
 
mov eax, [text_pos]
mov byte[esi + eax], bl ; write the byte
inc [text_pos]
jmp .continue
 
cmp [text_pos], ecx
jb .done
 
.linefeed:
; scroll all text one line to the top
mov edi, esi
add esi, [textbox_width]
rep movsb
 
mov ecx, TEXTBOX_LINES - 1
imul ecx, [textbox_width]
mov [text_pos], ecx
draw_channel_text:
 
.done:
call window_is_updated
mov edi, [window_active]
and [edi + window.flags], not FLAG_UPDATED ; clear the 'window is updated' flag
 
popa
ret
; Scan new text for newlines
mov esi, [edi + window.text_scanned]
call text_insert_newlines
add [edi + window.text_lines], edx
mov [edi + window.text_scanned], esi
 
; should we scroll up/down some lines ? ; TODO: only scroll down automatically when scrollbar is at lowest position ?
mov edx, [edi + window.text_lines]
sub edx, [textbox_height]
jle .noscroll ; There are less lines of text than fit into the window, dont scroll..
sub edx, [edi + window.text_line_print]
je .noscroll ; We are already at the bottom pos, dont scroll..
 
.scroll_to_pos: ; edx = number of lines to go up/down (flags must indicate direction)
pushf
add [edi + window.text_line_print], edx
mov esi, [edi + window.text_print]
popf
ja .loop_forward
std ; set direction flag so we can scan backwards
dec esi ; move our cursor just in front of newline, for scanning backwards
dec edx ;;;;; FIXME: this seems to be needed, but why ???
.loop_backward:
call text_nextline
inc edx
jnz .loop_backward
inc esi ; move the cursor just after last newline
cld
jmp .ok
 
draw_channel_text: ; edx = pointer to text
.loop_forward:
call text_nextline
dec edx
jnz .loop_forward
.ok:
mov [edi + window.text_print], esi
.noscroll:
 
pusha
mov edx, [edi + window.text_print]
; Calculate start coordinates (align text to bottom)
mov ebx, [textbox_height]
sub ebx, [edi + window.text_lines]
jae @f
xor ebx, ebx
@@:
imul ebx, FONT_HEIGHT
add ebx, TEXT_X shl 16 + TEXT_Y
 
mov ebx, TEXT_X shl 16 + TEXT_Y
mov ecx, TEXTBOX_LINES
; Prepare to actually draw some text
mov eax, [textbox_height] ; max number of lines to draw
mov ecx, [colors.work_text] ; default text color
.drawloop:
cmp byte[edx], 0
je .end
 
.drawloop:
; Clear one row of characters
pusha
mov cx, bx
shl ecx, 16
mov cx, 9 ; character height
mov cx, FONT_HEIGHT
mov ebx, TEXT_X shl 16
mov bx, word[textbox_width]
imul bx, 6 ; character width
imul bx, FONT_WIDTH
mov edx, [colors.work]
mcall 13 ; draw rectangle
popa
 
push ecx
mov ecx, [colors.work_text]
mov esi, edx
add esi, [textbox_width]
.line:
cmp byte[edx], 0
je .end
 
cmp byte[edx], 13
je .newline_soft
 
cmp byte[edx], 10
je .newline_hard
 
push esi eax
cmp byte[edx], 3 ; escape code for mIRC colors
jne .no_colors
inc edx
call dec_to_esi
jz .no_colors
mov ecx, [irc_colors + 4*esi]
 
cmp byte[edx], ',' ; background color?
jne .no_colors
inc edx
call dec_to_esi
jz .no_colors
mov edi, [irc_colors + 4*esi]
or ecx, 0x40000000
.no_colors:
 
.draw:
mov esi, [textbox_width]
mov esi, 1
mcall 4 ; draw text
add edx, [textbox_width]
add ebx, 10 ; height distance between lines
add ebx, FONT_WIDTH shl 16
inc edx
pop eax esi
cmp edx, esi
jb .line
jmp .line_full
 
pop ecx
loop .drawloop
.newline_hard:
mov ecx, [colors.work_text]
.newline_soft:
inc edx
.line_full:
and ebx, 0x0000ffff
add ebx, TEXT_X shl 16 + FONT_HEIGHT
dec eax
jnz .drawloop
 
mov eax, [window_active]
and [eax + window.flags], not FLAG_UPDATED ; clear the 'window is updated' flag
; take care of the scrollbar
.scrollbar:
mov edi, [window_active]
mov edx, [edi + window.text_lines]
cmp edx, [textbox_height]
ja .draw_scroll
mov [scroll2.position], 0 ; disable scrollbar
jmp .scroll_done
 
.draw_scroll:
mov [scroll2.max_area], edx
mov eax, [edi + window.text_line_print]
mov [scroll2.position], eax
 
push dword scroll2 ; redraw scrollbar
call [scrollbar_draw]
 
mov [scroll2.all_redraw], 0 ; next time, dont redraw it completely
.scroll_done:
.end:
ret
 
 
 
 
dec_to_esi:
 
xor esi, esi
.loop:
movzx eax, byte[edx]
sub al, '0'
jb .done
cmp al, 9
ja .done
inc edx
shl esi, 1 ; esi * 2
lea esi, [esi + 4*esi] ; esi * 5
add esi, eax
jmp .loop
.done:
cmp esi, 16
jae .fail
ret
 
.fail:
xor esi, esi
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
/programs/network/ircc/userparser.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
12,6 → 13,9
 
user_parser:
 
push [window_active] ; print to the current window
pop [window_print]
 
mov eax, [edit1.size]
test eax, eax
jz sdts_ret ; ignore empty commands
25,13 → 29,8
jne sdts_ret
 
; Ok, we said something, print it to our textbox
 
; TODO: dont send if it's a server window?
 
push [window_active] ; print to the current window
pop [window_print]
call window_refresh
 
if TIMESTAMP
call print_timestamp
end if
57,10 → 56,9
call print_character
 
; and now send it to the server
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
 
mov dword[packetbuf], 'priv'
mov dword[packetbuf+4], 'msg '
 
mov esi, [window_active]
add esi, window.name
mov edi, packetbuf+8
82,8 → 80,9
inc ecx
call recode
 
mov al, 10
stosb
; end the command with a CRLF
mov ax, 0x0a0d
stosw
 
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
100,10 → 99,13
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.
 
; All following commands require a connection to the server. TODO: verify connection
dd 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit
dd 'part', cmd_usr_part
dd 'ctcp', cmd_usr_ctcp
dd 'msg ', cmd_usr_msg
 
.number = ($ - user_commands) / 8
 
131,22 → 133,94
 
 
 
cmd_usr_msg:
 
lea esi, [usercommand+5]
 
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
lea edi, [packetbuf+8]
 
@@:
lodsb
test al, al
jz .fail
cmp al, 10
je .fail
cmp al, 13
je .fail
stosb
cmp al, ' '
jne @r
 
mov al, ':'
stosb
 
push edi
@@:
lodsb
test al, al
jz @f
cmp al, 10
je @f
cmp al, 13
je @f
stosb
jmp @r
@@:
; end the command with a CRLF
mov ax, 0x0a0d
stosw
mov byte[edi], 0
 
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
 
; now print to the window
if TIMESTAMP
call print_timestamp
end if
 
mov esi, msg_header
call print_text2
 
mov eax, packetbuf+8
mov dl, ' '
call print_text
 
mov bl, '*'
call print_character
 
mov bl, ' '
call print_character
 
pop esi
call print_text2
 
.fail:
ret
 
 
 
cmd_usr_quit:
 
mov esi, quit_msg
 
cmp byte[usercommand+5], ' '
jne .default_msg
jne .with_message
lea esi,[usercommand+6]
.default_msg:
.with_message:
call cmd_usr_quit_server
 
mcall close, [socketnum]
mov [status], STATUS_DISCONNECTED
 
mov ecx, MAX_WINDOWS
mov edi, windows
.loop:
mov [edi + window.flags], FLAG_CLOSE
mov [window_print], edi
push edi ecx
call window_close
pop ecx edi
add edi, sizeof.window
dec ecx
jnz .loop
165,11 → 239,14
; Append our quit msg
@@:
lodsb
cmp al, 13
je @f
test al, al
jz @f
stosb
test al, al
jnz @r
jmp @r
@@:
; end the command with a CRLF
dec edi
mov ax, 0x0a0d
stosw
 
184,31 → 261,37
cmd_usr_nick:
 
cmp [edit1.size], 5
je .justprint
je .dontsend
cmp byte[usercommand+5], ' '
jne cmd_usr_send
jne .fail
cmp [socketnum], 0
je .dontsend
 
mov dword[usercommand+1], 'NICK'
mov esi, [edit1.size]
mov word[usercommand + esi], 0x0a0d
inc esi
mcall send, [socketnum], usercommand+1, , 0
 
.fail:
 
ret
 
.dontsend:
mov ecx, MAX_NICK_LEN
mov esi, usercommand+6
mov edi, user_nick
.loop:
@@:
lodsb
cmp al, 13
je .done
je @f
stosb
dec ecx
jnz .loop
.done:
jnz @r
@@:
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
299,13 → 382,11
call window_create
test eax, eax
jz .error
mov [ebx + window.data_ptr], eax
mov [ebx + window.type], WINDOWTYPE_CHAT
 
mov esi, usercommand+7
call window_set_name
 
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
 
.error:
 
334,17 → 415,32
cmd_usr_part:
 
cmp byte[usercommand+5], 13 ; parameters given?
jne cmd_usr_send
jne cmd_usr_send ; yes, send command straight to server
 
mov esi, [window_active] ; window is not a server window?
; close active window
cmd_usr_close_window:
 
mov esi, [window_active]
mov [window_print], esi
cmp [esi + window.type], WINDOWTYPE_SERVER
je @f
je .not_channel
 
call window_close ; OK, close currently open (channel/chat/..) window
@@:
lea esi, [esi + window.name]
call cmd_usr_part_channel
call window_close
ret
 
.not_channel:
cmp [esi + window.type], WINDOWTYPE_CHAT
jne .not_chat
 
call window_close
.not_chat:
 
ret
 
 
 
; Send part command to server
; esi must point to channel name (ASCIIZ)
cmd_usr_part_channel:
355,11 → 451,16
lea edi, [packetbuf+5]
@@:
lodsb
test al, al
jz @f
cmp al, 13
je @f
cmp al, 10
je @f
stosb
test al, al
jnz @r
jmp @r
@@:
; end the command with a CRLF
dec edi
mov ax, 0x0a0d
stosw
 
369,6 → 470,63
ret
 
 
cmd_usr_ctcp:
 
cmp byte[usercommand+5], ' '
jne cmd_usr_send
 
mov esi, usercommand+6
; prepare a 'PRIVMSG '
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
lea edi, [packetbuf+8]
 
; append the destination (nickname/channel)
@@:
lodsb
test al, al
jz .fail
cmp al, ' '
je @f
stosb
jmp @r
@@:
 
mov ax, ' :'
stosw
mov al, 0x01
stosb
 
; copy the message itself
@@:
lodsb
test al, al
jz @f
cmp al, 13
je @f
cmp al, 10
je @f
stosb
jmp @r
@@:
 
; end of message
mov al, 0x01
stosb
mov ax, 0x0a0d
stosw
 
; now send it away
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
 
;; TODO: print to window
 
.fail:
 
ret
 
 
; The user typed some undefined command, just recode it and send to the server
cmd_usr_send:
 
383,3 → 541,7
 
ret
 
 
 
 
 
/programs/network/ircc/users.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
9,7 → 10,11
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; TODO: work correctly with user prefixes.
; use first byte of nick for prefix ONLY (use a space for those that do not have special powers..)
 
user_prefixes db '~&@%+ ', 0 ; in descending order
 
; esi is ptr to nick
; ebx is ptr to window
align 4
78,8 → 83,7
; mov all trailing usernames by MAX_NICK_LEN bytes
push esi edi
mov esi, [ebx + window.data_ptr]
add esi, window_data.names + MAX_NICK_LEN * (MAX_USERS - 1)
 
add esi, window_data.names + MAX_NICK_LEN * (MAX_USERS - 1) - 4 ; -4 because we're copying backward, dword wise
mov ecx, esi
sub ecx, edi
add ecx, MAX_NICK_LEN
98,6 → 102,10
je .done
cmp al, '!'
je .done
cmp al, 13
je .done
cmp al, 10
je .done
stosb
loop .fill
.done:
105,6 → 113,7
stosb
 
inc [ebx + window.users]
or [ebx + window.flags], FLAG_UPDATED
 
ret
 
128,7 → 137,7
rep movsd
 
dec [ebx + window.users]
xor eax, eax
or [ebx + window.flags], FLAG_UPDATED
 
ret
 
/programs/network/ircc/window.inc
3,6 → 3,7
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
10,11 → 11,15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; in: window ptr in ebx
; out: eax = 0 on error
window_create:
 
push ebx
; allocate the window data block
mcall 68, 12, sizeof.window_data
test eax, eax
pop ebx
jz .fail
 
; fill it with all zeros
25,6 → 30,19
rep stosd
pop eax
 
mov [ebx + window.data_ptr], eax
mov [ebx + window.flags], 0
 
add eax, window_data.text+1 ; let text begin at offset 1, this way the text will be prepended with a 0
mov [ebx + window.text_start], eax
mov [ebx + window.text_print], eax
mov [ebx + window.text_write], eax
mov [ebx + window.text_scanned], eax
mov [ebx + window.text_lines], 0
mov [ebx + window.text_line_print], 0
add eax, TEXT_BUFFERSIZE-1
mov [ebx + window.text_end], eax
 
.fail:
ret
 
63,32 → 81,16
 
 
 
window_refresh:
 
; set text write cursor to beginning of last line
mov eax, [textbox_width]
imul eax, TEXTBOX_LINES - 1
mov [text_pos], eax
 
; set the textbuffer pointer
mov eax, [window_print]
mov eax, [eax + window.data_ptr]
add eax, window_data.text
mov [text_start], eax
 
ret
 
 
 
window_is_updated:
 
mov edi, [window_print]
cmp edi, [window_active]
je .skip
test [edi + window.flags], FLAG_UPDATED
jnz .skip
 
or [edi + window.flags], FLAG_UPDATED
 
; now play a sound :)
; TODO: make some noise
 
call draw_windowtabs ; highlight updated tabs
.skip:
97,19 → 99,10
 
 
 
window_close:
window_close: ; closes the 'print' window
 
; 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]
mov edi, [window_print]
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
131,7 → 124,7
jne @f
sub edi, sizeof.window
mov [window_active], edi
mov [window_print], edi
mov [window_print], edi ;;;;;;;;
@@:
 
; At last, redraw everything
141,7 → 134,47
 
 
 
window_find: ; esi = window name
; search for window in list
mov ebx, windows
mov [window_print], ebx ; set first window (server window) as default output window
mov eax, MAX_WINDOWS
.scanloop:
push esi
cmp [ebx + window.type], WINDOWTYPE_NONE
je .try_next
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
repe cmpsb
cmp byte[edi-1], 0
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
.try_next:
pop esi
add ebx, sizeof.window
dec eax
jnz .scanloop
 
xor ebx, ebx
ret
 
.got_it:
pop esi ;;; TODO: dont reset ESI ?
mov [window_print], ebx
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!
;
157,22 → 190,9
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
call window_find
test ebx, ebx
jne .got_it
 
; create channel window - search for empty slot
.create_it:
185,31 → 205,20
dec ecx
jnz .scanloop2
; Error: no more available windows!
jmp .just_skip
jmp .got_it ; TODO: return error
 
.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
jz .got_it ; TODO: return error
mov [ebx + window.type], WINDOWTYPE_CHAT ; FIXME: let caller handle this ?
 
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
231,43 → 240,4
dec esi
 
.quit:
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
ret