diff --git a/README.md b/README.md index b3c9e90..2f47a41 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Simple serial terminal for KolibriOS. +![screenshot](screenshot.png) + # Requirements - [Fasm](https://flatassembler.net/) 1.7x diff --git a/icons.png b/icons.png index c1ba64d..b420b22 100644 Binary files a/icons.png and b/icons.png differ diff --git a/kterm.asm b/kterm.asm index 1bea7a2..1395db6 100644 --- a/kterm.asm +++ b/kterm.asm @@ -33,7 +33,7 @@ BTN_SEND = 5 BTN_OK = 2 BTN_CANCEL = 3 -__DEBUG__ = 0 +__DEBUG__ = 1 __DEBUG_LEVEL__ = 0 include '../../proc32.inc' @@ -43,8 +43,8 @@ include '../../dll.inc' include '../../debug-fdo.inc' include '../../develop/libraries/box_lib/trunk/box_lib.mac' include '../../../drivers/serial/common.inc' -include 'textview.asm' -include 'utils.asm' +include 'textview.inc' +include 'utils.inc' start: mcall SF_SYS_MISC, SSF_HEAP_INIT @@ -54,7 +54,7 @@ start: or eax, eax jnz .exit - mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_MOUSE_FILTER + EVM_REDRAW + EVM_BUTTON + EVM_KEY + mcall SF_SET_EVENTS_MASK, EVM_MOUSE + EVM_REDRAW + EVM_BUTTON + EVM_KEY mov byte [ed_send_val], 0 stdcall text_view_init, text_view @@ -69,7 +69,16 @@ start: dec eax jz .btn invoke edit_box_mouse, ed_send + push [vscroll.position] invoke scrollbar_mouse, vscroll + pop eax + cmp eax, [vscroll.position] + je @f + mov eax, [vscroll.position] + mov [text_view.curr_line], eax + DEBUGF 0, "vscroll.position=%d\n", eax + stdcall text_view_draw, text_view + @@: jmp .loop .win: call .draw_window @@ -93,7 +102,10 @@ start: @@: cmp ah, BTN_CLEAR jne @f - ; TODO + stdcall text_view_clear, text_view + stdcall text_view_draw, text_view + call update_vscroll + invoke scrollbar_draw, vscroll jmp .loop @@: cmp ah, BTN_SEND @@ -134,6 +146,7 @@ start: mcall SF_DEFINE_BUTTON, <59, 24>, <5, 24>, BTN_CLEAR, [sc.work_light] mcall SF_PUT_IMAGE_EXT, icons, <20, 20>, <3, 7>, 1, icons.palette, 0 + mcall SF_PUT_IMAGE_EXT, icons + 180, <20, 20>, <61, 7>, 1, icons.palette, 0 mov ebx, icons + 60 ; disconnected icon mov al, [is_connected] @@ -180,6 +193,7 @@ start: sub eax, 2 * FONT_HEIGHT + WIN_BORDER_WIDTH + 14 + SCROLL_TOP mov [vscroll.y_size], ax + call update_vscroll invoke scrollbar_draw, vscroll ; editbox and send button @@ -352,15 +366,29 @@ show_conn_window: mcall SF_REDRAW, SSF_END_DRAW ret -send_text: - stdcall text_view_append_line, text_view, ed_send_val - xor eax, eax - push eax - invoke edit_box_set_text, ed_send, esp - pop eax - stdcall text_view_draw, text_view - invoke edit_box_draw, ed_send - ret + +proc send_text + stdcall text_view_append_line, text_view, ed_send_val + xor eax, eax + push eax + invoke edit_box_set_text, ed_send, esp + pop eax + stdcall text_view_draw, text_view + invoke edit_box_draw, ed_send + call update_vscroll + invoke scrollbar_draw, vscroll + ret +endp + +proc update_vscroll + mov eax, [text_view.total_lines] + mov [vscroll.max_area], eax + mov eax, [text_view.rows] + mov [vscroll.cur_area], eax + mov eax, [text_view.curr_line] + mov [vscroll.position], eax + ret +endp align 16 @IMPORT: @@ -409,14 +437,14 @@ port_conf: db 8, 1, SERIAL_CONF_PARITY_NONE, SERIAL_CONF_FLOW_CTRL_NONE port_conf_end: -if __DEBUG__ eq 1 +;if __DEBUG__ eq 1 include_debug_strings -end if +;end if ; https://javl.github.io/image2cpp/ icons: - ; 'icons', 20x60px - db 0xff, 0xff, 0xf0, 0xfc, 0xff, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf + ; 'icons', 20x80px + db 0xff, 0xff, 0xf0, 0xfc, 0x7f, 0xf0, 0xf8, 0x3f, 0xf0, 0xf8, 0x1f, 0xf0, 0xfe, 0x1f, 0xf0, 0xdf db 0x1f, 0xf0, 0x8e, 0x1f, 0xf0, 0xa4, 0x3f, 0xf0, 0x90, 0x1f, 0xf0, 0xc8, 0x0f, 0xf0, 0xe0, 0x07 db 0xf0, 0xfe, 0x43, 0xf0, 0xff, 0x21, 0xf0, 0xff, 0x90, 0xf0, 0xff, 0xc8, 0x70, 0xff, 0xe4, 0x30 db 0xff, 0xf0, 0x70, 0xff, 0xf8, 0xf0, 0xff, 0xfd, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff @@ -427,7 +455,10 @@ icons: db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0x0f, 0xf0, 0xfe, 0x07, 0xf0, 0xfe, 0x07, 0xf0 db 0xfc, 0x03, 0xf0, 0x80, 0x00, 0x10, 0x80, 0x00, 0x10, 0xfc, 0x03, 0xf0, 0xfe, 0x07, 0xf0, 0xfe db 0x07, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0x9f, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff - db 0xf0, 0xff, 0xff, 0xf0 + db 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xe3, 0xf0 + db 0xff, 0xc9, 0xf0, 0xff, 0x9c, 0xf0, 0xff, 0x3e, 0x70, 0xfe, 0x7f, 0x70, 0xfc, 0x7f, 0x70, 0xf9 + db 0x3e, 0x70, 0xf3, 0x9c, 0xf0, 0xe7, 0xc9, 0xf0, 0xef, 0xe3, 0xf0, 0xe7, 0xe7, 0xf0, 0xf3, 0xcf + db 0xf0, 0xf9, 0x9f, 0xf0, 0xfc, 0x00, 0x70, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xf0 .palette: dd 0xffffff dd 0x000000 diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..f4c442d Binary files /dev/null and b/screenshot.png differ diff --git a/textview.asm b/textview.inc similarity index 62% rename from textview.asm rename to textview.inc index f4759bb..ceaadaa 100644 --- a/textview.asm +++ b/textview.inc @@ -1,4 +1,5 @@ BUF_SIZE = 4096 +FRM_WIDTH = 1 MARGIN = 1 struct TEXT_VIEW @@ -16,7 +17,7 @@ struct TEXT_VIEW total_lines dd ? curr_line dd ? - max_length dd ? + max_length dd ? ; length of the longest string rows dd ? cols dd ? @@ -45,59 +46,40 @@ proc text_view_deinit stdcall uses ebx, text_view:dword endp proc text_view_draw stdcall uses ebx esi edi, text_view:dword - ; draw frame and background mov esi, [text_view] + call tv.draw_frame_and_bg + call tv.calc_rows_and_cols + DEBUGF 0, "text_view rows=%d cols=%d\n", [esi + TEXT_VIEW.rows], [esi + TEXT_VIEW.cols] + + mov eax, [esi + TEXT_VIEW.curr_line] + mov ebx, [esi + TEXT_VIEW.total_lines] + DEBUGF 0, "text_view curr_line=%d total_lines=%d\n", eax, ebx + sub ebx, eax + cmp ebx, [esi + TEXT_VIEW.rows] + jbe @f + mov ebx, [esi + TEXT_VIEW.rows] + @@: + mov edi, [esi + TEXT_VIEW.buf_data] + call goto_curr_line + mov ecx, ebx ; ecx = count lines + xor eax, eax ; eax = index from 0 + mov ebx, [esi + TEXT_VIEW.left] - shl ebx, 16 - add ebx, [esi + TEXT_VIEW.width] - mov ecx, [esi + TEXT_VIEW.top] - shl ecx, 16 - add ecx, [esi + TEXT_VIEW.height] - mov edx, [esi + TEXT_VIEW.fg_color] - call draw_frame - add ebx, 1 shl 16 - sub ebx, 2 - add ecx, 1 shl 16 - sub ecx, 2 - mov edx, [esi + TEXT_VIEW.bg_color] - mcall SF_DRAW_RECT - ; calc rows and cols - mov eax, [esi + TEXT_VIEW.width] - sub eax, MARGIN * 2 - shr eax, 3 ; assume that font width is 8 px - mov [esi + TEXT_VIEW.cols], eax - xor edx, edx - mov eax, [esi + TEXT_VIEW.height] - sub eax, MARGIN * 2 - mov ebx, FONT_HEIGHT + MARGIN * 2 - div ebx - mov [esi + TEXT_VIEW.rows], eax - ; draw lines - xor eax, eax ; rows - mov ebx, [esi + TEXT_VIEW.left] - add ebx, MARGIN + 1 ; frame width + add ebx, MARGIN + FRM_WIDTH shl ebx, 16 add ebx, [esi + TEXT_VIEW.top] - add ebx, MARGIN + 1 ; frame width - mov edi, [esi + TEXT_VIEW.buf_data] + add ebx, MARGIN + FRM_WIDTH + .draw_lines: - cmp eax, [esi + TEXT_VIEW.total_lines] + cmp eax, ecx jae .draw_lines_end - mov ecx, 0x90000000 - or ecx, [esi + TEXT_VIEW.fg_color] - mov edx, edi - push eax - mcall SF_DRAW_TEXT + push eax ecx + call tv.draw_single_line ; move edi pointer to the next string - push esi - mov esi, edi - call strlen add edi, eax inc edi - pop esi - ; next line num - pop eax - inc eax + pop ecx eax + inc eax ; next line num add ebx, FONT_HEIGHT + MARGIN jmp .draw_lines .draw_lines_end: @@ -143,7 +125,112 @@ proc text_view_append_line stdcall uses ebx esi edi, text_view:dword, string:dwo ret endp -draw_frame: +proc text_view_clear stdcall uses ebx, text_view:dword + mov edx, [text_view] + mov ecx, [edx + TEXT_VIEW.buf_data] + test ecx, ecx + jz @f + mcall SF_SYS_MISC, SSF_MEM_FREE + @@: + xor eax, eax + mov [edx + TEXT_VIEW.buf_data], eax + mov [edx + TEXT_VIEW.buf_size], eax + mov [edx + TEXT_VIEW.data_size], eax + mov [edx + TEXT_VIEW.total_lines], eax + mov [edx + TEXT_VIEW.curr_line], eax + mov [edx + TEXT_VIEW.max_length], eax + ret +endp + +proc text_view_deinit stdcall uses ebx, text_view:dword + mov edx, [text_view] + mov ecx, [edx + TEXT_VIEW.buf_data] + test ecx, ecx + jz @f + mcall SF_SYS_MISC, SSF_MEM_FREE + @@: + ret +endp + +proc tv.draw_frame_and_bg +; esi = text_view + mov ebx, [esi + TEXT_VIEW.left] + shl ebx, 16 + add ebx, [esi + TEXT_VIEW.width] + mov ecx, [esi + TEXT_VIEW.top] + shl ecx, 16 + add ecx, [esi + TEXT_VIEW.height] + mov edx, [esi + TEXT_VIEW.fg_color] + call draw_frame + add ebx, 1 shl 16 + sub ebx, 2 + add ecx, 1 shl 16 + sub ecx, 2 + mov edx, [esi + TEXT_VIEW.bg_color] + mcall SF_DRAW_RECT + ret +endp + +proc tv.calc_rows_and_cols +; esi = text_view + mov eax, [esi + TEXT_VIEW.width] + sub eax, (FRM_WIDTH + MARGIN) * 2 + shr eax, 3 ; assume that font width is 8 px + mov [esi + TEXT_VIEW.cols], eax + xor edx, edx + mov eax, [esi + TEXT_VIEW.height] + sub eax, MARGIN * 2 + mov ebx, FONT_HEIGHT + MARGIN + div ebx + mov [esi + TEXT_VIEW.rows], eax + ret +endp + +proc tv.draw_single_line uses esi +; esi = text_view +; ebx = coordinates: left << 16 + top +; edi = pointer to the first byte of string in [text_view.buf_data] +; return: eax = length of the string + mov ecx, 0x10000000 ; fixed-length string + or ecx, [esi + TEXT_VIEW.fg_color] + push esi + mov esi, edi + call strlen + pop esi + push eax + cmp eax, [esi + TEXT_VIEW.cols] + jbe .len_ok + mov eax, [esi + TEXT_VIEW.cols] + .len_ok: + mov esi, eax + mov edx, edi + mcall SF_DRAW_TEXT + pop eax + ret +endp + +proc goto_curr_line uses ebx esi +; eax = curr line index +; edi = buf + mov ebx, eax + xor ecx, ecx + mov esi, edi + cld + .scan: + cmp ecx, ebx + je .exit + lodsb + test al, al + jnz .scan + inc ecx + jmp .scan + .exit: + mov eax, ebx + mov edi, esi + ret +endp + +proc draw_frame ; ebx = left << 16 + width ; ecx = top << 16 + height ; edx = color @@ -180,3 +267,4 @@ draw_frame: mcall SF_DRAW_LINE pop ecx ebx ret +endp diff --git a/utils.asm b/utils.inc similarity index 100% rename from utils.asm rename to utils.inc