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:
hidnplayr 2013-11-01 14:02:08 +00:00
parent 7830e9f673
commit 8ad9d9edd3
9 changed files with 1079 additions and 456 deletions

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by CleverMouse ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
@ -10,7 +11,8 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
draw_window:
draw_window: ; Completely redraw the window, recalculate all coordinates and sizes
pusha pusha
@ -37,6 +39,12 @@ draw_window:
add esi, ebx add esi, ebx
mcall 67, -1, -1 ; set the new sizes mcall 67, -1, -1 ; set the new sizes
popa
.dont_resize:
pusha
mcall 12, 1 mcall 12, 1
xor eax, eax ; draw window xor eax, eax ; draw window
mov ebx, WIN_MIN_X mov ebx, WIN_MIN_X
@ -49,39 +57,76 @@ draw_window:
mov ebx, [xsize] mov ebx, [xsize]
mov ecx, [ysize] mov ecx, [ysize]
sub cx, 15 ;;;; sub cx, BOTTOM_Y ;;;;
push cx push cx
shl ecx, 16 shl ecx, 16
pop cx pop cx
mov edx, [colors.work_graph] mov edx, [colors.work_graph]
mcall 38 ; draw line mcall 38 ; draw bottom line
mov ecx, TOP_Y SHL 16 + TOP_Y 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] mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .not_channel jne .not_channel
; draw a vertical separator line ; draw a vertical separator line
; TODO: dont draw this if we draw textbox scrollbar ??
mov ebx, [xsize] mov ebx, [xsize]
sub ebx, USERLIST_X + SCROLLBAR_WIDTH + 3 sub ebx, USERLIST_WIDTH + SCROLLBAR_WIDTH + 3
push bx push bx
shl ebx, 16 shl ebx, 16
pop bx pop bx
mov ecx, [ysize] mov ecx, [ysize]
add ecx, TOP_Y SHL 16 -(15) ;;;; add ecx, TOP_Y SHL 16 -(BOTTOM_Y) ;;;;
mcall mov edx, [colors.work_graph]
mcall 38
call redraw_channel_list
mov [scroll1.all_redraw], 1
call draw_channel_list
.not_channel: .not_channel:
mov edx, [edi + window.data_ptr]
add edx, window_data.text
call draw_channel_text
; editbox
; draw editbox
mov eax, [ysize] mov eax, [ysize]
sub eax, 12 ;;;;;; sub eax, 12 ;;;;;;
mov [edit1.top], eax mov [edit1.top], eax
@ -92,7 +137,7 @@ draw_window:
push dword edit1 push dword edit1
call [edit_box_draw] call [edit_box_draw]
; tabs ; draw tabs
call draw_windowtabs call draw_windowtabs
popa popa
@ -100,31 +145,15 @@ draw_window:
redraw_channel_list: draw_channel_list:
; First, calculate scrollbar pusha
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
; Do we need a scrollbar? ; 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 jae .noscroll
; Is the current position greater then the max position? ; Is the current position greater then the max position?
@ -132,42 +161,37 @@ redraw_channel_list:
ja @f ja @f
mov [scroll1.position], eax mov [scroll1.position], eax
@@: @@:
; OK, draw the scrollbar ; OK, draw the scrollbar
mov [scroll1.all_redraw], 1
push dword scroll1 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: .noscroll:
mov [scroll1.position], 0 mov [scroll1.position], 0
.scroll_done:
; draw an invisible button, where the usernames will go
print_channel_list:
pusha
; first, draw an invisible button
mov ebx, [xsize] mov ebx, [xsize]
sub ebx, USERLIST_X + SCROLLBAR_WIDTH sub ebx, USERLIST_WIDTH + SCROLLBAR_WIDTH
shl ebx, 16 shl ebx, 16
push ebx push ebx
mov bx, USERLIST_X mov bx, USERLIST_WIDTH
mov ecx, [ysize] 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 push ecx ebx
mov edx, WINDOW_BTN_LIST + 1 shl 29 + 1 shl 30 mov edx, WINDOW_BTN_LIST + 1 shl 29 + 1 shl 30
mcall 8 mcall 8
; draw rectangle to clear previously printed names ; draw a filled rectangle to clear previously printed names
pop ebx ecx pop ebx ecx
mov edx, [colors.work] mov edx, [colors.work]
mcall 13 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] mov eax, [scroll1.position]
xor edx, edx xor edx, edx
mov ecx, MAX_NICK_LEN mov ecx, MAX_NICK_LEN
@ -185,8 +209,7 @@ print_channel_list:
or ecx, 0x80000000 ; ASCIIZ string or ecx, 0x80000000 ; ASCIIZ string
mov eax, 4 ; draw text mov eax, 4 ; draw text
mov edi, [ysize] ; Calculate how many names will fit on screen mov edi, [textbox_height] ; how many names will fit on screen
sub edi, TEXT_Y + 15 ;+ 10 ;;;;;
.loop: .loop:
cmp byte[edx], 0 ; end of list? cmp byte[edx], 0 ; end of list?
je .done je .done
@ -196,7 +219,7 @@ print_channel_list:
; yes, highlight it ; yes, highlight it
pusha pusha
mov cx, bx mov cx, bx
mov bx, USERLIST_X mov bx, USERLIST_WIDTH
shl ecx, 16 shl ecx, 16
mov cx, 10 - 1 mov cx, 10 - 1
mov edx, 0x00000055 ; blue! mov edx, 0x00000055 ; blue!
@ -214,10 +237,10 @@ print_channel_list:
mcall mcall
.next: .next:
add edx, MAX_NICK_LEN ; next name add edx, MAX_NICK_LEN
add ebx, 10 ; height distance between lines add ebx, FONT_HEIGHT
sub edi, 10 dec edi
ja .loop jnz .loop
.done: .done:
popa popa

