--- rxvt-unicode/src/command.C 2004/02/22 08:09:37 1.50 +++ rxvt-unicode/src/command.C 2004/03/11 00:53:19 1.67 @@ -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; @@ -143,12 +152,12 @@ { if (keysym == ks_bigfont) { - change_font (0, FONT_UP); + change_font (FONT_UP); return; } else if (keysym == ks_smallfont) { - change_font (0, FONT_DN); + change_font (FONT_DN); return; } } @@ -231,10 +240,10 @@ return; /* rxvt extras */ case XK_KP_Add: /* Shift+KP_Add = bigger font */ - change_font (0, FONT_UP); + change_font (FONT_UP); return; case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ - change_font (0, FONT_DN); + change_font (FONT_DN); return; } } @@ -284,35 +293,11 @@ } else STRCPY (kbuf, key_backspace); -# ifdef MULTICHAR_SET - if ((Options & Opt_mc_hack) && screen.cur.col > 0) - { - int col, row; - - newlen = STRLEN (kbuf); - col = screen.cur.col - 1; - row = screen.cur.row + TermWin.saveLines; - if (IS_MULTI2 (screen.rend[row][col])) - MEMMOVE (kbuf + newlen, kbuf, newlen + 1); - } -# endif break; #endif #ifndef NO_DELETE_KEY case XK_Delete: STRCPY (kbuf, key_delete); -# ifdef MULTICHAR_SET - if (Options & Opt_mc_hack) - { - int col, row; - - newlen = STRLEN (kbuf); - col = screen.cur.col; - row = screen.cur.row + TermWin.saveLines; - if (IS_MULTI1 (screen.rend[row][col])) - MEMMOVE (kbuf + newlen, kbuf, newlen + 1); - } -# endif break; #endif case XK_Tab: @@ -364,41 +349,6 @@ } else if (PrivateModes & PrivMode_aplCUR) kbuf[1] = 'O'; -#ifdef MULTICHAR_SET - //TODO: ?? - if (Options & Opt_mc_hack) - { - int col, row, m; - - col = screen.cur.col; - row = screen.cur.row + TermWin.saveLines; - m = 0; - if (keysym == XK_Right - && IS_MULTI1 (screen.rend[row][col])) - m = 1; - else if (keysym == XK_Left) - { - if (col > 0) - { - if (IS_MULTI2 (screen.rend[row][col - 1])) - m = 1; - } - else if (screen.cur.row > 0) - { - col = screen.tlen[--row]; - if (col == -1) - col = TermWin.ncol - 1; - else - col--; - if (col > 0 - && IS_MULTI2 (screen.rend[row][col])) - m = 1; - } - } - if (m) - MEMMOVE (kbuf + 3, kbuf, 3 + 1); - } -#endif break; #ifndef UNSHIFTED_SCROLLKEYS @@ -655,25 +605,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 +637,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 +646,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 +739,7 @@ } else if (n < 0 && errno != EAGAIN) destroy (); - + return false; } @@ -812,106 +766,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 @@ -921,14 +885,20 @@ { while (cmdbuf_ptr < cmdbuf_endp) { - if (*cmdbuf_ptr < 0x80) // assume < 0x80 to be ascii ALWAYS (all shift-states etc.) uh-oh + // assume 0x20 .. 0x7f to be ascii ALWAYS (all shift-states etc.) uh-oh + if ((*cmdbuf_ptr <= 0x7f && 0x20 <= *cmdbuf_ptr) + || !*cmdbuf_ptr) return *cmdbuf_ptr++; wchar_t wc; size_t len = mbrtowc (&wc, (char *)cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate); if (len == (size_t)-2) - return NOCHAR; + { + // the mbstate stores incomplete sequences. didn't know this :/ + cmdbuf_ptr = cmdbuf_endp; + break; + } if (len == (size_t)-1) return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through @@ -999,10 +969,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 +1387,7 @@ #if MENUBAR if (isMenuBarWindow (ev.xany.window)) { - menubar_control (& (ev.xbutton)); + menubar_control (ev.xbutton); break; } #endif @@ -1556,7 +1526,7 @@ } void -rxvt_term::button_press (const XButtonEvent &ev) +rxvt_term::button_press (XButtonEvent &ev) { int reportmode = 0, clickintime; @@ -1794,7 +1764,7 @@ } void -rxvt_term::button_release (const XButtonEvent &ev) +rxvt_term::button_release (XButtonEvent &ev) { int reportmode = 0; @@ -1966,30 +1936,33 @@ /* * Copy display->root pixmap transparency */ - int sx, sy, nx, ny; - unsigned int nw, nh; - Window cr; - XImage *image; - GC gc; - XGCValues gcvalue; + int sx, sy, nx, ny; + unsigned int nw, nh; + Window cr; + XImage *image; + GC gc; + XGCValues gcvalue; XTranslateCoordinates (display->display, TermWin.parent[0], display->root, 0, 0, &sx, &sy, &cr); nw = (unsigned int)szHint.width; nh = (unsigned int)szHint.height; nx = ny = 0; + if (sx < 0) { nw += sx; nx = -sx; sx = 0; } + if (sy < 0) { nh += sy; ny = -sy; sy = 0; } + MIN_IT (nw, (unsigned int) (wrootattr.width - sx)); MIN_IT (nh, (unsigned int) (wrootattr.height - sy)); allowedxerror = -1; @@ -2032,6 +2005,7 @@ am_transparent = am_pixmap_trans = 1; } } + if (!am_pixmap_trans) { unsigned int n; @@ -2056,7 +2030,9 @@ if (oldp != TermWin.parent[i]) pchanged = 1; } + n = 0; + if (pchanged) { for (; n < (unsigned int)i; n++) @@ -2070,6 +2046,7 @@ } } } + if (n > (int) (sizeof (TermWin.parent) / sizeof (TermWin.parent[0]))) { @@ -2102,6 +2079,7 @@ ParentRelative); am_transparent = 1; } + for (; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++) TermWin.parent[i] = None; } @@ -2117,7 +2095,7 @@ FILE * rxvt_term::popen_printer () { - FILE *stream = popen (rs[Rs_print_pipe], "w"); + FILE *stream = popen (rs[Rs_print_pipe], "w"); if (stream == NULL) rxvt_print_error ("can't open printer pipe"); @@ -2339,11 +2317,6 @@ case '+': scr_charset_set (3, (unsigned int)cmd_getc ()); break; -#ifdef MULTICHAR_SET - case '$': - scr_charset_set (-2, (unsigned int)cmd_getc ()); - break; -#endif #ifndef NO_FRILLS case '6': scr_backindex (); @@ -2694,7 +2667,7 @@ break; #endif case 8: /* unofficial extension */ - xterm_seq (XTerm_title, APL_NAME "-" VERSION, CHAR_ST); + xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST); break; } break; @@ -2978,6 +2951,8 @@ * 39 = change default fg color * 49 = change default bg color * 55 = dump scrollback buffer and all of screen + * 701 = change locale + * 702 = find font */ void rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__ ((unused))) @@ -3073,8 +3048,27 @@ case XTerm_logfile: break; case XTerm_font: - change_font (0, str); + change_font (str); + break; +#ifndef NO_FRILLS + case XTerm_locale: + if (str[0] == '?' && !str[1]) + tt_printf ("%-.250s\n", locale); + else + { + set_locale (str); +# ifdef USE_XIM + im_cb (); +# endif + } + break; + case XTerm_findfont: + { + int fid = TermWin.fontset->find_font (atoi (str)); + tt_printf ("%d %-.250s\n", fid, (*TermWin.fontset)[fid]->name); + } break; +#endif #if 0 case XTerm_dumpscreen: /* no error notices */ { @@ -3212,8 +3206,7 @@ break; case 3: /* 80/132 */ if (PrivateModes & PrivMode_132OK) - set_widthheight ( (unsigned int) ((state ? 132 : 80) * TermWin.fwidth), - (unsigned int)TermWin.height); + set_widthheight (((state ? 132 : 80) * TermWin.fwidth), TermWin.height); break; case 4: /* smooth scrolling */ if (state)