forked from KolibriOS/kolibrios
Intermediate version of IRCC: new multiline resizeable textbox with proper line-breaking, colors and scrolling. New usercommands: msg and ctcp. Small bugfixes and enhancements
git-svn-id: svn://kolibrios.org@4143 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
7830e9f673
commit
8ad9d9edd3
@ -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 ;;
|
||||
|
@ -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,7 +11,8 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
draw_window:
|
||||
|
||||
draw_window: ; Completely redraw the window, recalculate all coordinates and sizes
|
||||
|
||||
pusha
|
||||
|
||||
@ -37,6 +39,12 @@ draw_window:
|
||||
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 @@ draw_window:
|
||||
|
||||
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
|
||||
|
||||
call redraw_channel_list
|
||||
add ecx, TOP_Y SHL 16 -(BOTTOM_Y) ;;;;
|
||||
mov edx, [colors.work_graph]
|
||||
mcall 38
|
||||
|
||||
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 @@ draw_window:
|
||||
push dword edit1
|
||||
call [edit_box_draw]
|
||||
|
||||
; tabs
|
||||
; draw tabs
|
||||
call draw_windowtabs
|
||||
|
||||
popa
|
||||
@ -100,31 +145,15 @@ draw_window:
|
||||
|
||||
|
||||
|
||||
redraw_channel_list:
|
||||
draw_channel_list:
|
||||
|
||||
; First, calculate scrollbar
|
||||
|
||||
mov ebx, [window_active]
|
||||
mov eax, [ebx + window.users] ; number of users in the open window
|
||||
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
|
||||
pusha
|
||||
|
||||
; Do we need a scrollbar?
|
||||
cmp eax, [scroll1.max_area]
|
||||
mov ebx, [window_active]
|
||||
mov eax, [ebx + window.users]
|
||||
mov [scroll1.max_area], eax
|
||||
cmp [scroll1.cur_area], eax
|
||||
jae .noscroll
|
||||
|
||||
; Is the current position greater then the max position?
|
||||
@ -132,42 +161,37 @@ redraw_channel_list:
|
||||
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 @@ print_channel_list:
|
||||
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 @@ print_channel_list:
|
||||
; 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 @@ print_channel_list:
|
||||
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
|
||||
|
@ -13,7 +13,7 @@
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
version equ '0.1'
|
||||
version equ '0.15'
|
||||
|
||||
; connection status
|
||||
STATUS_DISCONNECTED = 0
|
||||
@ -23,15 +23,15 @@ STATUS_CONNECTED = 3
|
||||
|
||||
; 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 @@ UTF8 = 2
|
||||
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,11 +71,11 @@ WINDOW_BTN_START = 100
|
||||
WINDOW_BTN_CLOSE = 2
|
||||
WINDOW_BTN_LIST = 3
|
||||
|
||||
SCROLLBAR_WIDTH = 12
|
||||
SCROLLBAR_WIDTH = 14
|
||||
USERLIST_WIDTH = 100
|
||||
|
||||
USERLIST_X = 98
|
||||
|
||||
TEXTBOX_LINES = 12
|
||||
FONT_HEIGHT = 9
|
||||
FONT_WIDTH = 6
|
||||
|
||||
format binary as ""
|
||||
|
||||
@ -98,25 +100,31 @@ include "../../struct.inc"
|
||||
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
|
||||
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,26 +168,30 @@ START:
|
||||
rep stosd
|
||||
|
||||
; allocate window data block
|
||||
call window_create
|
||||
mov ebx, windows
|
||||
mov [ebx + window.data_ptr], eax
|
||||
mov [ebx + window.flags], 0
|
||||
call window_create
|
||||
test eax, eax
|
||||
jz error
|
||||
mov [ebx + window.type], WINDOWTYPE_SERVER
|
||||
|
||||
call window_refresh
|
||||
|
||||
; get system colors
|
||||
mcall 48, 3, colors, 40
|
||||
|
||||
; set edit box and scrollbar colors
|
||||
mov eax, [colors.work]
|
||||
mov [scroll1.bg_color], eax
|
||||
mov [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
|
||||
@ -190,13 +202,12 @@ START:
|
||||
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 @@ still:
|
||||
|
||||
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 @@ button:
|
||||
|
||||
cmp ax, WINDOW_BTN_CLOSE
|
||||
jne @f
|
||||
|
||||
call window_close
|
||||
call cmd_usr_close_window
|
||||
jmp still
|
||||
|
||||
@@:
|
||||
@ -248,7 +258,7 @@ button:
|
||||
|
||||
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 @@ button:
|
||||
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 @@ button:
|
||||
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 @@ exit:
|
||||
call cmd_usr_quit_server
|
||||
@@:
|
||||
|
||||
error:
|
||||
|
||||
mcall -1
|
||||
|
||||
|
||||
@ -315,20 +329,32 @@ main_window_key:
|
||||
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
|
||||
|
||||
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,14 +366,31 @@ mouse:
|
||||
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 'CP1251'
|
||||
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 @@ kicked db ' is kicked from ', 0
|
||||
str_talking db 'Now talking in ',0
|
||||
str_topic db 'Topic is ',0
|
||||
str_setby db 'Set by ',0
|
||||
str_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_nick db 'kolibri_user', 0
|
||||
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,13 +464,30 @@ str_help db 10,'following commands are available:',10
|
||||
db '/server <address> : connect to server <address>',10
|
||||
db '/code <code> : change codepage to cp866, cp1251, or utf8',10,0
|
||||
|
||||
str_1 db ' -',0
|
||||
str_1 db 3,'13 -',0
|
||||
str_2 db '- ',0
|
||||
|
||||
str_sockerr db 'Socket Error',10,0
|
||||
str_dnserr db 'Unable to resolve hostname.',10,0
|
||||
str_refused db 'Connection refused',10,0
|
||||
|
||||
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,9 +497,9 @@ sockaddr1:
|
||||
|
||||
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
|
||||
@ -454,24 +521,23 @@ import libini,\
|
||||
ini.get_int, 'ini_get_int'
|
||||
|
||||
import boxlib,\
|
||||
edit_box_draw ,'edit_box' ,\
|
||||
edit_box_key ,'edit_box_key' ,\
|
||||
edit_box_mouse ,'edit_box_mouse' ,\
|
||||
scrollbar_v_draw ,'scrollbar_v_draw' ,\
|
||||
scrollbar_v_mouse,'scrollbar_v_mouse'
|
||||
edit_box_draw, 'edit_box',\
|
||||
edit_box_key, 'edit_box_key',\
|
||||
edit_box_mouse, 'edit_box_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
|
||||
|
@ -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 @@ server_commands:
|
||||
|
||||
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 @@ compare_to_nick:
|
||||
pop esi
|
||||
ret
|
||||
|
||||
|
||||
|
||||
align 4
|
||||
skip_nick:
|
||||
|
||||
@ -135,6 +140,8 @@ skip_nick:
|
||||
|
||||
|
||||
|
||||
cmd_324:
|
||||
cmd_329:
|
||||
cmd_328:
|
||||
cmd_421:
|
||||
cmd_372:
|
||||
@ -149,11 +156,16 @@ cmd_notice:
|
||||
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 @@ cmd_notice:
|
||||
cmp byte [esi], ':'
|
||||
je .loop2
|
||||
|
||||
.fail:
|
||||
call print_text2
|
||||
mov esi, str_newline
|
||||
call print_text2
|
||||
|
||||
.fail:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -212,19 +223,20 @@ cmd_ping:
|
||||
|
||||
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
|
||||
if TIMESTAMP
|
||||
; nope, just plain old privmsg, print it using '<nick> message' format
|
||||
if TIMESTAMP
|
||||
call print_timestamp
|
||||
end if
|
||||
end if
|
||||
|
||||
push esi
|
||||
mov bl, '<'
|
||||
@ -249,49 +261,36 @@ end if
|
||||
.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
|
||||
|
||||
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:
|
||||
mov byte [esi+4], ' '
|
||||
mov byte[esi+4], ' '
|
||||
lea edi, [esi+5]
|
||||
|
||||
; TODO: add system date (fn 29) in human readable format
|
||||
@ -375,12 +374,52 @@ cmd_ctcp:
|
||||
|
||||
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,27 +464,34 @@ ctcp_reply:
|
||||
|
||||
|
||||
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
|
||||
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_part:
|
||||
|
||||
|
||||
cmd_join:
|
||||
|
||||
cmp byte [esi+4], ' '
|
||||
jne .fail
|
||||
add esi, 5 ; skip 'JOIN '
|
||||
|
||||
; compare nick: did we join a channel?
|
||||
@ -488,27 +537,26 @@ cmd_join:
|
||||
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 @@ cmd_join:
|
||||
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,58 +601,71 @@ cmd_join:
|
||||
mov esi, servercommand+1
|
||||
call user_add
|
||||
|
||||
.fail:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
cmd_nick:
|
||||
; NOTE: This command applies to a user, and thus has no specific channel
|
||||
add esi, 5 ; skip 'NICK '
|
||||
|
||||
cmp byte[esi], ':' ; TODO: skip all spaces and semicolons?
|
||||
cmp byte[esi+4], ' '
|
||||
jne .fail
|
||||
add esi, 5 ; skip 'NICK '
|
||||
cmp byte[esi], ':'
|
||||
jne @f
|
||||
inc esi
|
||||
@@:
|
||||
|
||||
; Change the nick in the current userlist. TODO: check other channels too!
|
||||
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?
|
||||
push esi
|
||||
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,18 +675,31 @@ cmd_nick:
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
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 @@ cmd_kick:
|
||||
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 @@ cmd_kick:
|
||||
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,10 +779,16 @@ cmd_quit:
|
||||
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_quit:
|
||||
|
||||
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 @@ cmd_mode:
|
||||
|
||||
;;; TODO: change username if needed
|
||||
|
||||
.fail:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -739,7 +874,7 @@ cmd_353: ; channel usernames reply
|
||||
jmp .add
|
||||
|
||||
.done:
|
||||
call redraw_channel_list
|
||||
call draw_channel_list
|
||||
|
||||
ret
|
||||
|
||||
@ -767,8 +902,12 @@ cmd_topic:
|
||||
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 @@ cmd_333:
|
||||
; 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 @@ cmd_333:
|
||||
.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
|
@ -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 @@ socket_connect:
|
||||
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 @@ socket_connect:
|
||||
.fail_dns:
|
||||
mov [status], STATUS_DISCONNECTED
|
||||
|
||||
if TIMESTAMP
|
||||
call print_timestamp
|
||||
end if
|
||||
mov esi, str_dnserr
|
||||
call print_text2
|
||||
|
||||
@ -85,11 +91,26 @@ socket_connect:
|
||||
.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:
|
||||
@ -180,25 +201,11 @@ process_network_event:
|
||||
inc [status]
|
||||
|
||||
.connected:
|
||||
call read_incoming_data
|
||||
call socket_receive
|
||||
ret
|
||||
|
||||
|
||||
disconnect:
|
||||
|
||||
cmp [status], STATUS_DISCONNECTED
|
||||
je .nothing
|
||||
|
||||
mcall close, [socketnum]
|
||||
|
||||
mov [status], STATUS_DISCONNECTED
|
||||
|
||||
.nothing:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
read_incoming_data:
|
||||
socket_receive:
|
||||
|
||||
pusha
|
||||
|
||||
|
@ -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 @@ print_text: ; eax = start ptr
|
||||
|
||||
.done:
|
||||
popa
|
||||
|
||||
ret
|
||||
|
||||
|
||||
@ -44,80 +111,253 @@ print_text2: ; esi = ptr to ASCIIZ string
|
||||
|
||||
.done:
|
||||
popa
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; Character in bl
|
||||
print_character:
|
||||
|
||||
pusha
|
||||
mov ecx, TEXTBOX_LINES
|
||||
imul ecx, [textbox_width]
|
||||
mov esi, [text_start]
|
||||
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
|
||||
|
||||
cmp bl, 10 ; line down
|
||||
je .linefeed
|
||||
|
||||
mov eax, [text_pos]
|
||||
mov byte[esi + eax], bl ; write the byte
|
||||
inc [text_pos]
|
||||
|
||||
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
|
||||
|
||||
.done:
|
||||
call window_is_updated
|
||||
|
||||
popa
|
||||
ret
|
||||
|
||||
|
||||
|
||||
draw_channel_text: ; edx = pointer to text
|
||||
.uh_ow:
|
||||
|
||||
pusha
|
||||
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
|
||||
|
||||
mov ebx, TEXT_X shl 16 + TEXT_Y
|
||||
mov ecx, TEXTBOX_LINES
|
||||
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
|
||||
|
||||
jmp .continue
|
||||
|
||||
|
||||
|
||||
draw_channel_text:
|
||||
|
||||
mov edi, [window_active]
|
||||
and [edi + window.flags], not FLAG_UPDATED ; clear the 'window is updated' flag
|
||||
|
||||
; 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
|
||||
|
||||
.loop_forward:
|
||||
call text_nextline
|
||||
dec edx
|
||||
jnz .loop_forward
|
||||
.ok:
|
||||
mov [edi + window.text_print], esi
|
||||
.noscroll:
|
||||
|
||||
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
|
||||
|
||||
; 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
|
||||
|
||||
; 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
|
@ -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 @@ user_parser:
|
||||
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,9 +56,8 @@ user_parser:
|
||||
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
|
||||
@ -82,8 +80,9 @@ user_parser:
|
||||
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 @@ user_commands:
|
||||
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 @@ server_command:
|
||||
|
||||
|
||||
|
||||
cmd_usr_quit:
|
||||
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
|
||||
lea esi,[usercommand+6]
|
||||
.default_msg:
|
||||
jne .with_message
|
||||
lea esi, [usercommand+6]
|
||||
.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 @@ cmd_usr_quit_server:
|
||||
; Append our quit msg
|
||||
@@:
|
||||
lodsb
|
||||
stosb
|
||||
cmp al, 13
|
||||
je @f
|
||||
test al, al
|
||||
jnz @r
|
||||
jz @f
|
||||
stosb
|
||||
jmp @r
|
||||
@@:
|
||||
; end the command with a CRLF
|
||||
dec edi
|
||||
mov ax, 0x0a0d
|
||||
stosw
|
||||
|
||||
@ -184,31 +261,37 @@ cmd_usr_quit_server:
|
||||
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 @@ cmd_usr_quer:
|
||||
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_code:
|
||||
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 @@ cmd_usr_part_channel:
|
||||
lea edi, [packetbuf+5]
|
||||
@@:
|
||||
lodsb
|
||||
stosb
|
||||
test al, al
|
||||
jnz @r
|
||||
jz @f
|
||||
cmp al, 13
|
||||
je @f
|
||||
cmp al, 10
|
||||
je @f
|
||||
stosb
|
||||
jmp @r
|
||||
@@:
|
||||
; end the command with a CRLF
|
||||
dec edi
|
||||
mov ax, 0x0a0d
|
||||
stosw
|
||||
|
||||
@ -369,6 +470,63 @@ cmd_usr_part_channel:
|
||||
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 @@ cmd_usr_send:
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,12 +3,17 @@
|
||||
;; 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 ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; 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
|
||||
@ -78,8 +83,7 @@ user_add:
|
||||
; 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 @@ user_add:
|
||||
je .done
|
||||
cmp al, '!'
|
||||
je .done
|
||||
cmp al, 13
|
||||
je .done
|
||||
cmp al, 10
|
||||
je .done
|
||||
stosb
|
||||
loop .fill
|
||||
.done:
|
||||
@ -105,6 +113,7 @@ user_add:
|
||||
stosb
|
||||
|
||||
inc [ebx + window.users]
|
||||
or [ebx + window.flags], FLAG_UPDATED
|
||||
|
||||
ret
|
||||
|
||||
@ -128,7 +137,7 @@ user_remove:
|
||||
rep movsd
|
||||
|
||||
dec [ebx + window.users]
|
||||
xor eax, eax
|
||||
or [ebx + window.flags], FLAG_UPDATED
|
||||
|
||||
ret
|
||||
|
||||
|
@ -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 @@ window_create:
|
||||
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_set_name: ; esi = ptr to name, ebx = window ptr
|
||||
|
||||
|
||||
|
||||
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_is_updated:
|
||||
|
||||
|
||||
|
||||
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:
|
||||
window_close: ; closes the 'print' window
|
||||
|
||||
; 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 @@ window_close:
|
||||
jne @f
|
||||
sub edi, sizeof.window
|
||||
mov [window_active], edi
|
||||
mov [window_print], edi
|
||||
mov [window_print], edi ;;;;;;;;
|
||||
@@:
|
||||
|
||||
; At last, redraw everything
|
||||
@ -141,6 +134,46 @@ window_close:
|
||||
|
||||
|
||||
|
||||
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 @@ window_open:
|
||||
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 @@ window_open:
|
||||
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
|
||||
@ -232,42 +241,3 @@ window_open:
|
||||
|
||||
.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
|
Loading…
Reference in New Issue
Block a user