--- rxvt-unicode/src/command.C 2004/02/21 21:12:20 1.47 +++ rxvt-unicode/src/command.C 2004/02/25 15:39:48 1.59 @@ -27,6 +27,7 @@ * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * Copyright (c) 2003 Rob McMullen + * Copyright (c) 2003-2004 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,13 +58,13 @@ void rxvt_term::lookup_key (XKeyEvent &ev) { - int ctrl, meta, shft, len; - unsigned int newlen; - KeySym keysym; + int ctrl, meta, shft, len; + unsigned int newlen; + KeySym keysym; #ifdef DEBUG_CMD - static int debug_key = 1; /* accessible by a debugger only */ + static int debug_key = 1; /* accessible by a debugger only */ #endif - int valid_keysym; + int valid_keysym; unsigned char kbuf[KBUFSZ]; /* @@ -90,12 +91,11 @@ Status status_return; #ifdef X_HAVE_UTF8_STRING - if (enc_utf8 && 0) + if (enc_utf8 && 0) // currently disabled, doesn't seem to work, nor is useful len = Xutf8LookupString (Input_Context, &ev, (char *)kbuf, KBUFSZ, &keysym, &status_return); else #endif - { wchar_t wkbuf[KBUFSZ + 1]; @@ -110,26 +110,34 @@ SET_LOCALE (locale); if (status_return == XLookupChars - || status_return == XLookupBoth) + || 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; } valid_keysym = status_return == XLookupKeySym - || status_return == XLookupBoth; + || status_return == XLookupBoth; } else #endif - { len = XLookupString (&ev, (char *)kbuf, KBUFSZ, &keysym, &compose); - valid_keysym = !len; + valid_keysym = keysym != NoSymbol; } if (valid_keysym) @@ -144,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; } } @@ -164,7 +172,7 @@ if (IS_SCROLL_MOD) { #endif - int lnsppg; + int lnsppg; #ifdef PAGING_CONTEXT_LINES lnsppg = TermWin.nrow - PAGING_CONTEXT_LINES; @@ -212,7 +220,6 @@ } } #endif - } if (shft) @@ -233,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; } } @@ -248,22 +255,6 @@ return; } #endif -#ifdef GREEK_SUPPORT - if (keysym == ks_greekmodeswith) - { - greek_mode = !greek_mode; - if (greek_mode) - { - xterm_seq (XTerm_title, - (greek_getmode () == GREEK_ELOT928 - ? "[Greek: iso]" : "[Greek: ibm]"), CHAR_ST); - greek_reset (); - } - else - xterm_seq (XTerm_title, APL_NAME "-" VERSION, CHAR_ST); - return; - } -#endif if (keysym >= 0xFF00 && keysym <= 0xFFFF) { @@ -288,7 +279,6 @@ } else #endif - { newlen = 1; switch (keysym) @@ -351,7 +341,6 @@ } break; - #ifdef XK_KP_Left case XK_KP_Up: /* \033Ox or standard */ case XK_KP_Down: /* \033Or or standard */ @@ -484,7 +473,7 @@ break; case XK_KP_Multiply: /* "\033Oj" : "*" */ - case XK_KP_Add: /* "\033Ok" : "+" */ + case XK_KP_Add: /* "\033Ok" : "+" */ case XK_KP_Separator: /* "\033Ol" : "," */ case XK_KP_Subtract: /* "\033Om" : "-" */ case XK_KP_Decimal: /* "\033On" : "." */ @@ -644,10 +633,6 @@ meta = 0; } #endif -#ifdef GREEK_SUPPORT - if (greek_mode) - len = greek_xlat (kbuf, len); -#endif /* nil */ ; } } @@ -679,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); } @@ -713,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, @@ -721,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 */ @@ -809,7 +798,7 @@ } else if (n < 0 && errno != EAGAIN) destroy (); - + return false; } @@ -836,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 @@ -1023,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; @@ -1430,10 +1429,6 @@ if (menubar_visible () && isMenuBarWindow (ev.xany.window)) menubar_expose (); #endif -#ifdef RXVT_GRAPHICS - Gr_expose (ev.xany.window); -#endif - } break; @@ -1445,7 +1440,7 @@ #if MENUBAR if (isMenuBarWindow (ev.xany.window)) { - menubar_control (& (ev.xbutton)); + menubar_control (ev.xbutton); break; } #endif @@ -1584,7 +1579,7 @@ } void -rxvt_term::button_press (const XButtonEvent &ev) +rxvt_term::button_press (XButtonEvent &ev) { int reportmode = 0, clickintime; @@ -1596,88 +1591,80 @@ */ if (ev.window == TermWin.vt) { -#if RXVT_GRAPHICS - if (ev.subwindow != None) - rxvt_Gr_ButtonPress (ev.x, ev.y); - else -#endif - + clickintime = ev.time - MEvent.time < MULTICLICK_TIME; + if (reportmode) { - clickintime = ev.time - MEvent.time < MULTICLICK_TIME; - if (reportmode) - { - /* mouse report from vt window */ - /* save the xbutton state (for ButtonRelease) */ - MEvent.state = ev.state; + /* mouse report from vt window */ + /* save the xbutton state (for ButtonRelease) */ + MEvent.state = ev.state; #ifdef MOUSE_REPORT_DOUBLECLICK - if (ev.button == MEvent.button && clickintime) - { - /* same button, within alloted time */ - MEvent.clicks++; - if (MEvent.clicks > 1) - { - /* only report double clicks */ - MEvent.clicks = 2; - mouse_report (ev); - - /* don't report the release */ - MEvent.clicks = 0; - MEvent.button = AnyButton; - } - } - else + if (ev.button == MEvent.button && clickintime) + { + /* same button, within alloted time */ + MEvent.clicks++; + if (MEvent.clicks > 1) { - /* different button, or time expired */ - MEvent.clicks = 1; - MEvent.button = ev.button; + /* only report double clicks */ + MEvent.clicks = 2; mouse_report (ev); + + /* don't report the release */ + MEvent.clicks = 0; + MEvent.button = AnyButton; } -#else + } + else + { + /* different button, or time expired */ + MEvent.clicks = 1; MEvent.button = ev.button; mouse_report (ev); + } +#else + MEvent.button = ev.button; + mouse_report (ev); #endif /* MOUSE_REPORT_DOUBLECLICK */ - } - else + } + else + { + if (ev.button != MEvent.button) + MEvent.clicks = 0; + switch (ev.button) { - if (ev.button != MEvent.button) - MEvent.clicks = 0; - switch (ev.button) - { - case Button1: - /* allow shift+left click to extend selection */ - if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report)) - { - if (MEvent.button == Button1 && clickintime) - selection_rotate (ev.x, ev.y); - else - selection_extend (ev.x, ev.y, 1); - } + case Button1: + /* allow shift+left click to extend selection */ + if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report)) + { + if (MEvent.button == Button1 && clickintime) + selection_rotate (ev.x, ev.y); else - { - if (MEvent.button == Button1 && clickintime) - MEvent.clicks++; - else - MEvent.clicks = 1; + selection_extend (ev.x, ev.y, 1); + } + else + { + if (MEvent.button == Button1 && clickintime) + MEvent.clicks++; + else + MEvent.clicks = 1; - selection_click (MEvent.clicks, ev.x, ev.y); - } + selection_click (MEvent.clicks, ev.x, ev.y); + } - MEvent.button = Button1; - break; + MEvent.button = Button1; + break; - case Button3: - if (MEvent.button == Button3 && clickintime) - selection_rotate (ev.x, ev.y); - else - selection_extend (ev.x, ev.y, 1); - MEvent.button = Button3; - break; - } + case Button3: + if (MEvent.button == Button3 && clickintime) + selection_rotate (ev.x, ev.y); + else + selection_extend (ev.x, ev.y, 1); + MEvent.button = Button3; + break; } - MEvent.time = ev.time; - return; } + MEvent.time = ev.time; + return; } /* @@ -1830,7 +1817,7 @@ } void -rxvt_term::button_release (const XButtonEvent &ev) +rxvt_term::button_release (XButtonEvent &ev) { int reportmode = 0; @@ -1852,93 +1839,85 @@ #endif if (ev.window == TermWin.vt) { -#ifdef RXVT_GRAPHICS - if (ev.subwindow != None) - rxvt_Gr_ButtonRelease (ev.x, ev.y); - else -#endif - + if (reportmode) { - if (reportmode) - { - /* mouse report from vt window */ - /* don't report release of wheel "buttons" */ - if (ev.button >= 4) - return; + /* mouse report from vt window */ + /* don't report release of wheel "buttons" */ + if (ev.button >= 4) + return; #ifdef MOUSE_REPORT_DOUBLECLICK - /* only report the release of 'slow' single clicks */ - if (MEvent.button != AnyButton - && (ev.button != MEvent.button - || (ev.time - MEvent.time - > MULTICLICK_TIME / 2))) - { - MEvent.clicks = 0; - MEvent.button = AnyButton; - mouse_report (ev); - } -#else /* MOUSE_REPORT_DOUBLECLICK */ + /* only report the release of 'slow' single clicks */ + if (MEvent.button != AnyButton + && (ev.button != MEvent.button + || (ev.time - MEvent.time + > MULTICLICK_TIME / 2))) + { + MEvent.clicks = 0; MEvent.button = AnyButton; mouse_report (ev); -#endif /* MOUSE_REPORT_DOUBLECLICK */ - return; } - /* - * dumb hack to compensate for the failure of click-and-drag - * when overriding mouse reporting - */ - if (PrivateModes & PrivMode_mouse_report - && bypass_keystate - && ev.button == Button1 && MEvent.clicks <= 1) - selection_extend (ev.x, ev.y, 0); - - switch (ev.button) - { - case Button1: - case Button3: - selection_make (ev.time); - break; - case Button2: - selection_request (ev.time, ev.x, ev.y); - break; +#else /* MOUSE_REPORT_DOUBLECLICK */ + MEvent.button = AnyButton; + mouse_report (ev); +#endif /* MOUSE_REPORT_DOUBLECLICK */ + return; + } + /* + * dumb hack to compensate for the failure of click-and-drag + * when overriding mouse reporting + */ + if (PrivateModes & PrivMode_mouse_report + && bypass_keystate + && ev.button == Button1 && MEvent.clicks <= 1) + selection_extend (ev.x, ev.y, 0); + + switch (ev.button) + { + case Button1: + case Button3: + selection_make (ev.time); + break; + case Button2: + selection_request (ev.time, ev.x, ev.y); + break; #ifdef MOUSE_WHEEL - case Button4: - case Button5: - { - int i; - page_dirn v; + case Button4: + case Button5: + { + int i; + page_dirn v; - v = (ev.button == Button4) ? UP : DN; - if (ev.state & ShiftMask) - i = 1; - else if ((Options & Opt_mouseWheelScrollPage)) - i = TermWin.nrow - 1; - else - i = 5; + v = (ev.button == Button4) ? UP : DN; + if (ev.state & ShiftMask) + i = 1; + else if ((Options & Opt_mouseWheelScrollPage)) + i = TermWin.nrow - 1; + else + i = 5; # ifdef MOUSE_SLIP_WHEELING - if (ev.state & ControlMask) - { - mouse_slip_wheel_speed += (v ? -1 : 1); - mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY; - } + if (ev.state & ControlMask) + { + mouse_slip_wheel_speed += (v ? -1 : 1); + mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY; + } # endif # ifdef JUMP_MOUSE_WHEEL - scr_page (v, i); + scr_page (v, i); + scr_refresh (SMOOTH_REFRESH); + scrollbar_show (1); +# else + while (i--) + { + scr_page (v, 1); scr_refresh (SMOOTH_REFRESH); scrollbar_show (1); -# else - while (i--) - { - scr_page (v, 1); - scr_refresh (SMOOTH_REFRESH); - scrollbar_show (1); - } + } # endif - } - break; + } + break; #endif - } } } #ifdef MENUBAR @@ -3017,6 +2996,7 @@ * 50 = change font * * rxvt extensions: + * 9 = change locale (NYI) * 10 = menu (may change in future) * 20 = bg pixmap * 39 = change default fg color @@ -3117,7 +3097,21 @@ case XTerm_logfile: break; case XTerm_font: - change_font (0, str); + change_font (str); + break; + case XTerm_locale: + if (str[0] == '?' && !str[1]) + tt_printf ("%-.250s\n", locale); + else + { + set_locale (str); + im_cb (); + + // TODO: call selection_make with the right values set + // to re-fresh the selection. + if (display->selection_owner == this) + display->set_selection_owner (0); + } break; #if 0 case XTerm_dumpscreen: /* no error notices */ @@ -3478,7 +3472,6 @@ { unsigned char ch, cmd = cmd_getc (); -#ifndef RXVT_GRAPHICS if (cmd == 'Q') { /* query graphics */ tt_printf ("\033G0\n"); /* no graphics */ @@ -3488,51 +3481,6 @@ do ch = cmd_getc (); while (ch != ':'); -#else - unsigned int nargs; - int args[NGRX_PTS]; - unsigned char *text = NULL; - - if (cmd == 'Q') - { /* query graphics */ - tt_printf ("\033G1\n"); /* yes, graphics (color) */ - return; - } - for (nargs = 0; nargs < (sizeof (args) / sizeof (args[0])) - 1;) - { - int neg; - - ch = cmd_getc (); - neg = (ch == '-'); - if (neg || ch == '+') - ch = cmd_getc (); - - for (args[nargs] = 0; isdigit (ch); ch = cmd_getc ()) - args[nargs] = args[nargs] * 10 + (ch - '0'); - if (neg) - args[nargs] = -args[nargs]; - - nargs++; - args[nargs] = 0; - if (ch != ';') - break; - } - - if ((cmd == 'T') && (nargs >= 5)) - { - int i, len = args[4]; - - text = (unsigned char *)rxvt_malloc ((len + 1) * sizeof (char)); - - if (text != NULL) - { - for (i = 0; i < len; i++) - text[i] = cmd_getc (); - text[len] = '\0'; - } - } - Gr_do_graphics (cmd, nargs, args, text); -#endif } /*}}} */