--- rxvt-unicode/src/command.C 2004/02/22 12:34:53 1.53 +++ rxvt-unicode/src/command.C 2004/02/24 16:25:44 1.57 @@ -112,10 +112,19 @@ if (status_return == XLookupChars || status_return == XLookupBoth) { - wkbuf[len] = 0; - len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ); - if (len < 0) - len = 0; + /* make sure the user can type ctrl-@, i.e. NUL */ + if (len == 1 && *wkbuf == 0) + { + kbuf[0] = 0; + len = 1; + } + else + { + wkbuf[len] = 0; + len = wcstombs ((char *)kbuf, wkbuf, KBUFSZ); + if (len < 0) + len = 0; + } } else len = 0; @@ -655,25 +664,23 @@ /* escape prefix */ if (meta #ifdef META8_OPTION - && (meta_char == C0_ESC) + && meta_char == C0_ESC #endif ) { const unsigned char ch = C0_ESC; - tt_write (&ch, 1); } -#ifdef DEBUG_CMD - if (debug_key) - { /* Display keyboard buffer contents */ - char *p; - int i; - - fprintf (stderr, "key 0x%04X [%d]: `", (unsigned int)keysym, len); - for (i = 0, p = kbuf; i < len; i++, p++) - fprintf (stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); - fprintf (stderr, "'\n"); - } + +#if defined(DEBUG_CMD) + /* Display keyboard buffer contents */ + unsigned char *p; + int i; + + fprintf (stderr, "key 0x%04X [%d]: `", (unsigned int)keysym, len); + for (i = 0, p = kbuf; i < len; i++, p++) + fprintf (stderr, (*p >= ' ' && *p < '\177' ? "%c" : "\\%03o"), *p); + fprintf (stderr, "'\n"); #endif /* DEBUG_CMD */ tt_write (kbuf, (unsigned int)len); } @@ -689,6 +696,7 @@ n = cmdbuf_ptr - cmdbuf_base; s = cmdbuf_base + BUFSIZ - 1 - cmdbuf_endp; + if (n > 0 && s < count) { MEMMOVE (cmdbuf_base, cmdbuf_ptr, @@ -697,13 +705,18 @@ cmdbuf_endp -= n; s += n; } + if (count > s) { rxvt_print_error ("data loss: cmd_write too large"); count = s; } + for (; count--;) *cmdbuf_endp++ = *str++; + + cmd_parse (); + return 0; } #endif /* MENUBAR_MAX */ @@ -785,7 +798,7 @@ } else if (n < 0 && errno != EAGAIN) destroy (); - + return false; } @@ -812,106 +825,116 @@ tt_winch (); } - uint32_t ch = NOCHAR; + if (cmd_parse ()) + break; + } + } +} + +bool +rxvt_term::cmd_parse () +{ + bool flag = false; + uint32_t ch = NOCHAR; + + for (;;) + { + if (ch == NOCHAR) + ch = next_char (); + + if (ch == NOCHAR) // TODO: improve + break; + + if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') + { + /* Read a text string from the input buffer */ + uint32_t buf[BUFSIZ]; + bool refreshnow = false; + int nlines = 0; + uint32_t *str = buf; + + *str++ = ch; for (;;) { - if (ch == NOCHAR) - ch = next_char (); + ch = next_char (); - if (ch == NOCHAR) // TODO: improve + if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) break; - - if (ch >= ' ' || ch == '\t' || ch == '\n' || ch == '\r') + else { - /* Read a text string from the input buffer */ - uint32_t buf[BUFSIZ]; - bool refreshnow = false; - int nlines = 0; - uint32_t *str = buf; - *str++ = ch; - for (;;) + if (ch == '\n') { - ch = next_char (); + nlines++; + refresh_count++; - if (ch == NOCHAR || (ch < ' ' && ch != '\t' && ch != '\n' && ch != '\r')) - break; - else + if (! (Options & Opt_jumpScroll) + || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) { - *str++ = ch; + refreshnow = true; + flag = false; + ch = NOCHAR; + break; + } - if (ch == '\n') - { - nlines++; - refresh_count++; - - if (! (Options & Opt_jumpScroll) - || (refresh_count >= (refresh_limit * (TermWin.nrow - 1)))) - { - refreshnow = true; - flag = false; - ch = NOCHAR; - break; - } - - // scr_add_lines only works for nlines < TermWin.nrow - 1. - if (nlines >= TermWin.nrow - 1) - { - scr_add_lines (buf, nlines, str - buf); - nlines = 0; - str = buf; - } - } - - if (str >= buf + BUFSIZ) - { - ch = NOCHAR; - break; - } + // scr_add_lines only works for nlines < TermWin.nrow - 1. + if (nlines >= TermWin.nrow - 1) + { + scr_add_lines (buf, nlines, str - buf); + nlines = 0; + str = buf; } } - scr_add_lines (buf, nlines, str - buf); - - /* - * If there have been a lot of new lines, then update the screen - * What the heck I'll cheat and only refresh less than every page-full. - * the number of pages between refreshes is refresh_limit, which - * is incremented here because we must be doing flat-out scrolling. - * - * refreshing should be correct for small scrolls, because of the - * time-out - */ - if (refreshnow) + if (str >= buf + BUFSIZ) { - if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) - refresh_limit++; - - scr_refresh (refresh_type); + ch = NOCHAR; + break; } - } - else - { - switch (ch) - { - default: - process_nonprinting (ch); - break; - case C0_ESC: /* escape char */ - process_escape_seq (); - break; - /*case 0x9b: */ /* CSI */ - /* process_csi_seq (); */ - } + } - ch = NOCHAR; - } + scr_add_lines (buf, nlines, str - buf); + + /* + * If there have been a lot of new lines, then update the screen + * What the heck I'll cheat and only refresh less than every page-full. + * the number of pages between refreshes is refresh_limit, which + * is incremented here because we must be doing flat-out scrolling. + * + * refreshing should be correct for small scrolls, because of the + * time-out + */ + if (refreshnow) + { + if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) + refresh_limit++; + + scr_refresh (refresh_type); } + + } + else + { + switch (ch) + { + default: + process_nonprinting (ch); + break; + case C0_ESC: /* escape char */ + process_escape_seq (); + break; + /*case 0x9b: */ /* CSI */ + /* process_csi_seq (); */ + } + + ch = NOCHAR; } } + + return flag; } // read the next character, currently handles UTF-8 @@ -999,10 +1022,10 @@ #endif void -rxvt_term::mouse_report (const XButtonEvent &ev) +rxvt_term::mouse_report (XButtonEvent &ev) { - int button_number, key_state = 0; - int x, y; + int button_number, key_state = 0; + int x, y; x = ev.x; y = ev.y; @@ -1417,7 +1440,7 @@ #if MENUBAR if (isMenuBarWindow (ev.xany.window)) { - menubar_control (& (ev.xbutton)); + menubar_control (ev.xbutton); break; } #endif @@ -1556,7 +1579,7 @@ } void -rxvt_term::button_press (const XButtonEvent &ev) +rxvt_term::button_press (XButtonEvent &ev) { int reportmode = 0, clickintime; @@ -1794,7 +1817,7 @@ } void -rxvt_term::button_release (const XButtonEvent &ev) +rxvt_term::button_release (XButtonEvent &ev) { int reportmode = 0; @@ -2696,10 +2719,6 @@ case 8: /* unofficial extension */ xterm_seq (XTerm_title, APL_NAME "-" VERSION, CHAR_ST); break; - - case XTerm_locale: /* unofficial extension */ - tt_printf ("%-.250s\n", locale); - break; } break; @@ -3081,8 +3100,13 @@ change_font (str); break; case XTerm_locale: - set_locale (str); - im_cb (); + if (str[0] == '?' && !str[1]) + tt_printf ("%-.250s\n", locale); + else + { + set_locale (str); + im_cb (); + } break; #if 0 case XTerm_dumpscreen: /* no error notices */