#include #include #include #include "addrs.h" #include "screen.h" #include "edbox.h" #include "keyclick.h" /* TODO: tab completion */ // static int edbox_visible = 0; /* don't think we'll ever need it */ static u16 edbox_pos; /* range 0 to EDBOX_SIZE - 1 */ static u16 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(); } 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; show_cursor(); } void edbox_hide(void) { scr_refresh(); } void edbox_putc(char c) { if(!c) return; /* no inserting nulls */ if((c != CH_EOL) && (edbox_pos == EDBOX_SIZE - 1)) return; memmove(edit_box + edbox_pos + 1, edit_box + edbox_pos, EDBOX_SIZE - edbox_pos - 1); edit_box[edbox_pos++] = c; edbox_len++; edbox_show(); } void edbox_append(char *s) { while(*s) edit_box[edbox_pos++] = *s++; edbox_len = edbox_pos; } void edbox_preset(char *s) { edbox_clear(); edbox_append(s); } static char readline_done, readline_len; static char *readline_dest; static void readline_callback(void) { strncpy(readline_dest, edit_box, readline_len); readline_done = 1; } void edbox_readline(char *dest, char len) { void (*old_callback)(void); edbox_clear(); if(*dest) edbox_preset(dest); edbox_show(); old_callback = edbox_callback; edbox_callback = readline_callback; readline_dest = dest; readline_len = len; readline_done = 0; while(!readline_done) edbox_keystroke(); edbox_callback = old_callback; } static void special_keystroke(char c) { keyclick(); OS.ch = 0xff; edbox_putc(c); } static void del_char(void) { if(!edbox_len) return; memmove(edit_box + edbox_pos, edit_box + edbox_pos + 1, EDBOX_SIZE - edbox_pos - 1); edbox_len--; } static void backspace(void) { if(!edbox_pos) return; edbox_pos--; del_char(); } static void del_word(void) { if(!edbox_pos) return; edbox_pos--; while(edbox_pos && edit_box[edbox_pos] == ' ') { del_char(); edbox_pos--; } while(edbox_pos && edit_box[edbox_pos] != ' ') { del_char(); edbox_pos--; } if(!edbox_pos) edit_box[edbox_pos] = ' '; } static void normal_keystroke(void) { char c; c = cgetc(); switch(c) { case CH_EOL: hide_cursor(); if(edbox_callback) (*edbox_callback)(); /* fall thru */ case CH_CLR: edbox_hide(); /* fall thru */ case CH_DELLINE: case 0x15: /* ^U */ edbox_clear(); break; case CH_DEL: backspace(); break; case 0x17: /* ^W */ del_word(); break; case CH_CURS_LEFT: if(edbox_pos) edbox_pos--; break; case CH_CURS_RIGHT: if(edbox_pos < edbox_len) edbox_pos++; break; case CH_DELCHR: del_char(); break; case 0x01: /* ^A */ edbox_pos = 0; break; case 0x05: /* ^E */ edbox_pos = edbox_len; break; default: edbox_putc(c); break; } } void edbox_keystroke(void) { char c; while(OS.ch == 0xff) ; 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 */ OS.shflok ^= 0x40; keyclick(); OS.ch = 0xff; return; break; case 0x7c: /* shift-caps */ case 0xbc: /* ctrl-caps */ case 0x27: /* atari key */ case 0x67: /* ...w/shift */ case 0x97: /* ...w/ctrl */ case 0x9a: /* ctrl-3 (crash if cgetc() reads it!) */ OS.ch = 0xff; /* ignore it! */ return; break; default: break; } hide_cursor(); if(c) { special_keystroke(c); } else { normal_keystroke(); } show_cursor(); }