diff options
Diffstat (limited to 'src/edbox.c')
| -rw-r--r-- | src/edbox.c | 295 |
1 files changed, 105 insertions, 190 deletions
diff --git a/src/edbox.c b/src/edbox.c index d5728c2..0725379 100644 --- a/src/edbox.c +++ b/src/edbox.c @@ -4,34 +4,29 @@ #include "addrs.h" #include "screen.h" #include "edbox.h" -#include "keyclick.h" #include "complete.h" - -/* TODO: tab completion */ - -char *old_edbox[EDBOX_SIZE]; -static u16 old_len; - -int edbox_visible = 0; -static u16 edbox_pos; /* range 0 to EDBOX_SIZE - 1 */ -u16 edbox_len; /* idem */ +#include "keytab.h" +#include "irc.h" + +/* private API stuff (not in edbox.h) that's been rewritten in asm. */ +void hide_cursor(void); +void show_cursor(void); +void storechr(char c); +void copy_to_old(void); +void restore_old(void); +void backspace(void); +void inschr(char c); + +char old_edbox[EDBOX_SIZE]; +char old_len; +char typeover; + +char edbox_visible = 0; +char edbox_pos; /* range 0 to EDBOX_SIZE - 1 */ +char edbox_len; /* idem */ void (*edbox_callback)(void); -static void hide_cursor(void) { - edit_box[edbox_pos] &= 0x7f; -} - -static void show_cursor(void) { - edit_box[edbox_pos] |= 0x80; -} - -void edbox_clear(void) { - memset(edit_box, 0, EDBOX_SIZE); - edbox_pos = edbox_len = 0; - show_cursor(); // not needed? seems it is.. -} - void edbox_show(void) { u16 addr; @@ -40,7 +35,7 @@ void edbox_show(void) { else addr = (u16)edit_box + edbox_pos - 79; - scr_waitvcount(116); + scr_waitvcount_116(); *dlist_status_lms = addr; *dlist_last_line = 0x02; /* ANTIC GR.0 */ @@ -54,50 +49,37 @@ void edbox_hide(void) { scr_refresh(); } +void move_right(void) { + memmove(edit_box + edbox_pos + 1, edit_box + edbox_pos, EDBOX_MAXPOS - edbox_pos); +} + /* note: c will never be an EOL. idea: when the edbox is completely full (240 chars), go ahead and pretend the user pressed Return (call edbox_callback, etc). not sure if this is more or less annoying than just refusing to accept more input until Return is pressed. */ void edbox_putc(char c) { - extern void __fastcall__ bell(void); - if(!c) return; /* no inserting nulls */ - memmove(edit_box + edbox_pos + 1, edit_box + edbox_pos, EDBOX_SIZE - edbox_pos - 1); - edit_box[edbox_pos] = c; - if(edbox_pos < EDBOX_SIZE - 1) { - edbox_pos++; - edbox_len++; - } else { + /* cannot insert *or* typeover at end of buffer! */ + if(edbox_pos == EDBOX_MAXPOS) { bell(); + return; } -} -static void copy_to_old(void) { - if(!edbox_len) return; - memcpy(old_edbox, edit_box, edbox_len); - memset(old_edbox + edbox_len, 0, (EDBOX_SIZE - 1) - edbox_len); - old_len = edbox_len; -} - -static void restore_old(void) { - edbox_clear(); - hide_cursor(); - memcpy(edit_box, old_edbox, old_len); - edbox_pos = edbox_len = old_len; + if(typeover) { + storechr(c); + edbox_pos++; + } else { + inschr(c); + } } -static void fake_keystroke(char c) { - keyclick(); - OS.ch = 0xff; - edbox_putc(c); -} -static void del_char(void) { +void del_char(void) { if(!edbox_len) return; - memmove(edit_box + edbox_pos, edit_box + edbox_pos + 1, EDBOX_SIZE - edbox_pos - 1); + memmove(edit_box + edbox_pos, edit_box + edbox_pos + 1, EDBOX_MAXPOS - edbox_pos); edbox_len--; } @@ -106,12 +88,6 @@ static void del_to_end(void) { del_char(); } -static void backspace(void) { - if(!edbox_pos) return; - edbox_pos--; - del_char(); -} - static void up(void) { if(!edbox_len) { restore_old(); @@ -145,14 +121,6 @@ static void word_left(char del) { if(del && !edbox_pos) edit_box[edbox_pos] = /* ' ' */ 0; } -static void del_word(void) { - word_left(1); -} - -static void back_word(void) { - word_left(0); -} - static void forward_word(void) { while(edbox_pos < edbox_len && edit_box[edbox_pos] == ' ') edbox_pos++; @@ -161,64 +129,101 @@ static void forward_word(void) { } static void del_to_start(void) { - while(edbox_pos) backspace(); + if(!edbox_pos) return; + memmove(edit_box, edit_box + edbox_pos, EDBOX_MAXPOS - edbox_pos); + edbox_len -= edbox_pos; + bzero(edit_box + edbox_len, EDBOX_MAXPOS - edbox_len); + edbox_pos = 0; } -static void normal_keystroke(void) { - char c; +void left(void) { + if(edbox_pos) edbox_pos--; +} + +void right(void) { + if(edbox_pos < edbox_len) edbox_pos++; +} - c = cgetc(); +void edbox_keystroke(char c) { + if(c == CH_ESC) { + start_latch = 1; + return; + } - if(c != CH_TAB) + if(c != XCH_TAB) comp_complete_done(); + if(c >= XCH_SCR1 && c <= XCH_SCR7) { + start_keystroke(c & 0x7f); + return; + } else if(c == XCH_ACTIVE) { + start_keystroke('a'); + return; + } + + edbox_show(); + hide_cursor(); + switch(c) { case CH_EOL: - // hide_cursor(); // already done by the caller copy_to_old(); edbox_hide(); if(edbox_callback) (*edbox_callback)(); edbox_clear(); break; - case CH_CLR: - edbox_hide(); - /* fall thru */ - case CH_DELLINE: - edbox_clear(); + case XCH_TAB: + comp_complete(); break; - case 0x15: /* ^U */ - del_to_start(); + case XCH_UP: + up(); break; - case 0x0b: /* ^K */ - del_to_end(); + case XCH_DOWN: + down(); + break; + case XCH_LEFT: + left(); break; - case CH_DEL: - backspace(); + case XCH_RIGHT: + right(); break; - case 0x02: /* ^B */ - back_word(); + case XCH_LWORD: + word_left(0); break; - case 0x06: /* ^F */ + case XCH_RWORD: forward_word(); break; - case 0x17: /* ^W */ - del_word(); + case XCH_CLS: + edbox_clear(); + edbox_hide(); + return; + case CH_DELCHR: + case 0x18: /* ^X */ + del_char(); break; - case CH_CURS_LEFT: - if(edbox_pos) edbox_pos--; + case CH_DELLINE: + edbox_clear(); break; - case CH_CURS_RIGHT: - if(edbox_pos < edbox_len) edbox_pos++; + case XCH_INSCHR: + inschr(' '); break; - case CH_CURS_UP: - up(); + case CH_INSLINE: + typeover = !typeover; break; - case CH_CURS_DOWN: - down(); + case 0x15: /* ^U */ + del_to_start(); break; - case CH_DELCHR: - del_char(); + case 0x0b: /* ^K */ + del_to_end(); + break; + case XCH_BS: + if(!edbox_len) + edbox_hide(); + else + backspace(); + break; + case 0x17: /* ^W */ + word_left(1); break; case 0x01: /* ^A */ edbox_pos = 0; @@ -226,101 +231,11 @@ static void normal_keystroke(void) { case 0x05: /* ^E */ edbox_pos = edbox_len; break; - case CH_TAB: - comp_complete(); - break; default: edbox_putc(c); break; } -} - -void edbox_keystroke(void) { - char c; - - while(OS.ch == 0xff) - ; - - /* filter out all ctrl-shift key combos except the ones - we actually support */ - if(OS.ch == 0xce) { - /* ctrl-shift-up, same as ^B = back 1 word */ - OS.ch = 0x95; - } else if(OS.ch == 0xcf) { - /* ctrl-shift-down, same as ^F = forward 1 word */ - OS.ch = 0xb8; - } else if(OS.ch > 0xbf) { - OS.ch = 0xff; - return; - } - - edbox_show(); - - c = 0; - - switch(OS.ch) { - case 0xa0: /* key: ctrl [ */ - c = 0x7b; /* ascii: { */ - break; - case 0xa2: /* key: ctrl ] */ - c = 0x7d; /* ascii: } */ - break; - case 0x1c: /* key: ESC */ - c = 0x60; /* ascii: ` */ - break; - case 0x5c: /* key: shift ESC */ - case 0x9c: /* key: ctrl ESC */ - c = 0x7e; /* ascii: ~ */ - break; - case 0x3c: /* caps */ - case 0x7c: /* shift-caps */ - case 0xbc: /* ctrl-caps */ - OS.shflok ^= 0x40; - keyclick(); - OS.ch = 0xff; - return; - break; - case 0x27: /* atari key */ - case 0x67: /* ...w/shift */ - case 0xa7: /* ...w/ctrl */ - c = 0x02; /* ^B = IRC bold formatting char */ - break; - case 0x9a: /* ctrl-3 (crash if cgetc() reads it!) */ - case 0x9e: /* ctrl-2 */ - case 0x6c: /* shift-tab */ - case 0xac: /* ctrl-tab */ - OS.ch = 0xff; /* ignore it! */ - return; - break; - default: - break; - } - hide_cursor(); - - if(c) { - fake_keystroke(c); - } else { - normal_keystroke(); - } - - if(edbox_visible) edbox_show(); show_cursor(); -} - -void edbox_addchr(char c) { - edit_box[edbox_len++] = c; - edbox_pos = edbox_len; -} - -void edbox_space(void) { - edbox_addchr(' '); -} - -void edbox_set(char *contents) { - edbox_clear(); - while(*contents) { - edit_box[edbox_len++] = *contents++; - } - edbox_pos = edbox_len; + if(edbox_visible) edbox_show(); } |
