/* * input.c: parse and process user input * * Copyright(c) 1997-2000 - All Rights Reserved * * See the COPYRIGHT file. */ #ifndef lint static char rcsid[] = "@(#)$Id: input.c,v 1.40 2001/02/20 02:06:55 kalt Exp $"; #endif #include "os.h" #include "struct.h" #include "server.h" #include "window.h" #include "term.h" #include "config.h" extern void parse_command(char *, int); extern int cmd_msgnotice(char *, char *); extern char *tab_get(); extern char *space_get(); extern struct window_ *current; extern struct server_ *server; static char inbuf[512] = ""; static char history[100][512]; static int curh = -1, nexh = -1; static unsigned int inlen = 0, inpos = 0; static void parse_input() { vsic_slog(LOG_INPUT, ">>> %s", inbuf); if (nexh == -1) for (nexh = 99; nexh > 0; nexh--) history[nexh][0] = '\0'; strcpy(history[nexh], inbuf); if (nexh++ == 99) nexh = 0; history[curh = nexh][0] = '\0'; switch (*inbuf) { case '/' : if (inbuf[1] == '/') if (inbuf[2] == '/') vsic_write(inbuf+3); else parse_command(inbuf+2, 0); else parse_command(inbuf+1, 1); break; default : cmd_msgnotice(NULL, inbuf); break; } inbuf[0] = '\0'; inlen = inpos = 0; } int cmd_run(p) char *p; { FILE *s; char fname[255]; if (!*p) return -1; strcpy(fname, cfgdir); strcat(fname, p); if (s = fopen(fname, "r")) { while (!feof(s)) { if (fgets(inbuf+1, 400, s) == NULL) break; if (inbuf[1] == '#') continue; inbuf[0] = '/'; inbuf[strlen(inbuf) - 1] = '\0'; select_active(NULL, 2); server = current->via; parse_input(inbuf); } fclose(s); } else if (strcmp(p, "startup")) vsic_slog(LOG_CLIENT, "--- %s: %s.", p, strerror(errno)); return 0; } void space_trick() { char obuf[512] = ""; char *ch; if (ch = index(inbuf, ':')) strcpy(obuf, (ch[1] == ' ') ? ch+2 : ch+1); else strcpy(obuf, inbuf); ch = space_get(); if (*ch) { sprintf(inbuf, "%s: ", ch); inpos = strlen(inbuf); strcat(inbuf, obuf); inlen = strlen(inbuf); } } void tab_trick() { char obuf[512] = ""; char *ch; if (ch = index(inbuf, ' ')) if (ch = index(ch+1, ' ')) strcpy(obuf, ch+1); ch = tab_get(); if (*ch) { char *cmd; if (*ch == '@') { ch++; cmd = "squery"; } else cmd = "msg"; sprintf(inbuf, "/%s %s ", cmd, ch); } else strcpy(inbuf, "/msg "); inpos = strlen(inbuf); strcat(inbuf, obuf); inlen = strlen(inbuf); } char in_delprev() { if (inpos) { char *wp; wp = inbuf+inpos-1; while (*wp++) *(wp-1) = *wp; inlen--; inpos--; return 1; } else { term_beep(); return 0; } } char in_delnext() { if (inpos < inlen) { char *wp; wp = inbuf+inpos; while (*wp++) *(wp-1) = *wp; inlen--; return 1; } else { term_beep(); return 0; } } void in_insert(ch, trunc) char ch, *trunc; { int i; if (*trunc) { inbuf[inlen = inpos] = '\0'; *trunc = 0; } if (inlen < 400) { inlen++; for (i = inlen; i > inpos; i--) inbuf[i] = inbuf[i-1]; inbuf[inpos++] = ch; } else term_beep(); } void display_input() { term_input(inbuf + ((CO-10)*(inpos/(CO-10))) - ((inpos>=CO-10) ? 10 :0), inpos - ((CO-10)*(inpos/(CO-10))) + ((inpos>=CO-10) ? 10:0)); } void sic_getch() { static char escape = 0, screen = 0, search = 0, quote = 0, replace = 0; static char cursor = 0; char ch, chg = 0; assert(inlen == strlen(inbuf)); assert(inpos <= inlen); if (read(0, &ch, 1) != 1) return; server = current->via; if (quote) { quote = 0; in_insert(ch, &replace); chg = 1; } else { select_active(NULL, 2); if (search) { if (ch == '/') sic_scroll2(search = +2, inbuf); else if (ch == '?') sic_scroll2(search = -2, inbuf); else { search = 0; inbuf[0] = '\0'; inlen = inpos = 0; chg = 1; } } if (search == 0) { if (screen) { screen = 0; switch (ch) { case 'a': case ctrl('A'): case ctrl('X'): sic_chgwin(-3); chg = 1; break; case 'c': case ctrl('C'): sic_newwin(); sic_chgwin(-3); chg = 1; break; case 'd': case ctrl('D'): sic_wdcc(); break; case 'k': case ctrl('K'): sic_wkill(); break; case 'l': case ctrl('L'): sic_wlist(); break; case '\0': /* ^-space */ case ' ': case 'n': case ctrl('N'): sic_chgwin(-1); chg = 1; break; case 'p': case ctrl('P'): sic_chgwin(-2); chg = 1; break; case 's': sic_swin(2); break; default: if (ch >= 48 && ch <= 57) sic_chgwin((int) ch - 48); chg = 1; } } else if (escape) { switch (ch) { case '[': cursor = 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': current->fnb = ch - 48; sic_redowin(0); break; case '/': sic_scroll2(search = +2, inbuf); break; case '?': sic_scroll2(search = -2, inbuf); break; case '<': sic_scroll2(-1, NULL); break; case '>': sic_scroll2(+1, NULL); break; case '-': sic_scroll(-1); break; case '+': sic_scroll(+1); break; case '.': sic_clog(0); sic_redowin(0); break; case 'b': if (inpos) { if (!isspace((int) inbuf[inpos])) inpos -= 1; while (inpos && isspace((int) inbuf[inpos--])); while (inpos && !isspace((int) inbuf[inpos-1])) inpos -= 1; chg = 1; } replace = 0; break; case 'f': if (inpos < inlen) { while (isspace((int) inbuf[inpos++])); while (inbuf[inpos] && !isspace((int) inbuf[inpos])) inpos += 1; chg = 1; } replace = 0; break; case 'd': if (inpos < inlen) { while (isspace((int) inbuf[inpos])) in_delnext(); while (inbuf[inpos] && !isspace((int) inbuf[inpos])) in_delnext(); chg = 1; } replace = 0; break; case 'H': if (option(current->custw.zopt_on, Z_NOCOLOR)) unset_option(current->custw.zopt_on, Z_NOCOLOR); else set_option(current->custw.zopt_on, Z_NOCOLOR); sic_redowin(0); break; case 'h': if (option(current->custw.zopt_on, Z_IRCII)) unset_option(current->custw.zopt_on, Z_IRCII); else set_option(current->custw.zopt_on, Z_IRCII); sic_redowin(0); break; case ctrl('H'): case 127: if (inpos) { while (inpos && isspace((int) inbuf[inpos-1])) in_delprev(); while (inpos && !isspace((int) inbuf[inpos-1])) in_delprev(); chg = 1; } replace = 0; break; case 'n': sic_scroll((LI-2)/2); break; case 'N': sic_scroll2(+2, NULL); break; case 'p': sic_scroll(-(LI-2)/2); break; case 'P': sic_scroll2(-2, NULL); break; case 's': if (inbuf[0]) { sic_scroll2(0, inbuf); inbuf[0] = '\0'; inpos = inlen = replace = 0; chg = 1; } else sic_scroll2(0, NULL); sic_redowin(0); break; case 'S': if (option(current->custw.zopt_on, Z_SHOWALL)) unset_option(current->custw.zopt_on, Z_SHOWALL); else set_option(current->custw.zopt_on, Z_SHOWALL); sic_redowin(0); break; case 't': sic_wptoggle(); sic_redowin(0); break; case 'u': if (option(current->custw.zopt_on, Z_UNDEL)) unset_option(current->custw.zopt_on, Z_UNDEL); else set_option(current->custw.zopt_on, Z_UNDEL); sic_redowin(0); break; } escape = 0; } else if (cursor) { switch (ch) { case 'C': /* cursor right */ if (inpos < inlen) { inpos++; chg = 1; } replace = 0; break; case 'D': /* cursor left */ if (inpos) { inpos--; chg = 1; } replace = 0; break; case 'B': /* cursor down */ if (curh != -1) { do if (curh++ == 99) curh = 0; while (*history[curh] == '\0'); strcpy(inbuf, history[curh]); inlen = strlen(inbuf); inpos = 0; replace = 1; chg = 1; } else term_beep(); break; case 'A': /* cursor up */ if (curh != -1) { do if (curh-- == 0) curh = 99; while (*history[curh] == '\0'); strcpy(inbuf, history[curh]); inlen = strlen(inbuf); inpos = 0; replace = 1; chg = 1; } else term_beep(); break; } cursor = 0; } else switch (ch) { case 0: space_trick(); replace = 1; chg = 1; break; case 27: /* escape */ escape = 1; break; case ctrl('A'): inpos = 0; replace = 0; chg = 1; break; case ctrl('B'): if (inpos) { inpos--; chg = 1; } replace = 0; break; case ctrl('D'): replace = 0; chg = in_delnext(); break; case ctrl('E'): inpos = inlen; replace = 0; chg = 1; break; case ctrl('F'): if (inpos < inlen) { inpos++; chg = 1; } replace = 0; break; case ctrl('I'): tab_trick(); replace = 1; chg = 1; break; case ctrl('H'): case 127: chg = in_delprev(); replace = 0; break; case ctrl('K'): inbuf[inpos] = '\0'; inlen = inpos; chg = 1; replace = 0; break; case ctrl('L'): sic_redowin(1); chg = 1; break; case ctrl('N'): if (curh != -1) { do if (curh++ == 99) curh = 0; while (*history[curh] == '\0'); strcpy(inbuf, history[curh]); inlen = strlen(inbuf); inpos = 0; replace = 1; chg = 1; } else term_beep(); break; case ctrl('P'): if (curh != -1) { do if (curh-- == 0) curh = 99; while (*history[curh] == '\0'); strcpy(inbuf, history[curh]); inlen = strlen(inbuf); inpos = 0; replace = 1; chg = 1; } else term_beep(); break; case ctrl('T'): if (inpos && inpos < inlen) { char sw = inbuf[inpos]; inbuf[inpos] = inbuf[inpos-1]; inbuf[inpos-1] = sw; chg = 1; } else term_beep(); replace = 0; break; case ctrl('U'): inbuf[0] = '\0'; inlen = inpos = 0; replace = 0; chg = 1; break; case ctrl('V'): quote = 1; break; case ctrl('W'): if (inpos) { while (inpos && isspace((int) inbuf[inpos-1])) in_delprev(); while (inpos && !isspace((int) inbuf[inpos-1])) in_delprev(); chg = 1; } replace = 0; break; case ctrl('X'): screen = 1; break; case ctrl('J'): case ctrl('M'): if (*inbuf) { parse_input(); chg = 1; } else sic_scroll(LI-4); replace = 0; break; default: in_insert(ch, &replace); chg = 1; } } } if (chg) display_input(); return; }