--- rxvt-unicode/src/command.C 2006/01/03 17:34:44 1.229 +++ rxvt-unicode/src/command.C 2006/01/11 05:14:26 1.256 @@ -27,7 +27,7 @@ * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * Copyright (c) 2003 Rob McMullen - * Copyright (c) 2003-2005 Marc Lehmann + * Copyright (c) 2003-2006 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 @@ -52,7 +52,8 @@ #include "command.h" #if HAVE_SCHED_YIELD -# include +#undef HAVE_SCHED_YIELD // disabled for the time being +//# include #endif #ifdef KEYSYM_RESOURCE @@ -269,7 +270,7 @@ } if (len > 0) - tt_write ((unsigned char *)mb, len); + tt_write (mb, len); else scr_bell (); } @@ -307,7 +308,7 @@ static int debug_key = 1; /* accessible by a debugger only */ #endif int valid_keysym; - unsigned char kbuf[KBUFSZ]; + char kbuf[KBUFSZ]; /* * use Num_Lock to toggle Keypad on/off. If Num_Lock is off, allow an @@ -335,7 +336,7 @@ #if 0 #ifdef X_HAVE_UTF8_STRING if (enc_utf8 && 0) // currently disabled, doesn't seem to work, nor is useful - len = Xutf8LookupString (Input_Context, &ev, (char *)kbuf, + len = Xutf8LookupString (Input_Context, &ev, kbuf, KBUFSZ, &keysym, &status_return); else #endif @@ -382,7 +383,7 @@ else #endif { - len = XLookupString (&ev, (char *)kbuf, KBUFSZ, &keysym, &compose); + len = XLookupString (&ev, kbuf, KBUFSZ, &keysym, &compose); valid_keysym = keysym != NoSymbol; } @@ -856,7 +857,7 @@ /* set 8-bit on */ if (meta && (meta_char == 0x80)) { - unsigned char *ch; + char *ch; for (ch = kbuf; ch < kbuf + len; ch++) *ch |= 0x80; @@ -868,6 +869,9 @@ } } + if (HOOK_INVOKE ((this, HOOK_KEY_PRESS, DT_XEVENT, &ev, DT_INT, keysym, DT_STR_LEN, kbuf, len, DT_END))) + return; + if (len <= 0) return; /* not mapped */ @@ -899,7 +903,7 @@ #endif ) { - const unsigned char ch = C0_ESC; + const char ch = C0_ESC; tt_write (&ch, 1); } @@ -921,7 +925,7 @@ /*{{{ rxvt_cmd_write (), rxvt_cmd_getc () */ /* attempt to `write' count to the input buffer */ unsigned int -rxvt_term::cmd_write (const unsigned char *str, unsigned int count) +rxvt_term::cmd_write (const char *str, unsigned int count) { unsigned int n, s; @@ -968,6 +972,44 @@ if (want_refresh) { + if (SHOULD_INVOKE (HOOK_LINE_UPDATE)) + { + int row = -view_start; + int end_row = row + nrow; + + while (row > -nsaved && ROW (row - 1).is_longer ()) + --row; + + do + { + int start_row = row; + line_t *l; + + do + { + l = &ROW (row++); + + if (!(l->f & LINE_FILTERED)) + { + // line not filtered, mark it as filtered + l->f |= LINE_FILTERED; + while (l->is_longer ()) + { + l = &ROW (row++); + l->f |= LINE_FILTERED; + } + + // and filter it + HOOK_INVOKE ((this, HOOK_LINE_UPDATE, DT_INT, start_row, DT_END)); + + break; + } + } + while (l->is_longer () && row < end_row); + } + while (row < end_row); + } + scr_refresh (refresh_type); scrollbar_show (1); #ifdef USE_XIM @@ -1097,7 +1139,7 @@ if (CBUFSIZ == n) { - rxvt_warn ("pty_fill on full buffer, draining input, continuing.\n"); + rxvt_warn ("PLEASE REPORT: pty_fill on full buffer, draining input, continuing.\n"); n = 0; } @@ -1164,7 +1206,7 @@ void rxvt_term::pointer_blank () { - if (! OPTION (Opt_pointerBlank)) + if (!OPTION (Opt_pointerBlank)) return; XDefineCursor (display->display, vt, display->blank_cursor); @@ -1271,33 +1313,6 @@ SET_R (this); SET_LOCALE (locale); -#if defined(CURSOR_BLINK) - if (OPTION (Opt_cursorBlink) && ev.type == KeyPress) - { - if (hidden_cursor) - { - hidden_cursor = 0; - want_refresh = 1; - } - - cursor_blink_ev.start (NOW + BLINK_INTERVAL); - } -#endif - -#if defined(POINTER_BLANK) - if (OPTION (Opt_pointerBlank) && pointerBlankDelay > 0) - { - if (ev.type == MotionNotify - || ev.type == ButtonPress - || ev.type == ButtonRelease) - if (hidden_pointer) - pointer_unblank (); - - if (ev.type == KeyPress && hidden_pointer == 0) - pointer_blank (); - } -#endif - Window unused_root, unused_child; int unused_root_x, unused_root_y; unsigned int unused_mask; @@ -1314,10 +1329,10 @@ case KeyRelease: { -#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755 - KeySym ks; +#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755 || ENABLE_PERL + KeySym keysym; - ks = XLookupKeysym (&ev.xkey, ev.xkey.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/ + keysym = XLookupKeysym (&ev.xkey, ev.xkey.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/ #endif #if ENABLE_FRILLS || ISO_14755 @@ -1332,20 +1347,20 @@ // iso14755 part 5.2 handling: release time // first: controls if ((ev.xkey.state & ControlMask) - && ((ks >= 0x40 && ks <= 0x5f) - || (ks >= 0x61 && ks <= 0x7f))) + && ((keysym >= 0x40 && keysym <= 0x5f) + || (keysym >= 0x61 && keysym <= 0x7f))) { - iso14755buf = ISO_14755_51 | 0x2400 | (ks & 0x1f); + iso14755buf = ISO_14755_51 | 0x2400 | (keysym & 0x1f); commit_iso14755 (); - return; // case-break; + goto skip_switch; } for (unsigned short *i = iso14755_symtab; i[0]; i+= 2) - if (i[0] == ks) + if (i[0] == keysym) { iso14755buf = ISO_14755_51 | i[1]; commit_iso14755 (); - return; // case-break; + goto skip_switch; } scr_bell (); @@ -1374,10 +1389,14 @@ } #endif + if (ev.xany.window == vt + && HOOK_INVOKE ((this, HOOK_KEY_RELEASE, DT_XEVENT, &ev, DT_INT, keysym, DT_END))) + break; + #if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING) if (!(ev.xkey.state & ControlMask)) slip_wheel_ev.stop (); - else if (ks == XK_Control_L || ks == XK_Control_R) + else if (keysym == XK_Control_L || keysym == XK_Control_R) mouse_slip_wheel_speed = 0; #endif break; @@ -1517,18 +1536,20 @@ selection_send (ev.xselectionrequest); break; - case UnmapNotify: - mapped = 0; + case MapNotify: + mapped = 1; #ifdef TEXT_BLINK - text_blink_ev.stop (); + text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL); #endif + HOOK_INVOKE ((this, HOOK_MAP_NOTIFY, DT_XEVENT, &ev, DT_END)); break; - case MapNotify: - mapped = 1; + case UnmapNotify: + mapped = 0; #ifdef TEXT_BLINK - text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL); + text_blink_ev.stop (); #endif + HOOK_INVOKE ((this, HOOK_UNMAP_NOTIFY, DT_XEVENT, &ev, DT_END)); break; #ifdef TRANSPARENT @@ -1552,7 +1573,7 @@ scr_expose (ev.xexpose.x, ev.xexpose.y, ev.xexpose.width, ev.xexpose.height, False); - scr_refresh (refresh_type); + want_refresh = 1; } else { @@ -1597,7 +1618,9 @@ if (ev.xany.window == vt) { - if (ev.xbutton.state & (Button1Mask | Button3Mask)) + if (HOOK_INVOKE ((this, HOOK_MOTION_NOTIFY, DT_XEVENT, &ev, DT_END))) + ; // nop + else if (ev.xbutton.state & (Button1Mask | Button3Mask)) { while (XCheckTypedWindowEvent (disp, vt, MotionNotify, &ev)) ; @@ -1687,12 +1710,41 @@ &unused_mask); scr_move_to (scrollbar_position (ev.xbutton.y) - csrO, scrollbar_size ()); - scr_refresh (refresh_type); + want_refresh = 1; refresh_limit = 0; scrollbar_show (1); } break; } + +skip_switch: ; + +#if defined(CURSOR_BLINK) + if (OPTION (Opt_cursorBlink) && ev.type == KeyPress) + { + if (hidden_cursor) + { + hidden_cursor = 0; + want_refresh = 1; + } + + cursor_blink_ev.start (NOW + BLINK_INTERVAL); + } +#endif + +#if defined(POINTER_BLANK) + if (OPTION (Opt_pointerBlank) && pointerBlankDelay > 0) + { + if (ev.type == MotionNotify + || ev.type == ButtonPress + || ev.type == ButtonRelease) + if (hidden_pointer) + pointer_unblank (); + + if (ev.type == KeyPress && hidden_pointer == 0) + pointer_blank (); + } +#endif } void @@ -1703,7 +1755,7 @@ focus = 1; want_refresh = 1; - PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); #if USE_XIM if (Input_Context != NULL) @@ -1734,7 +1786,7 @@ focus = 0; want_refresh = 1; - PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); #if ENABLE_FRILLS || ISO_14755 if (iso14755buf) @@ -1827,6 +1879,7 @@ { /* same button, within alloted time */ MEvent.clicks++; + if (MEvent.clicks > 1) { /* only report double clicks */ @@ -1856,7 +1909,7 @@ if (ev.button != MEvent.button) MEvent.clicks = 0; - if (!PERL_INVOKE ((this, HOOK_MOUSE_CLICK, DT_XEVENT, &ev, DT_END))) + if (!HOOK_INVOKE ((this, HOOK_BUTTON_PRESS, DT_XEVENT, &ev, DT_END))) switch (ev.button) { case Button1: @@ -2044,8 +2097,10 @@ break; } } + return; } + #if MENUBAR /* * Menubar window processing of button press @@ -2118,6 +2173,9 @@ && ev.button == Button1 && MEvent.clicks <= 1) selection_extend (ev.x, ev.y, 0); + if (HOOK_INVOKE ((this, HOOK_BUTTON_RELEASE, DT_XEVENT, &ev, DT_END))) + return; + switch (ev.button) { case Button1: @@ -2158,21 +2216,11 @@ else { # endif -# ifdef JUMP_MOUSE_WHEEL 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); - } -# endif # ifdef MOUSE_SLIP_WHEELING } -#endif +# endif } break; #endif @@ -2671,8 +2719,8 @@ rxvt_term::cmd_parse () { bool flag = false; - unicode_t ch = NOCHAR; - unsigned char *seq_begin; // remember start of esc-sequence here + wchar_t ch = NOCHAR; + char *seq_begin; // remember start of esc-sequence here for (;;) { @@ -2680,10 +2728,10 @@ { seq_begin = cmdbuf_ptr; ch = next_char (); - } - if (ch == NOCHAR) // TODO: improve - break; + if (ch == NOCHAR) + break; + } if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT) { @@ -2702,11 +2750,11 @@ } /* Read a text string from the input buffer */ - unicode_t buf[UBUFSIZ]; + wchar_t buf[UBUFSIZ]; bool refreshnow = false; int nlines = 0; - unicode_t *str = buf; - unicode_t *eol = str + min (ncol, UBUFSIZ); + wchar_t *str = buf; + wchar_t *eol = str + min (ncol, UBUFSIZ); for (;;) { @@ -2734,7 +2782,9 @@ // scr_add_lines only works for nlines <= nrow - 1. if (nlines >= nrow - 1) { - scr_add_lines (buf, nlines, str - buf); + if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_WCS_LEN, buf, str - buf, DT_END))) + scr_add_lines (buf, str - buf, nlines); + nlines = 0; str = buf; eol = str + min (ncol, UBUFSIZ); @@ -2757,7 +2807,8 @@ ch = next_char (); } - scr_add_lines (buf, nlines, str - buf); + if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_WCS_LEN, buf, str - buf, DT_END))) + scr_add_lines (buf, str - buf, nlines); /* * If there have been a lot of new lines, then update the screen @@ -2773,7 +2824,7 @@ { flag = true; scr_refresh (refresh_type); - flush_ev.stop (); + want_refresh = 1; } } @@ -2798,27 +2849,18 @@ return flag; } -// read the next octet -unicode_t -rxvt_term::next_octet () -{ - return cmdbuf_ptr < cmdbuf_endp - ? *cmdbuf_ptr++ - : NOCHAR; -} - // read the next character -unicode_t +wchar_t rxvt_term::next_char () { while (cmdbuf_ptr < cmdbuf_endp) { // assume 7-bit to be ascii ALWAYS - if (*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b) + if ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b) return *cmdbuf_ptr++; wchar_t wc; - size_t len = mbrtowc (&wc, (char *)cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate); + size_t len = mbrtowc (&wc, cmdbuf_ptr, cmdbuf_endp - cmdbuf_ptr, mbstate); if (len == (size_t)-2) { @@ -2828,7 +2870,7 @@ } if (len == (size_t)-1) - return *cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through + return (unsigned char)*cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through // assume wchar == unicode cmdbuf_ptr += len; @@ -2838,15 +2880,24 @@ return NOCHAR; } +// read the next octet +uint32_t +rxvt_term::next_octet () +{ + return cmdbuf_ptr < cmdbuf_endp + ? (unsigned char)*cmdbuf_ptr++ + : NOCHAR; +} + /* rxvt_cmd_getc () - Return next input character */ /* * Return the next input character after first passing any keyboard input * to the command. */ -unicode_t +wchar_t rxvt_term::cmd_getc () { - unicode_t c = next_char (); + wchar_t c = next_char (); if (c == NOCHAR) throw out_of_input; @@ -2854,10 +2905,10 @@ return c; } -unicode_t +uint32_t rxvt_term::cmd_get8 () { - unicode_t c = next_octet (); + uint32_t c = next_octet (); if (c == NOCHAR) throw out_of_input; @@ -2967,11 +3018,9 @@ break; case C0_ENQ: /* terminal Status */ if (rs[Rs_answerbackstring]) - tt_write ((const unsigned char *)rs[Rs_answerbackstring], - (unsigned int)strlen (rs[Rs_answerbackstring])); + tt_write (rs [Rs_answerbackstring], strlen (rs [Rs_answerbackstring])); else - tt_write ((unsigned char *)VT100_ANS, - (unsigned int)strlen (VT100_ANS)); + tt_write (VT100_ANS, strlen (VT100_ANS)); break; case C0_BEL: /* bell */ scr_bell (); @@ -3136,8 +3185,8 @@ /* 8.3.87: NEXT LINE */ case C1_NEL: /* ESC E */ { - unicode_t nlcr[] = { C0_LF, C0_CR }; - scr_add_lines (nlcr, 1, 2); + wchar_t nlcr[] = { C0_LF, C0_CR }; + scr_add_lines (nlcr, sizeof (nlcr) / sizeof (nlcr [0]), 1); } break; @@ -3169,8 +3218,7 @@ /* 8.3.110: SINGLE CHARACTER INTRODUCER */ case C1_SCI: /* ESC Z */ - tt_write ((const unsigned char *)ESCZ_ANSWER, - (unsigned int) (sizeof (ESCZ_ANSWER) - 1)); + tt_write (ESCZ_ANSWER, sizeof (ESCZ_ANSWER) - 1); break; /* steal obsolete ESC [ c */ /* 8.3.16: CONTROL SEQUENCE INTRODUCER */ @@ -3424,8 +3472,7 @@ break; case CSI_DA: /* 8.3.24: (0) DEVICE ATTRIBUTES */ - tt_write ((const unsigned char *)VT100_ANS, - (unsigned int) (sizeof (VT100_ANS) - 1)); + tt_write (VT100_ANS, sizeof (VT100_ANS) - 1); break; case CSI_SGR: /* 8.3.118: (0) SELECT GRAPHIC RENDITION */ @@ -3637,7 +3684,7 @@ * get input up until STRING TERMINATOR (or BEL) * ends_how is terminator used. returned input must be free()'d */ -unsigned char * +char * rxvt_term::get_to_st (unicode_t &ends_how) { unicode_t ch; @@ -3680,7 +3727,7 @@ ends_how = (ch == 0x5c ? C0_ESC : ch); - return (unsigned char *)rxvt_wcstombs (string); + return rxvt_wcstombs (string); } /*----------------------------------------------------------------------*/ @@ -3690,7 +3737,7 @@ void rxvt_term::process_dcs_seq () { - unsigned char *s; + char *s; unicode_t eh; /* @@ -3719,18 +3766,18 @@ if (ch == ';') { - unsigned char *s = get_to_st (eh); + char *s = get_to_st (eh); if (s) { - process_xterm_seq (arg, (char *)s, eh); + process_xterm_seq (arg, s, eh); free (s); } } } void -rxvt_term::process_color_seq (int report, int color, const char *str, unsigned char resp) +rxvt_term::process_color_seq (int report, int color, const char *str, char resp) { if (str[0] == '?' && !str[1]) { @@ -3746,7 +3793,7 @@ * XTerm escape sequences: ESC ] Ps;Pt (ST|BEL) */ void -rxvt_term::process_xterm_seq (int op, const char *str, unsigned char resp) +rxvt_term::process_xterm_seq (int op, const char *str, char resp) { int changed = 0; int color; @@ -3813,9 +3860,9 @@ break; *name++ = '\0'; - color = atoi (buf); + color = atoi (buf) + minCOLOR; - if (color < 0 || color >= TOTAL_COLORS) + if (!IN_RANGE_EXC (color, minCOLOR, TOTAL_COLORS)) break; if ((buf = strchr (name, ';')) != NULL) @@ -3824,18 +3871,18 @@ if (name[0] == '?' && !name[1]) { unsigned short r, g, b; - pix_colors_focused[color + minCOLOR].get (display, r, g, b); + pix_colors_focused[color].get (display, r, g, b); tt_printf ("\033]%d;%d;rgb:%04x/%04x/%04x%c", XTerm_Color, color, r, g, b, resp); } else - set_window_color (color + minCOLOR, name); + set_window_color (color, name); } break; case XTerm_Color00: process_color_seq (XTerm_Color00, Color_fg, str, resp); break; case XTerm_Color01: - process_color_seq (XTerm_Color00, Color_bg, str, resp); + process_color_seq (XTerm_Color01, Color_bg, str, resp); break; #ifndef NO_CURSORCOLOR case XTerm_Color_cursor: @@ -3877,9 +3924,10 @@ #if XPM_BACKGROUND scale_pixmap (""); /* reset to default scaling */ set_bgPixmap (str); /* change pixmap */ -#endif scr_touch (true); +#endif } + while ((str = strchr (str, ';')) != NULL) { str++; @@ -3892,8 +3940,8 @@ { #ifdef XPM_BACKGROUND resize_pixmap (); -#endif scr_touch (true); +#endif } break; @@ -3963,17 +4011,24 @@ case URxvt_view_up: case URxvt_view_down: - int lines = atoi (str); + { + int lines = atoi (str); - if (lines) - scr_page (op == URxvt_view_up ? UP : DN, lines); - else - { + if (lines) + scr_page (op == URxvt_view_up ? UP : DN, lines); + else scr_erase_savelines (); - } + } break; #endif + +#if ENABLE_PERL + case URxvt_perl: + if (HOOK_INVOKE ((this, HOOK_OSC_SEQ, DT_STR, str, DT_END))) + ; // no responses yet + break; +#endif } } /*----------------------------------------------------------------------*/ @@ -4092,10 +4147,7 @@ { #if ENABLE_STYLES case 1021: - if (mode) - SET_OPTION (Opt_intensityStyles); - else - CLR_OPTION (Opt_intensityStyles); + set_option (Opt_intensityStyles, mode); scr_touch (true); break; @@ -4127,10 +4179,7 @@ set_widthheight (((state ? 132 : 80) * fwidth), height); break; case 4: /* smooth scrolling */ - if (!state) - SET_OPTION (Opt_jumpScroll); - else - CLR_OPTION (Opt_jumpScroll); + set_option (Opt_jumpScroll, !state); break; case 5: /* reverse video */ scr_rvideo_mode (state); @@ -4181,16 +4230,10 @@ break; /* X11 mouse highlighting */ #endif case 1010: /* scroll to bottom on TTY output inhibit */ - if (!state) - SET_OPTION (Opt_scrollTtyOutput); - else - CLR_OPTION (Opt_scrollTtyOutput); + set_option (Opt_scrollTtyOutput, !state); break; case 1011: /* scroll to bottom on key press */ - if (state) - SET_OPTION (Opt_scrollTtyKeypress); - else - CLR_OPTION (Opt_scrollTtyKeypress); + set_option (Opt_scrollTtyKeypress, state); break; case 1047: /* secondary screen w/ clearing last */ if (OPTION (Opt_secondaryScreen)) @@ -4338,7 +4381,7 @@ //case 50: // not variable spacing -#ifndef NO_BRIGHTCOLOR +#if ENABLE_FRILLS case 90: case 91: /* set bright fg color */ case 92: @@ -4393,7 +4436,7 @@ rxvt_term::tt_printf (const char *fmt,...) { va_list arg_ptr; - unsigned char buf[256]; + char buf[256]; va_start (arg_ptr, fmt); vsnprintf ((char *)buf, 256, fmt, arg_ptr); @@ -4408,8 +4451,14 @@ const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT void -rxvt_term::tt_write (const unsigned char *data, unsigned int len) +rxvt_term::tt_write (const char *data, unsigned int len) { + if (HOOK_INVOKE ((this, HOOK_TT_WRITE, DT_STR_LEN, data, len, DT_END))) + return; + + if (pty.pty < 0) + return; + if (v_buflen == 0) { ssize_t written = write (pty.pty, data, min (len, MAX_PTY_WRITE)); @@ -4421,7 +4470,7 @@ len -= written; } - v_buffer = (unsigned char *)realloc (v_buffer, v_buflen + len); + v_buffer = (char *)realloc (v_buffer, v_buflen + len); memcpy (v_buffer + v_buflen, data, len); v_buflen += len;