View File

@ -13,7 +13,7 @@
;; ;; ;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
version equ '0.1' version equ '0.15'
; connection status ; connection status
STATUS_DISCONNECTED = 0 STATUS_DISCONNECTED = 0
@ -23,15 +23,15 @@ STATUS_CONNECTED = 3
; window flags ; window flags
FLAG_UPDATED = 1 shl 0 FLAG_UPDATED = 1 shl 0
FLAG_CLOSE = 1 shl 1 FLAG_RECEIVING_NAMES = 1 shl 1
FLAG_RECEIVING_NAMES = 1 shl 2
; window types ; window types
WINDOWTYPE_SERVER = 0 WINDOWTYPE_NONE = 0
WINDOWTYPE_CHANNEL = 1 WINDOWTYPE_SERVER = 1
WINDOWTYPE_CHAT = 2 WINDOWTYPE_CHANNEL = 2
WINDOWTYPE_LIST = 3 WINDOWTYPE_CHAT = 3
WINDOWTYPE_DCC = 4 WINDOWTYPE_LIST = 4
WINDOWTYPE_DCC = 5
; supported encodings ; supported encodings
CP866 = 0 CP866 = 0
@ -42,15 +42,17 @@ UTF8 = 2
USERCMD_MAX_SIZE = 400 USERCMD_MAX_SIZE = 400
WIN_MIN_X = 600 WIN_MIN_X = 600
WIN_MIN_Y = 165 WIN_MIN_Y = 170
TEXT_X = 5 TEXT_X = 5
TEXT_Y = 30 TEXT_Y = TOP_Y + 2
TOP_Y = 25 TOP_Y = 24
BOTTOM_Y = 15
MAX_WINDOWS = 20 MAX_WINDOWS = 20
MAX_USERS = 4096 MAX_USERS = 4096
TEXT_BUFFERSIZE = 4096;*1024
MAX_NICK_LEN = 32 MAX_NICK_LEN = 32
MAX_REAL_LEN = 32 ; realname MAX_REAL_LEN = 32 ; realname
@ -69,11 +71,11 @@ WINDOW_BTN_START = 100
WINDOW_BTN_CLOSE = 2 WINDOW_BTN_CLOSE = 2
WINDOW_BTN_LIST = 3 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 "" format binary as ""
@ -98,25 +100,31 @@ include "../../struct.inc"
include '../../develop/libraries/box_lib/trunk/box_lib.mac' include '../../develop/libraries/box_lib/trunk/box_lib.mac'
struct window struct window
data_ptr dd ? ; zero if not used data_ptr dd ?
flags db ? flags db ?
type db ? type db ?
name rb MAX_WINDOWNAME_LEN name rb MAX_WINDOWNAME_LEN
users dd ? users dd ?
users_scroll dd ? users_scroll dd ?
selected dd ? ; selected user, 0 if none selected 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 ends
struct window_data struct window_data
text rb 120*60 text rb TEXT_BUFFERSIZE
title rb 256
names rb MAX_NICK_LEN * MAX_USERS names rb MAX_NICK_LEN * MAX_USERS
usertext rb 256
usertextlen dd ?
ends ends
include "encodings.inc" include "encodings.inc"
include "window.inc" ; also contains text print routines include "window.inc"
include "serverparser.inc" include "serverparser.inc"
include "userparser.inc" include "userparser.inc"
include "socket.inc" include "socket.inc"
@ -160,26 +168,30 @@ START:
rep stosd rep stosd
; allocate window data block ; allocate window data block
call window_create
mov ebx, windows mov ebx, windows
mov [ebx + window.data_ptr], eax call window_create
mov [ebx + window.flags], 0 test eax, eax
jz error
mov [ebx + window.type], WINDOWTYPE_SERVER mov [ebx + window.type], WINDOWTYPE_SERVER
call window_refresh
; get system colors ; get system colors
mcall 48, 3, colors, 40 mcall 48, 3, colors, 40
; set edit box and scrollbar colors ; set edit box and scrollbar colors
mov eax, [colors.work] mov eax, [colors.work]
mov [scroll1.bg_color], eax mov [scroll1.bg_color], eax
mov [scroll2.bg_color], eax
mov eax, [colors.work_button] mov eax, [colors.work_button]
mov [scroll1.front_color], eax mov [scroll1.front_color], eax
mov [scroll2.front_color], eax
mov eax, [colors.work_text] mov eax, [colors.work_text]
mov [scroll1.line_color], eax 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 ; 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_nick, user_nick, MAX_NICK_LEN, default_nick
@ -190,13 +202,12 @@ START:
mov esi, str_welcome mov esi, str_welcome
call print_text2 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: redraw:
call draw_window call draw_window
still: still:
; wait here for event ; wait here for event
mcall 10 mcall 10
@ -214,15 +225,15 @@ still:
call process_network_event call process_network_event
mov edx, [window_active] mov edi, [window_active]
test [edx + window.flags], FLAG_UPDATED test [edi + window.flags], FLAG_UPDATED
jz .no_update 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 call draw_channel_text
mov edi, [window_active]
cmp [edi + window.type], WINDOWTYPE_CHANNEL
jne .no_update
call draw_channel_list
.no_update: .no_update:
call print_channel_list
jmp still jmp still
@ -236,8 +247,7 @@ button:
cmp ax, WINDOW_BTN_CLOSE cmp ax, WINDOW_BTN_CLOSE
jne @f jne @f
call cmd_usr_close_window
call window_close
jmp still jmp still
@@: @@:
@ -248,7 +258,7 @@ button:
mcall 37, 1 ; Get mouse position mcall 37, 1 ; Get mouse position
sub ax, TEXT_Y sub ax, TEXT_Y
mov bl, 10 mov bl, FONT_HEIGHT
div bl div bl
and eax, 0x000000ff and eax, 0x000000ff
inc eax inc eax
@ -256,7 +266,7 @@ button:
mov ebx, [window_active] mov ebx, [window_active]
mov [ebx + window.selected], eax mov [ebx + window.selected], eax
call print_channel_list call draw_channel_list
pop eax pop eax
test eax, 1 shl 25 ; Right mouse button pressed? test eax, 1 shl 25 ; Right mouse button pressed?
@ -283,15 +293,17 @@ button:
cmp ax, MAX_WINDOWS cmp ax, MAX_WINDOWS
ja exit ja exit
; OK, time to switch to another window.
mov dx, sizeof.window mov dx, sizeof.window
mul dx mul dx
shl edx, 16 shl edx, 16
mov dx, ax mov dx, ax
add edx, windows add edx, windows
cmp [edx + window.data_ptr], 0 cmp [edx + window.type], WINDOWTYPE_NONE
je exit je exit
mov [window_active], edx mov [window_active], edx
call window_refresh
mov [scroll2.position], 1 ;;; FIXME
call draw_window call draw_window
jmp still jmp still
@ -304,6 +316,8 @@ exit:
call cmd_usr_quit_server call cmd_usr_quit_server
@@: @@:
error:
mcall -1 mcall -1
@ -315,20 +329,32 @@ main_window_key:
push dword edit1 push dword edit1
call [edit_box_key] 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 cmp ah, 13 ; enter
jne no_send2 jne no_send2
call user_parser call user_parser
mov eax, [edit1.size]
mov [edit1.size], 0 mov [edit1.size], 0
mov [edit1.pos], 0 mov [edit1.pos], 0
push dword edit1 push dword edit1
call [edit_box_draw] call [edit_box_draw]
mov edx, [window_active]
mov edx, [edx + window.data_ptr]
add edx, window_data.text
call draw_channel_text call draw_channel_text
jmp still jmp still
@ -340,14 +366,31 @@ mouse:
push dword edit1 push dword edit1
call [edit_box_mouse] 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 [scroll1.position]
push dword scroll1 push dword scroll1
call [scrollbar_v_mouse] call [scrollbar_mouse]
pop eax pop eax
cmp eax, [scroll1.position] ; did the scrollbar move? cmp eax, [scroll1.position] ; did the scrollbar move?
je @f 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 jmp still
@ -361,9 +404,16 @@ db 'CP1251'
db 'UTF-8 ' db 'UTF-8 '
encoding_text_len = 6 encoding_text_len = 6
action_header db '*** ', 0 join_header db 3,'3* ', 0
action_header_short db '* ', 0 quit_header db 3,'5* ', 0
ctcp_header db '-> [',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_version db '] VERSION',10,0
ctcp_ping db '] PING',10,0 ctcp_ping db '] PING',10,0
ctcp_time db '] TIME',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_talking db 'Now talking in ',0
str_topic db 'Topic is ',0 str_topic db 'Topic is ',0
str_setby db 'Set by ',0 str_setby db 'Set by ',0
str_reconnect db 'Connection reset by user.',10,0
str_version db 'VERSION ' str_version db 'VERSION '
str_programname db 'KolibriOS IRC client ', version, 0 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_real db 'Kolibri User', 0
default_quit db 'KolibriOS forever', 0 default_quit db 'KolibriOS forever', 0
str_welcome db 10 str_welcome db 3,'3 ___',3,'7__________',3,'6_________ ',3,'4 __ __ __',10
db ' ______________________ __ __ __',10 db 3,'3| \',3,'7______ \',3,'6_ ___ \ ',3,'4 ____ | | |__| ____ _____/ |_',10
db '| \______ \_ ___ \ ____ | | |__| ____ _____/ |_',10 db 3,'3| |',3,'7| _/',3,'6 \ \/ ',3,'4 _/ ___\| | | |/ __ \ / \ __\',10
db '| || _/ \ \/ _/ ___\| | | |/ __ \ / \ __\',10 db 3,'3| |',3,'7| | \',3,'6 \____',3,'4 \ \___| |_| \ ___/| | \ |',10
db '| || | \ \____ \ \___| |_| \ ___/| | \ |',10 db 3,'3|___|',3,'7|____|_ /\',3,'6______ /',3,'4 \___ >____/__|\___ >___| /__|',10
db '|___||____|_ /\______ / \___ >____/__|\___ >___| /__|',10 db 3,'3 ',3,'7 \/ ',3,'6 \/ ',3,'4 \/ \/ \/',10
db ' \/ \/ \/ \/ \/',10
db 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 10
db 'Type /help for help',10,0 db 'Type /help for help',10,10,0
str_nickchange db 'Nickname is now ',0 str_nickchange db 'Nickname is now ',0
str_realchange db 'Real name is now ',0 str_realchange db 'Real name is now ',0
str_dotnewline db '.',10, 0 str_dotnewline db '.',10, 0
str_newline 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 str_help db 10,'following commands are available:',10
db 10 db 10
db '/nick <nick> : change nickname to <nick>',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 '/server <address> : connect to server <address>',10
db '/code <code> : change codepage to cp866, cp1251, or utf8',10,0 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_2 db '- ',0
str_sockerr db 'Socket Error',10,0 str_sockerr db 'Socket Error',10,0
str_dnserr db 'Unable to resolve hostname.',10,0 str_dnserr db 'Unable to resolve hostname.',10,0
str_refused db 'Connection refused',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: sockaddr1:
dw AF_INET4 dw AF_INET4
.port dw 0x0b1a ; 6667 .port dw 0x0b1a ; 6667
@ -430,9 +497,9 @@ sockaddr1:
status dd STATUS_DISCONNECTED status dd STATUS_DISCONNECTED
text_start dd ? ; pointer to current textbox data
textbox_width dd 80 ; in characters, not pixels ;) textbox_height dd 12 ; in characters
text_pos dd ? ; text writing cursor textbox_width dd 78 ; in characters, not pixels ;)
window_active dd windows window_active dd windows
window_print dd windows window_print dd windows
@ -454,24 +521,23 @@ import libini,\
ini.get_int, 'ini_get_int' ini.get_int, 'ini_get_int'
import boxlib,\ import boxlib,\
edit_box_draw ,'edit_box' ,\ edit_box_draw, 'edit_box',\
edit_box_key ,'edit_box_key' ,\ edit_box_key, 'edit_box_key',\
edit_box_mouse ,'edit_box_mouse' ,\ edit_box_mouse, 'edit_box_mouse',\
scrollbar_v_draw ,'scrollbar_v_draw' ,\ scrollbar_draw, 'scrollbar_v_draw',\
scrollbar_v_mouse,'scrollbar_v_mouse' scrollbar_mouse,'scrollbar_v_mouse'
I_END: I_END:
; width, left, top ; width, left, top
edit1 edit_box 0, 0, 0, 0xffffff, 0x6f9480, 0, 0, 0, USERCMD_MAX_SIZE, usercommand, mouse_dd, ed_focus, 25, 25 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 ; xsize, xpos, ysize, ypos, btn_height, max, cur, pos, bgcol, frcol, linecol
scroll1 scrollbar SCROLLBAR_WIDTH, 300, 150, TOP_Y, 10, 100, 0, 0, 0, 0, 0, 1 scroll1 scrollbar SCROLLBAR_WIDTH, 0, 0, TOP_Y, SCROLLBAR_WIDTH, 0, 0, 0, 0, 0, 0, 1
scroll2 scrollbar SCROLLBAR_WIDTH, 300, 150, TOP_Y, 10, 100, 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 usercommand db '/server chat.freenode.net', 0
rb MAX_COMMAND_LEN rb MAX_COMMAND_LEN
main_PID dd ? ; identifier of main thread
utf8_bytes_rest dd ? ; bytes rest in current UTF8 sequence utf8_bytes_rest dd ? ; bytes rest in current UTF8 sequence
utf8_char dd ? ; first bits of current UTF8 character utf8_char dd ? ; first bits of current UTF8 character
gai_reqdata rb 32 ; buffer for getaddrinfo_start/process gai_reqdata rb 32 ; buffer for getaddrinfo_start/process

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
@ -48,7 +49,9 @@ server_commands:
dd '322 ', cmd_322 ; RPL_LIST dd '322 ', cmd_322 ; RPL_LIST
dd '323 ', cmd_323 ; RPL_LISTEND dd '323 ', cmd_323 ; RPL_LISTEND
dd '324 ', cmd_324 ;;;;
dd '328 ', cmd_328 ; RPL_CHANNEL_URL dd '328 ', cmd_328 ; RPL_CHANNEL_URL
dd '329 ', cmd_329
dd '332 ', cmd_topic dd '332 ', cmd_topic
dd '333 ', cmd_333 ; nickname and time of topic dd '333 ', cmd_333 ; nickname and time of topic
dd '353 ', cmd_353 ; name reply dd '353 ', cmd_353 ; name reply
@ -110,6 +113,8 @@ compare_to_nick:
pop esi pop esi
ret ret
align 4 align 4
skip_nick: skip_nick:
@ -135,6 +140,8 @@ skip_nick:
cmd_324:
cmd_329:
cmd_328: cmd_328:
cmd_421: cmd_421:
cmd_372: cmd_372:
@ -149,11 +156,16 @@ cmd_notice:
jne .gogogo jne .gogogo
mov byte [esi-1], 0 mov byte [esi-1], 0
if TIMESTAMP
call print_timestamp
end if
push esi push esi
mov esi, str_1 mov esi, str_1
call print_text2 call print_text2
mov esi, servercommand+1 mov eax, servercommand+1
call print_text2 mov dl, '!'
call print_text
mov esi, str_2 mov esi, str_2
call print_text2 call print_text2
pop esi pop esi
@ -177,12 +189,11 @@ cmd_notice:
cmp byte [esi], ':' cmp byte [esi], ':'
je .loop2 je .loop2
.fail:
call print_text2 call print_text2
mov esi, str_newline mov esi, str_newline
call print_text2 call print_text2
.fail:
ret ret
@ -212,19 +223,20 @@ cmd_ping:
cmd_privmsg: cmd_privmsg:
mov eax, dword[esi+4]
or eax, 0x20202020
cmp eax, 'msg '
jne .fail
add esi, 8 ; skip 'PRIVMSG ' add esi, 8 ; skip 'PRIVMSG '
call window_open ; esi now points to end of destination name 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 je cmd_ctcp
cmp dword[esi], 'ACTI' ; Action? ; nope, just plain old privmsg, print it using '<nick> message' format
je .action if TIMESTAMP
; nope, just plain old privmsg
if TIMESTAMP
call print_timestamp call print_timestamp
end if end if
push esi push esi
mov bl, '<' mov bl, '<'
@ -249,49 +261,36 @@ end if
.fail: .fail:
ret 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: cmd_ctcp:
cmp byte [esi+4], ' '
jne .fail
inc esi inc esi
mov eax, dword[esi]
or eax, 0x20202020
cmp dword[esi], 'VERS' cmp eax, 'vers'
je .version je .version
cmp eax, 'time'
cmp dword[esi], 'TIME'
je .time je .time
cmp eax, 'ping'
cmp dword[esi], 'PING'
je .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 ret
.time: .time:
mov byte [esi+4], ' ' mov byte[esi+4], ' '
lea edi, [esi+5] lea edi, [esi+5]
; TODO: add system date (fn 29) in human readable format ; TODO: add system date (fn 29) in human readable format
@ -375,12 +374,52 @@ cmd_ctcp:
ret 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: ctcp_reply:
push esi push esi
mov dword [usercommand], 'NOTI' mov dword [usercommand], 'NOTI'
mov dword [usercommand+4], 'CE ' mov dword [usercommand+4], 'CE '
@ -425,27 +464,34 @@ ctcp_reply:
cmd_part: cmd_part:
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'PART ' add esi, 5 ; skip 'PART '
push esi
call skip_nick
call window_open
pop esi
; Is it me who parted? ; Is it me who parted?
mov edi, servercommand+1 mov edi, servercommand+1
call compare_to_nick call compare_to_nick
jne .dont_close jne .dont_close
; yes, close the window ; yes, close the window (if its open)
mov edi, [window_print] call window_find
mov [edi + window.flags], FLAG_UPDATED + FLAG_CLOSE test ebx, ebx
jz @f
call window_close
@@:
.fail:
ret ret
; somebody else parted, just print message ; somebody else parted, just print message
.dont_close: .dont_close:
push esi push esi
mov esi, action_header call skip_nick
call window_open
mov esi, part_header
call print_text2 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
@ -471,6 +517,9 @@ cmd_part:
cmd_join: cmd_join:
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'JOIN ' add esi, 5 ; skip 'JOIN '
; compare nick: did we join a channel? ; compare nick: did we join a channel?
@ -488,27 +537,26 @@ cmd_join:
dec ecx dec ecx
jnz .loop jnz .loop
; Error: no more available windows!! ;;;;; TODO ; Error: no more available windows!! ;;;;; TODO
.fail:
ret ret
.free_found: .free_found:
push ebx
call window_create call window_create
pop ebx
test eax, eax test eax, eax
jz .fail jz .fail
mov [ebx + window.data_ptr], eax
mov [ebx + window.type], WINDOWTYPE_CHANNEL mov [ebx + window.type], WINDOWTYPE_CHANNEL
mov [ebx + window.flags], 0
call window_set_name call window_set_name
mov [window_active], ebx mov [window_active], ebx
mov [window_print], ebx mov [window_print], ebx
call window_refresh
if TIMESTAMP
call print_timestamp
end if
push esi push esi
mov esi, action_header mov esi, join_header
call print_text2 call print_text2
mov esi, str_talking mov esi, str_talking
@ -529,7 +577,11 @@ cmd_join:
push esi push esi
call window_open call window_open
mov esi, action_header if TIMESTAMP
call print_timestamp
end if
mov esi, join_header
call print_text2 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
@ -549,58 +601,71 @@ cmd_join:
mov esi, servercommand+1 mov esi, servercommand+1
call user_add call user_add
.fail:
ret ret
cmd_nick: 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 jne @f
inc esi 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? ; Is it me who changed nick?
push esi
mov edi, servercommand+1 mov edi, servercommand+1
call compare_to_nick call compare_to_nick
pop esi
jne .not_me jne .not_me
mov ecx, MAX_NICK_LEN-1 mov ecx, MAX_NICK_LEN-1
push esi mov esi, [esp]
.copyloop: @@:
lodsb lodsb
test al, al test al, al
jz .copydone jz @f
cmp al, ' ' cmp al, ' '
je .copydone je @f
cmp al, 10
je @f
cmp al, 13
je @f
stosb stosb
dec ecx dec ecx
jnz .copyloop jnz @r
.copydone: @@:
xor al, al xor al, al
stosb stosb
pop esi
.not_me: .not_me:
; Now print a message on the current channel mov ebx, windows
push esi mov ecx, MAX_WINDOWS
mov esi, action_header_short .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 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
@ -610,18 +675,31 @@ cmd_nick:
mov esi, is_now_known_as mov esi, is_now_known_as
call print_text2 call print_text2
pop esi mov esi, [esp + 8] ; FIXME: dont print the 0x0a0d!!!
call print_text2 call print_text2
mov esi, str_newline mov esi, str_newline
call print_text2 call print_text2
.next_window:
pop ebx ecx
add ebx, sizeof.window
dec ecx
jnz .window_loop
pop esi
.fail:
ret ret
cmd_kick: cmd_kick:
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'KICK ' add esi, 5 ; skip 'KICK '
; Is it me who got kicked? ; Is it me who got kicked?
mov edi, servercommand+1 mov edi, servercommand+1
@ -636,7 +714,11 @@ cmd_kick:
call skip_nick call skip_nick
call window_open call window_open
mov esi, action_header_short if TIMESTAMP
call print_timestamp
end if
mov esi, kick_header
call print_text2 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
@ -656,14 +738,38 @@ cmd_kick:
mov esi, servercommand+1 mov esi, servercommand+1
call user_remove call user_remove
.fail:
ret ret
cmd_quit: 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 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
@ -673,10 +779,16 @@ cmd_quit:
mov esi, has_quit_irc mov esi, has_quit_irc
call print_text2 call print_text2
; TODO: check other channels on same server too! ; TODO: check if quit message was given, and print it to the window
mov ebx, [window_print] pop ebx
mov esi, servercommand+1 .next_window:
call user_remove pop ecx
add ebx, sizeof.window
dec ecx
jnz .window_loop
.fail:
ret ret
@ -684,14 +796,35 @@ cmd_quit:
cmd_mode: cmd_mode:
cmp byte [esi+4], ' '
jne .fail
add esi, 5 ; skip 'MODE ' 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 push esi
mov esi, action_header_short
if TIMESTAMP
call print_timestamp
end if
mov esi, mode_header
call print_text2 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
mov dl, ' ' mov dl, '!'
call print_text call print_text
mov esi, sets_mode mov esi, sets_mode
@ -705,6 +838,8 @@ cmd_mode:
;;; TODO: change username if needed ;;; TODO: change username if needed
.fail:
ret ret
@ -739,7 +874,7 @@ cmd_353: ; channel usernames reply
jmp .add jmp .add
.done: .done:
call redraw_channel_list call draw_channel_list
ret ret
@ -767,8 +902,12 @@ cmd_topic:
call skip_nick call skip_nick
call window_open call window_open
if TIMESTAMP
call print_timestamp
end if
push esi push esi
mov esi, action_header mov esi, topic_header
call print_text2 call print_text2
mov esi, str_topic mov esi, str_topic
@ -799,8 +938,12 @@ cmd_333:
; dec ecx ; dec ecx
; jnz .loop ; find some more spaces ; jnz .loop ; find some more spaces
if TIMESTAMP
call print_timestamp
end if
push esi push esi
mov esi, action_header mov esi, topic_header
call print_text2 call print_text2
mov esi, str_setby mov esi, str_setby
@ -819,18 +962,20 @@ cmd_333:
.fail: .fail:
ret ret
cmd_322: cmd_322: ; LIST
add esi, 4 add esi, 4
mov [window_print], windows ; FIXME
call skip_nick call skip_nick
mov eax, esi
call print_text2 mov dl, 13
call print_text
mov esi, str_newline mov esi, str_newline
call print_text2 call print_text2
ret ret
cmd_323: cmd_323: ; LIST END
ret ret

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
@ -12,13 +13,13 @@
socket_connect: socket_connect:
; cmp [status], STATUS_CONNECTED ; TODO
; je disconnect
; ignore if status is not "disconnected" ; ignore if status is not "disconnected"
cmp [status], STATUS_DISCONNECTED cmp [status], STATUS_DISCONNECTED
jne .nothing jne .reconnect
if TIMESTAMP
call print_timestamp
end if
mov esi, str_connecting mov esi, str_connecting
call print_text2 call print_text2
mov esi, irc_server_name mov esi, irc_server_name
@ -63,12 +64,14 @@ socket_connect:
cmp eax, -1 cmp eax, -1
jz .fail_refused jz .fail_refused
.nothing:
ret ret
.fail: .fail:
mov [status], STATUS_DISCONNECTED mov [status], STATUS_DISCONNECTED
if TIMESTAMP
call print_timestamp
end if
mov esi, str_sockerr mov esi, str_sockerr
call print_text2 call print_text2
@ -77,6 +80,9 @@ socket_connect:
.fail_dns: .fail_dns:
mov [status], STATUS_DISCONNECTED mov [status], STATUS_DISCONNECTED
if TIMESTAMP
call print_timestamp
end if
mov esi, str_dnserr mov esi, str_dnserr
call print_text2 call print_text2
@ -85,11 +91,26 @@ socket_connect:
.fail_refused: .fail_refused:
mov [status], STATUS_DISCONNECTED mov [status], STATUS_DISCONNECTED
if TIMESTAMP
call print_timestamp
end if
mov esi, str_refused mov esi, str_refused
call print_text2 call print_text2
ret 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: socket_write_userinfo:
@ -180,25 +201,11 @@ process_network_event:
inc [status] inc [status]
.connected: .connected:
call read_incoming_data call socket_receive
ret ret
disconnect: socket_receive:
cmp [status], STATUS_DISCONNECTED
je .nothing
mcall close, [socketnum]
mov [status], STATUS_DISCONNECTED
.nothing:
ret
read_incoming_data:
pusha pusha

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; 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 print_text: ; eax = start ptr
; dl = end char ; dl = end char
pusha pusha
@ -27,6 +93,7 @@ print_text: ; eax = start ptr
.done: .done:
popa popa
ret ret
@ -44,80 +111,253 @@ print_text2: ; esi = ptr to ASCIIZ string
.done: .done:
popa popa
ret ret
; Character in bl
print_character: print_character:
pusha push esi edi
mov ecx, TEXTBOX_LINES mov esi, [window_print]
imul ecx, [textbox_width] mov edi, [esi + window.text_write]
mov esi, [text_start] 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 ret
.uh_ow:
draw_channel_text: ; edx = pointer to text
pusha 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 ebx, [window_print]
mov ecx, TEXTBOX_LINES 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: .drawloop:
cmp byte[edx], 0
je .end
; Clear one row of characters
pusha pusha
mov cx, bx mov cx, bx
shl ecx, 16 shl ecx, 16
mov cx, 9 ; character height mov cx, FONT_HEIGHT
mov ebx, TEXT_X shl 16 mov ebx, TEXT_X shl 16
mov bx, word[textbox_width] mov bx, word[textbox_width]
imul bx, 6 ; character width imul bx, FONT_WIDTH
mov edx, [colors.work] mov edx, [colors.work]
mcall 13 ; draw rectangle mcall 13 ; draw rectangle
popa popa
push ecx mov esi, edx
mov ecx, [colors.work_text] 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: .draw:
mov esi, [textbox_width] mov esi, 1
mcall 4 ; draw text mcall 4 ; draw text
add edx, [textbox_width] add ebx, FONT_WIDTH shl 16
add ebx, 10 ; height distance between lines inc edx
pop eax esi
cmp edx, esi
jb .line
jmp .line_full
pop ecx .newline_hard:
loop .drawloop 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] ; take care of the scrollbar
and [eax + window.flags], not FLAG_UPDATED ; clear the 'window is updated' flag .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 popa
ret ret
end if

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
@ -12,6 +13,9 @@
user_parser: user_parser:
push [window_active] ; print to the current window
pop [window_print]
mov eax, [edit1.size] mov eax, [edit1.size]
test eax, eax test eax, eax
jz sdts_ret ; ignore empty commands jz sdts_ret ; ignore empty commands
@ -25,16 +29,11 @@ user_parser:
jne sdts_ret jne sdts_ret
; Ok, we said something, print it to our textbox ; Ok, we said something, print it to our textbox
; TODO: dont send if it's a server window? ; TODO: dont send if it's a server window?
push [window_active] ; print to the current window if TIMESTAMP
pop [window_print]
call window_refresh
if TIMESTAMP
call print_timestamp call print_timestamp
end if end if
mov bl, '<' mov bl, '<'
call print_character call print_character
@ -57,9 +56,8 @@ user_parser:
call print_character call print_character
; and now send it to the server ; and now send it to the server
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf], 'priv' mov dword[packetbuf+4], 'MSG '
mov dword[packetbuf+4], 'msg '
mov esi, [window_active] mov esi, [window_active]
add esi, window.name add esi, window.name
@ -82,8 +80,9 @@ user_parser:
inc ecx inc ecx
call recode call recode
mov al, 10 ; end the command with a CRLF
stosb mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf] lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0 mcall send, [socketnum], packetbuf, , 0
@ -100,10 +99,13 @@ user_commands:
dd 'serv', cmd_usr_server dd 'serv', cmd_usr_server
dd 'help', cmd_usr_help dd 'help', cmd_usr_help
dd 'code', cmd_usr_code 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 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit dd 'quit', cmd_usr_quit
dd 'part', cmd_usr_part dd 'part', cmd_usr_part
dd 'ctcp', cmd_usr_ctcp
dd 'msg ', cmd_usr_msg
.number = ($ - user_commands) / 8 .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 mov esi, quit_msg
cmp byte[usercommand+5], ' ' cmp byte[usercommand+5], ' '
jne .default_msg jne .with_message
lea esi,[usercommand+6] lea esi, [usercommand+6]
.default_msg: .with_message:
call cmd_usr_quit_server call cmd_usr_quit_server
mcall close, [socketnum] mcall close, [socketnum]
mov [status], STATUS_DISCONNECTED
mov ecx, MAX_WINDOWS mov ecx, MAX_WINDOWS
mov edi, windows mov edi, windows
.loop: .loop:
mov [edi + window.flags], FLAG_CLOSE mov [window_print], edi
push edi ecx
call window_close
pop ecx edi
add edi, sizeof.window add edi, sizeof.window
dec ecx dec ecx
jnz .loop jnz .loop
@ -165,11 +239,14 @@ cmd_usr_quit_server:
; Append our quit msg ; Append our quit msg
@@: @@:
lodsb lodsb
stosb cmp al, 13
je @f
test al, al test al, al
jnz @r jz @f
stosb
jmp @r
@@:
; end the command with a CRLF ; end the command with a CRLF
dec edi
mov ax, 0x0a0d mov ax, 0x0a0d
stosw stosw
@ -184,31 +261,37 @@ cmd_usr_quit_server:
cmd_usr_nick: cmd_usr_nick:
cmp [edit1.size], 5 cmp [edit1.size], 5
je .justprint je .dontsend
cmp byte[usercommand+5], ' ' 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 ecx, MAX_NICK_LEN
mov esi, usercommand+6 mov esi, usercommand+6
mov edi, user_nick mov edi, user_nick
.loop: @@:
lodsb lodsb
cmp al, 13 cmp al, 13
je .done je @f
stosb stosb
dec ecx dec ecx
jnz .loop jnz @r
.done: @@:
xor al, al xor al, al
stosb stosb
cmp [socketnum], 0
je .justprint
lea esi, [edi - usercommand]
mcall send, [socketnum], usercommand+1, , 0
.justprint:
mov esi, str_nickchange mov esi, str_nickchange
call print_text2 call print_text2
mov esi, user_nick mov esi, user_nick
@ -299,13 +382,11 @@ cmd_usr_quer:
call window_create call window_create
test eax, eax test eax, eax
jz .error jz .error
mov [ebx + window.data_ptr], eax mov [ebx + window.type], WINDOWTYPE_CHAT
mov esi, usercommand+7 mov esi, usercommand+7
call window_set_name call window_set_name
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
.error: .error:
@ -333,18 +414,33 @@ cmd_usr_code:
; User typed a part command ; User typed a part command
cmd_usr_part: cmd_usr_part:
cmp byte[usercommand+5], 13 ; parameters given? 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 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 ret
; Send part command to server ; Send part command to server
; esi must point to channel name (ASCIIZ) ; esi must point to channel name (ASCIIZ)
cmd_usr_part_channel: cmd_usr_part_channel:
@ -355,11 +451,16 @@ cmd_usr_part_channel:
lea edi, [packetbuf+5] lea edi, [packetbuf+5]
@@: @@:
lodsb lodsb
stosb
test al, al 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 ; end the command with a CRLF
dec edi
mov ax, 0x0a0d mov ax, 0x0a0d
stosw stosw
@ -369,6 +470,63 @@ cmd_usr_part_channel:
ret 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 ; The user typed some undefined command, just recode it and send to the server
cmd_usr_send: cmd_usr_send:
@ -383,3 +541,7 @@ cmd_usr_send:
ret ret

