/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 |