#include #include #include #include "addrs.h" #include "screen.h" #include "edbox.h" #include "complete.h" #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); 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); void edbox_show(void) { u16 addr; if(edbox_pos < 80) addr = (u16)edit_box; else addr = (u16)edit_box + edbox_pos - 79; scr_waitvcount_116(); *dlist_status_lms = addr; *dlist_last_line = 0x02; /* ANTIC GR.0 */ edbox_visible = 1; show_cursor(); } void edbox_hide(void) { scr_end_scrollback(); /* exit Start+E mode */ edbox_visible = 0; scr_refresh(); } void move_right(void) { memmove(edit_box + edbox_pos + 1, edit_box + edbox_pos, EDBOX_MAXPOS - edbox_pos); } void inschr(char c) { if(edbox_len == EDBOX_MAXPOS) { /* buffer full, can't insert */ bell(); return; } move_right(); edbox_len++; storechr(c); 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) { if(!c) return; /* no inserting nulls */ /* cannot insert *or* typeover at end of buffer! */ if(edbox_pos == EDBOX_MAXPOS) { bell(); return; } if(typeover) { storechr(c); edbox_pos++; } else { inschr(c); } } static void del_char(void) { if(!edbox_len) return; memmove(edit_box + edbox_pos, edit_box + edbox_pos + 1, EDBOX_MAXPOS - edbox_pos); edbox_len--; } static void del_to_end(void) { while(edbox_len > edbox_pos) del_char(); } static void backspace(void) { if(!edbox_pos) return; edbox_pos--; if(typeover) edit_box[edbox_pos] = ' '; else del_char(); } static void up(void) { if(!edbox_len) { restore_old(); } else { if(edbox_pos > 39) edbox_pos -= 40; else edbox_pos = 0; } } static void down(void) { if(edbox_pos > 199) return; edbox_pos += 40; if(edbox_pos > edbox_len) edbox_pos = edbox_len; } static void word_left(char del) { if(!edbox_pos) return; if(!del) edbox_pos--; while(edbox_pos && edit_box[edbox_pos] == ' ') { if(del) del_char(); edbox_pos--; } while(edbox_pos && edit_box[edbox_pos] != ' ') { if(del) del_char(); edbox_pos--; } // XXX: what's this good for? 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++; while(edbox_pos < edbox_len && edit_box[edbox_pos] != ' ') edbox_pos++; } static void del_to_start(void) { 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; } void left(void) { if(edbox_pos) edbox_pos--; } void right(void) { if(edbox_pos < edbox_len) edbox_pos++; } void edbox_keystroke(char c) { if(c == CH_ESC) { start_latch = 1; return; } 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: copy_to_old(); edbox_hide(); if(edbox_callback) (*edbox_callback)(); edbox_clear(); break; case XCH_TAB: comp_complete(); break; case XCH_UP: up(); break; case XCH_DOWN: down(); break; case XCH_LEFT: left(); break; case XCH_RIGHT: right(); break; case XCH_LWORD: back_word(); break; case XCH_RWORD: forward_word(); break; case XCH_CLS: edbox_clear(); edbox_hide(); return; case CH_DELCHR: case 0x18: /* ^X */ del_char(); break; case CH_DELLINE: edbox_clear(); break; case XCH_INSCHR: inschr(' '); break; case CH_INSLINE: typeover = !typeover; break; case 0x15: /* ^U */ del_to_start(); break; case 0x0b: /* ^K */ del_to_end(); break; case XCH_BS: if(!edbox_len) edbox_hide(); else backspace(); break; case 0x17: /* ^W */ del_word(); break; case 0x01: /* ^A */ edbox_pos = 0; break; case 0x05: /* ^E */ edbox_pos = edbox_len; break; default: edbox_putc(c); break; } show_cursor(); if(edbox_visible) edbox_show(); }