View File

@ -3,12 +3,17 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; 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 ; esi is ptr to nick
; ebx is ptr to window ; ebx is ptr to window
@ -21,7 +26,7 @@ user_add:
mov edi, [ebx + window.data_ptr] mov edi, [ebx + window.data_ptr]
add edi, window_data.names add edi, window_data.names
mov ebp, [ebx + window.users] mov ebp, [ebx + window.users]
inc ebp ; CHECKME inc ebp ; CHECKME
push esi edi push esi edi
.restart: .restart:
@ -78,8 +83,7 @@ user_add:
; mov all trailing usernames by MAX_NICK_LEN bytes ; mov all trailing usernames by MAX_NICK_LEN bytes
push esi edi push esi edi
mov esi, [ebx + window.data_ptr] 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 mov ecx, esi
sub ecx, edi sub ecx, edi
add ecx, MAX_NICK_LEN add ecx, MAX_NICK_LEN
@ -98,6 +102,10 @@ user_add:
je .done je .done
cmp al, '!' cmp al, '!'
je .done je .done
cmp al, 13
je .done
cmp al, 10
je .done
stosb stosb
loop .fill loop .fill
.done: .done:
@ -105,6 +113,7 @@ user_add:
stosb stosb
inc [ebx + window.users] inc [ebx + window.users]
or [ebx + window.flags], FLAG_UPDATED
ret ret
@ -128,7 +137,7 @@ user_remove:
rep movsd rep movsd
dec [ebx + window.users] dec [ebx + window.users]
xor eax, eax or [ebx + window.flags], FLAG_UPDATED
ret ret

View File

@ -3,6 +3,7 @@
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;; ;; ;;
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
@ -10,11 +11,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; in: window ptr in ebx
; out: eax = 0 on error
window_create: window_create:
push ebx
; allocate the window data block ; allocate the window data block
mcall 68, 12, sizeof.window_data mcall 68, 12, sizeof.window_data
test eax, eax test eax, eax
pop ebx
jz .fail jz .fail
; fill it with all zeros ; fill it with all zeros
@ -25,6 +30,19 @@ window_create:
rep stosd rep stosd
pop eax 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: .fail:
ret 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: window_is_updated:
mov edi, [window_print] mov edi, [window_print]
cmp edi, [window_active]
je .skip
test [edi + window.flags], FLAG_UPDATED test [edi + window.flags], FLAG_UPDATED
jnz .skip jnz .skip
or [edi + window.flags], FLAG_UPDATED or [edi + window.flags], FLAG_UPDATED
; now play a sound :) ; TODO: make some noise
call draw_windowtabs ; highlight updated tabs call draw_windowtabs ; highlight updated tabs
.skip: .skip:
@ -97,19 +99,10 @@ window_is_updated:
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) ; 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 push [edi + window.data_ptr] ; remember data ptr so we can free it later
lea esi, [edi + sizeof.window] lea esi, [edi + sizeof.window]
mov ecx, windows + MAX_WINDOWS*sizeof.window mov ecx, windows + MAX_WINDOWS*sizeof.window
@ -131,7 +124,7 @@ window_close:
jne @f jne @f
sub edi, sizeof.window sub edi, sizeof.window
mov [window_active], edi mov [window_active], edi
mov [window_print], edi mov [window_print], edi ;;;;;;;;
@@: @@:
; At last, redraw everything ; 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 ; open a window with a given name, if it does not exist, create it
; This procedure only affects window_print ptr, not window_active! ; This procedure only affects window_print ptr, not window_active!
@ -157,22 +190,9 @@ window_open:
mov esi, servercommand+1 mov esi, servercommand+1
.nochat: .nochat:
; now search for window in list call window_find
mov ebx, windows test ebx, ebx
mov [window_print], ebx ; set first window (server window) as default output window jne .got_it
.scanloop:
cmp [ebx + window.data_ptr], 0
je .create_it
push esi
lea edi, [ebx + window.name]
mov ecx, MAX_WINDOWNAME_LEN
repe cmpsb
pop esi
cmp byte[edi-1], 0
je .got_it
add ebx, sizeof.window
; TODO: check buffer limits ?
jmp .scanloop
; create channel window - search for empty slot ; create channel window - search for empty slot
.create_it: .create_it:
@ -185,31 +205,20 @@ window_open:
dec ecx dec ecx
jnz .scanloop2 jnz .scanloop2
; Error: no more available windows! ; Error: no more available windows!
jmp .just_skip jmp .got_it ; TODO: return error
.free_found: .free_found:
push ebx
call window_create call window_create
pop ebx
test eax, eax test eax, eax
jz .just_skip jz .got_it ; TODO: return error
mov [ebx + window.data_ptr], eax mov [ebx + window.type], WINDOWTYPE_CHAT ; FIXME: let caller handle this ?
mov [ebx + window.type], WINDOWTYPE_CHAT
mov [ebx + window.flags], 0
call window_set_name call window_set_name
mov [window_print], ebx mov [window_print], ebx
call window_refresh
call draw_windowtabs call draw_windowtabs
jmp .just_skip
; found it!
.got_it: .got_it:
mov [window_print], ebx
call window_refresh
.just_skip:
pop esi pop esi
.skip1: .skip1:
; skip text ; skip text
@ -232,42 +241,3 @@ window_open:
.quit: .quit:
ret 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