--- rxvt-unicode/src/command.C 2012/05/25 18:45:40 1.511 +++ rxvt-unicode/src/command.C 2014/04/29 12:51:41 1.547 @@ -6,7 +6,7 @@ * Copyright (c) 1992 John Bovey, University of Kent at Canterbury * - original version * Copyright (c) 1994 Robert Nation - * - extensive modifications + * - extensive modifications * Copyright (c) 1995 Garrett D'Amore * - vt100 printing * Copyright (c) 1995 Steven Hirsch @@ -22,12 +22,12 @@ * and Linux 1.2.x * Copyright (c) 1997,1998 Oezguer Kesim * Copyright (c) 1998-2001 Geoff Wing - * - extensive modifications + * - extensive modifications * Copyright (c) 1998 Alfredo K. Kojima * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * Copyright (c) 2003 Rob McMullen - * Copyright (c) 2003-2011 Marc Lehmann + * Copyright (c) 2003-2014 Marc Lehmann * Copyright (c) 2007 Emanuele Giaquinta * * This program is free software; you can redistribute it and/or modify @@ -133,7 +133,7 @@ 0, }; -void +void ecb_cold rxvt_term::iso14755_54 (int x, int y) { x = Pixel2Col (x); @@ -151,7 +151,7 @@ if (t != NOCHAR || !x) { - iso14755_51 (l.t[x], l.r[x], x, y); + iso14755_51 (l.t[x], l.r[x], x, y, view_start); iso14755buf = ISO_14755_54; break; } @@ -160,8 +160,8 @@ } } -void -rxvt_term::iso14755_51 (unicode_t ch, rend_t r, int x, int y) +void ecb_cold +rxvt_term::iso14755_51 (unicode_t ch, rend_t r, int x, int y, int y2) { rxvt_fontset *fs = FONTSET (r); wchar_t *chr, *alloc, ch2, **fname; @@ -184,6 +184,9 @@ len = 1; } + char rowcol[40]; + snprintf (rowcol, sizeof rowcol, "col %d row %d @%d", x, y, y2); + char attr[80]; // plenty sprintf (attr, "%08x = fg %d bg %d%s%s%s%s%s%s", @@ -205,7 +208,6 @@ max_it (width, wcswidth (fname[i], wcslen (fname[i]))); } - max_it (width, 8+5); // for char + hex max_it (width, strlen (attr)); if (y >= 0) @@ -214,7 +216,9 @@ x = 0; } - scr_overlay_new (x, y, width, len * 2 + 1); + scr_overlay_new (x, y, width, len * 2 + 2); + + scr_overlay_set (0, 0, rowcol); r = SET_STYLE (OVERLAY_RSTYLE, GET_STYLE (r)); @@ -225,16 +229,16 @@ ch = *chr++; sprintf (buf, "%8x", ch); - scr_overlay_set (0, y, buf); - scr_overlay_set (9, y, '='); + scr_overlay_set (0, y + 1, buf); + scr_overlay_set (9, y + 1, '='); # if !UNICODE_3 if (ch >= 0x10000) ch = 0xfffd; # endif - scr_overlay_set (11, y, ch, r); + scr_overlay_set (11, y + 1, ch, r); if (WCWIDTH (ch) >= 2) - scr_overlay_set (12, y, NOCHAR, r); + scr_overlay_set (12, y + 1, NOCHAR, r); } // { @@ -242,10 +246,10 @@ // snprintf (buf, sizeof (buf), "(%.4d|%.4d)", x, y); // scr_overlay_set (0, 0, buf); // } - scr_overlay_set (0, len , attr); + scr_overlay_set (0, len + 1, attr); for (int i = 0; i < len; i++) { - scr_overlay_set (0, len + 1 + i, fname[i]); + scr_overlay_set (0, len + 2 + i, fname[i]); free (fname[i]); } @@ -256,7 +260,7 @@ } #endif -void +void ecb_cold rxvt_term::commit_iso14755 () { wchar_t ch = iso14755buf & ISO_14755_MASK; @@ -284,7 +288,7 @@ iso14755buf = 0; } -static int +static int ecb_cold hex_keyval (XKeyEvent &ev) { // check whether this event corresponds to a hex digit @@ -303,7 +307,7 @@ } #endif -static inline KeySym +static inline KeySym ecb_cold translate_keypad (KeySym keysym, bool kp) { #ifdef XK_KP_Home @@ -339,7 +343,7 @@ return keysym; } -static inline int +static inline int ecb_cold map_function_key (KeySym keysym) { int param = 0; @@ -398,13 +402,23 @@ return param; } -void +static inline wchar_t * +rxvt_wcsdup (const wchar_t *str, int len) +{ + wchar_t *r = (wchar_t *)rxvt_malloc ((len + 1) * sizeof (wchar_t)); + memcpy (r, str, len * sizeof (wchar_t)); + r[len] = 0; + return r; +} + +void ecb_cold rxvt_term::key_press (XKeyEvent &ev) { int ctrl, meta, shft, len; KeySym keysym; int valid_keysym; - char kbuf[KBUFSZ]; + char rkbuf[KBUFSZ + 1]; + char *kbuf = rkbuf + 1; #if ISO_14755 if (iso14755buf & ISO_14755_52) @@ -423,7 +437,7 @@ kbuf[0] = 0; -#ifdef USE_XIM +#if USE_XIM if (Input_Context) { Status status_return; @@ -484,161 +498,6 @@ if (valid_keysym) { -#ifdef KEYSYM_RESOURCE - if (keyboard->dispatch (this, keysym, ev.state)) - return; -#endif - - if (saveLines) - { -#ifdef UNSHIFTED_SCROLLKEYS - if (!ctrl && !meta) -#else - if (IS_SCROLL_MOD) -#endif - { - int lnsppg; - -#ifdef PAGING_CONTEXT_LINES - lnsppg = nrow - PAGING_CONTEXT_LINES; -#else - lnsppg = nrow * 4 / 5; -#endif - max_it (lnsppg, 1); - - if (keysym == XK_Prior) - { - scr_page (UP, lnsppg); - return; - } - else if (keysym == XK_Next) - { - scr_page (DN, lnsppg); - return; - } - } -#ifdef SCROLL_ON_UPDOWN_KEYS - if (IS_SCROLL_MOD) - { - if (keysym == XK_Up) - { - scr_page (UP, 1); - return; - } - else if (keysym == XK_Down) - { - scr_page (DN, 1); - return; - } - } -#endif -#ifdef SCROLL_ON_HOMEEND_KEYS - if (IS_SCROLL_MOD) - { - if (keysym == XK_Home) - { - scr_move_to (0, 1); - return; - } - else if (keysym == XK_End) - { - scr_move_to (1, 1); - return; - } - } -#endif - } - - if (shft) - { - /* Shift + F1 - F10 generates F11 - F20 */ - if (keysym >= XK_F1 && keysym <= XK_F10) - { - keysym += (XK_F11 - XK_F1); - shft = 0; /* turn off Shift */ - } - else if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys)) - { - switch (keysym) - { - /* normal XTerm key bindings */ - case XK_Insert: /* Shift+Insert = paste mouse selection */ - selection_request (ev.time); - return; -#if TODO - /* rxvt extras */ - case XK_KP_Add: /* Shift+KP_Add = bigger font */ - return; - case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ - return; -#endif - } - } - } - -#if ENABLE_FRILLS || ISO_14755 - // ISO 14755 support - if (iso14755buf & (ISO_14755_STARTED | ISO_14755_51)) - { - int hv; - - if (iso14755buf & ISO_14755_51 - && (keysym == XK_space || keysym == XK_KP_Space - || keysym == XK_Return || keysym == XK_KP_Enter)) - { - commit_iso14755 (); - iso14755buf = ISO_14755_51; -# if ISO_14755 - iso14755_51 (0); -# endif - return; - } - else if (keysym == XK_BackSpace) - { - iso14755buf = ((iso14755buf & ISO_14755_MASK) >> 4) | ISO_14755_51; -# if ISO_14755 - iso14755_51 (iso14755buf & ISO_14755_MASK); -# endif - return; - } - else if ((hv = hex_keyval (ev)) >= 0) - { - iso14755buf = ((iso14755buf << 4) & ISO_14755_MASK) - | hv | ISO_14755_51; -# if ISO_14755 - iso14755_51 (iso14755buf & ISO_14755_MASK); -# endif - return; - } - else - { -# if ISO_14755 - scr_overlay_off (); -# endif - iso14755buf = 0; - } - } - else if (option (Opt_iso14755) && - ((ctrl && (keysym == XK_Shift_L || keysym == XK_Shift_R)) - || (shft && (keysym == XK_Control_L || keysym == XK_Control_R)))) - if (!(iso14755buf & ISO_14755_STARTED)) - { - iso14755buf |= ISO_14755_STARTED; -# if ISO_14755 - scr_overlay_new (0, -1, sizeof ("ISO 14755 mode") - 1, 1); - scr_overlay_set (0, 0, "ISO 14755 mode"); -# endif - } -#endif - -#ifdef PRINTPIPE - if (keysym == XK_Print) - { - scr_printscreen (ctrl | shft); - return; - } -#endif - if (keysym >= 0xFF00 && keysym <= 0xFFFF) { bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; @@ -830,9 +689,193 @@ } } + /* escape prefix */ + if (len && meta +#ifdef META8_OPTION + && meta_char == C0_ESC +#endif + ) + { + *--kbuf = C0_ESC; + len++; + } + if (HOOK_INVOKE ((this, HOOK_KEY_PRESS, DT_XEVENT, &ev, DT_INT, keysym, DT_STR_LEN, kbuf, len, DT_END))) return; + if (valid_keysym) + { +#ifdef KEYSYM_RESOURCE + if (keyboard->dispatch (this, keysym, ev.state, kbuf, len)) + return; +#endif + + if (saveLines) + { +#ifdef UNSHIFTED_SCROLLKEYS + if (!ctrl && !meta) +#else + if (IS_SCROLL_MOD) +#endif + { + int lnsppg; + +#ifdef PAGING_CONTEXT_LINES + lnsppg = nrow - PAGING_CONTEXT_LINES; +#else + lnsppg = nrow * 4 / 5; +#endif + max_it (lnsppg, 1); + + if (keysym == XK_Prior) + { + scr_page (lnsppg); + return; + } + else if (keysym == XK_Next) + { + scr_page (-lnsppg); + return; + } + } +#ifdef SCROLL_ON_UPDOWN_KEYS + if (IS_SCROLL_MOD) + { + if (keysym == XK_Up) + { + scr_page (1); + return; + } + else if (keysym == XK_Down) + { + scr_page (-1); + return; + } + } +#endif +#ifdef SCROLL_ON_HOMEEND_KEYS + if (IS_SCROLL_MOD) + { + if (keysym == XK_Home) + { + scr_changeview (top_row); + return; + } + else if (keysym == XK_End) + { + scr_changeview (0); + return; + } + } +#endif + } + + if (shft) + { + /* Shift + F1 - F10 generates F11 - F20 */ + if (keysym >= XK_F1 && keysym <= XK_F10) + { + keysym += (XK_F11 - XK_F1); + shft = 0; /* turn off Shift */ + } + else if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys)) + { + switch (keysym) + { + /* normal XTerm key bindings */ + case XK_Insert: /* Shift+Insert = paste mouse selection */ + selection_request (ev.time); + return; +#if TODO + /* rxvt extras */ + case XK_KP_Add: /* Shift+KP_Add = bigger font */ + return; + case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ + return; +#endif + } + } + } + + if (ctrl && meta && (keysym == XK_c || keysym == XK_v)) + { + if (keysym == XK_v) + selection_request (ev.time, Sel_Clipboard); + else if (selection.len > 0) + { + free (selection.clip_text); + selection.clip_text = rxvt_wcsdup (selection.text, selection.len); + selection.clip_len = selection.len; + selection_grab (CurrentTime, true); + } + + return; + } + +#if ENABLE_FRILLS || ISO_14755 + // ISO 14755 support + if (iso14755buf & (ISO_14755_STARTED | ISO_14755_51)) + { + int hv; + + if (iso14755buf & ISO_14755_51 + && (keysym == XK_space || keysym == XK_KP_Space + || keysym == XK_Return || keysym == XK_KP_Enter)) + { + commit_iso14755 (); + iso14755buf = ISO_14755_51; +# if ISO_14755 + iso14755_51 (0); +# endif + return; + } + else if (keysym == XK_BackSpace) + { + iso14755buf = ((iso14755buf & ISO_14755_MASK) >> 4) | ISO_14755_51; +# if ISO_14755 + iso14755_51 (iso14755buf & ISO_14755_MASK); +# endif + return; + } + else if ((hv = hex_keyval (ev)) >= 0) + { + iso14755buf = ((iso14755buf << 4) & ISO_14755_MASK) + | hv | ISO_14755_51; +# if ISO_14755 + iso14755_51 (iso14755buf & ISO_14755_MASK); +# endif + return; + } + else + { +# if ISO_14755 + scr_overlay_off (); +# endif + iso14755buf = 0; + } + } + else if (option (Opt_iso14755) && + ((ctrl && (keysym == XK_Shift_L || keysym == XK_Shift_R)) + || (shft && (keysym == XK_Control_L || keysym == XK_Control_R)))) + if (!(iso14755buf & ISO_14755_STARTED)) + { + iso14755buf |= ISO_14755_STARTED; +# if ISO_14755 + scr_overlay_new (0, -1, sizeof ("ISO 14755 mode") - 1, 1); + scr_overlay_set (0, 0, "ISO 14755 mode"); +# endif + } +#endif + +#ifdef PRINTPIPE + if (keysym == XK_Print) + { + scr_printscreen (ctrl | shft); + return; + } +#endif + } + if (len <= 0) return; /* not mapped */ @@ -843,21 +886,10 @@ want_refresh = 1; } - /* escape prefix */ - if (meta -#ifdef META8_OPTION - && meta_char == C0_ESC -#endif - ) - { - const char ch = C0_ESC; - tt_write (&ch, 1); - } - tt_write (kbuf, (unsigned int)len); } -void +void ecb_cold rxvt_term::key_release (XKeyEvent &ev) { #if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755 || ENABLE_PERL @@ -939,7 +971,7 @@ { flush_ev.stop (); -#ifdef HAVE_BG_PIXMAP +#ifdef HAVE_IMG if (bg_flags & BG_NEEDS_REFRESH) { bg_flags &= ~BG_NEEDS_REFRESH; @@ -989,7 +1021,7 @@ scr_refresh (); scrollBar.show (1); -#ifdef USE_XIM +#if USE_XIM im_send_spot (); #endif } @@ -1075,7 +1107,7 @@ void rxvt_term::sel_scroll_cb (ev::timer &w, int revents) { - if (scr_page (scroll_selection_dir, scroll_selection_lines)) + if (scr_page (scroll_selection_lines)) { selection_extend (selection_save_x, selection_save_y, selection_save_state); want_refresh = 1; @@ -1090,7 +1122,7 @@ void rxvt_term::slip_wheel_cb (ev::timer &w, int revents) { - if (scr_changeview (view_start - mouse_slip_wheel_speed)) + if (scr_page (mouse_slip_wheel_speed)) { want_refresh = 1; refresh_check (); @@ -1221,7 +1253,7 @@ refresh_check (); } -void +void ecb_cold rxvt_term::pointer_unblank () { XDefineCursor (dpy, vt, TermWin_cursor); @@ -1236,7 +1268,7 @@ } #ifdef POINTER_BLANK -void +void ecb_cold rxvt_term::pointer_blank () { if (!option (Opt_pointerBlank)) @@ -1248,7 +1280,7 @@ hidden_pointer = 1; } -void +void ecb_cold rxvt_term::pointer_cb (ev::timer &w, int revents) { make_current (); @@ -1350,7 +1382,7 @@ } /*{{{ process an X event */ -void +void ecb_hot rxvt_term::x_cb (XEvent &ev) { make_current (); @@ -1463,11 +1495,22 @@ while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev)) ; -#ifdef HAVE_BG_PIXMAP + bool want_position_change = SHOULD_INVOKE (HOOK_POSITION_CHANGE); + bool moved = false; +#ifdef HAVE_BG_PIXMAP if (bg_window_position_sensitive ()) { + want_position_change = true; + if (bg_img == 0) + moved = true; + } +#endif + + if (want_position_change) + { int x, y; + if (ev.xconfigure.send_event) { x = ev.xconfigure.x; @@ -1476,11 +1519,14 @@ else get_window_origin (x, y); - if (bg_set_position (x, y) - || !(bg_flags & BG_IS_VALID)) - moved = true; + if (x != parent_x || y != parent_y) + { + parent_x = x; + parent_y = y; + HOOK_INVOKE ((this, HOOK_POSITION_CHANGE, DT_INT, x, DT_INT, y, DT_END)); + moved = true; + } } -#endif if (szHint.width != ev.xconfigure.width || szHint.height != ev.xconfigure.height) { @@ -1513,19 +1559,14 @@ case MapNotify: #ifdef HAVE_BG_PIXMAP - /* This is needed specifically to fix the case of no window manager or a - * non-reparenting window manager. In those cases we never get first - * ConfigureNotify. Also that speeds startup under normal WM, by taking - * care of multiplicity of ConfigureNotify events arriving while WM does - * reparenting. - * We should not render background immediately, as there could be several - * ConfigureNotify's to follow. Lets take care of all of them in one scoop - * by scheduling background redraw as soon as we can, but giving a short - * bit of time for ConfigureNotifies to arrive. - * We should render background PRIOR to drawing any text, but AFTER all - * of ConfigureNotifys for the best results. - */ - if (!(bg_flags & BG_IS_VALID)) + // This is needed at startup for the case of no window manager + // or a non-reparenting window manager and also because we + // defer bg image updates if the window is not mapped. The + // short delay is to optimize for multiple ConfigureNotify + // events at startup when the window manager reparents the + // window, so as to perform the computation after we have + // received all of them. + if (bg_img == 0) update_background_ev.start (0.025); #endif mapped = 1; @@ -1627,6 +1668,7 @@ if (ev.xbutton.y < int_bwidth || Pixel2Row (ev.xbutton.y) > (nrow-1)) { + page_dirn scroll_selection_dir; int dist; /* don't clobber the current delay if we are @@ -1659,6 +1701,7 @@ + 1; min_it (scroll_selection_lines, SELECTION_SCROLL_MAX_LINES); + scroll_selection_lines *= scroll_selection_dir; } else { @@ -1715,7 +1758,7 @@ } #if ENABLE_FRILLS -void +void ecb_cold rxvt_term::set_urgency (bool enable) { if (enable == urgency_hint) @@ -1731,7 +1774,7 @@ } #endif -void +void ecb_cold rxvt_term::focus_in () { if (!focus) @@ -1766,7 +1809,7 @@ } } -void +void ecb_cold rxvt_term::focus_out () { if (focus) @@ -1809,7 +1852,7 @@ } } -void +void ecb_cold rxvt_term::update_fade_color (unsigned int idx) { #if OFF_FOCUS_FADING @@ -1822,8 +1865,8 @@ #endif } -#if ENABLE_TRANSPARENCY || ENABLE_PERL -void +#if BG_IMAGE_FROM_ROOT || ENABLE_PERL +void ecb_hot rxvt_term::rootwin_cb (XEvent &ev) { make_current (); @@ -1832,7 +1875,6 @@ && HOOK_INVOKE ((this, HOOK_ROOT_EVENT, DT_XEVENT, &ev, DT_END))) return; -# if ENABLE_TRANSPARENCY switch (ev.type) { case PropertyNotify: @@ -1843,13 +1885,18 @@ if (ev.xproperty.atom == xa[XA_XROOTPMAP_ID] || ev.xproperty.atom == xa[XA_ESETROOT_PMAP_ID]) { - bg_set_root_pixmap (); - update_background (); +#if BG_IMAGE_FROM_ROOT + if (option (Opt_transparent)) + { + rxvt_img::new_from_root (this)->replace (root_img); + update_background (); + } +#endif + HOOK_INVOKE ((this, HOOK_ROOTPMAP_CHANGE, DT_END)); } break; } -# endif refresh_check (); } @@ -2180,24 +2227,23 @@ case Button4: case Button5: { - int i; - page_dirn v; + int lines; + page_dirn dirn; - v = ev.button == Button4 ? UP : DN; + dirn = ev.button == Button4 ? UP : DN; if (ev.state & ShiftMask) - i = 1; + lines = 1; else if (option (Opt_mouseWheelScrollPage)) - i = nrow - 1; + lines = nrow - 1; else - i = 5; + lines = 5; # ifdef MOUSE_SLIP_WHEELING if (ev.state & ControlMask) { - mouse_slip_wheel_speed += v ? -1 : 1; - if (mouse_slip_wheel_speed < -nrow) mouse_slip_wheel_speed = -nrow; - if (mouse_slip_wheel_speed > +nrow) mouse_slip_wheel_speed = +nrow; + mouse_slip_wheel_speed += dirn; + clamp_it (mouse_slip_wheel_speed, -nrow, nrow); if (!slip_wheel_ev.is_active ()) slip_wheel_ev.start (SCROLLBAR_CONTINUOUS_DELAY, SCROLLBAR_CONTINUOUS_DELAY); @@ -2205,7 +2251,7 @@ else # endif { - scr_page (v, i); + scr_page (dirn, lines); scrollBar.show (1); } } @@ -2217,7 +2263,7 @@ /*}}} */ -void +void ecb_hot rxvt_term::cmd_parse () { wchar_t ch = NOCHAR; @@ -2346,7 +2392,7 @@ } // read the next character -wchar_t +wchar_t ecb_hot rxvt_term::next_char () NOTHROW { while (cmdbuf_ptr < cmdbuf_endp) @@ -2368,6 +2414,8 @@ if (len == (size_t)-1) { mbstate.reset (); // reset now undefined conversion state + // a -1 might indicate that a previous incomplete char is invalid (previous return -2) + // in which case we "erroneously" return the next byte which might be valid. return (unsigned char)*cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through } @@ -2380,7 +2428,7 @@ } // read the next octet -uint32_t +uint32_t ecb_hot rxvt_term::next_octet () NOTHROW { return cmdbuf_ptr < cmdbuf_endp @@ -2390,7 +2438,7 @@ static class out_of_input out_of_input; -wchar_t +wchar_t ecb_hot rxvt_term::cmd_getc () THROW ((class out_of_input)) { wchar_t c = next_char (); @@ -2401,7 +2449,7 @@ return c; } -uint32_t +uint32_t ecb_hot rxvt_term::cmd_get8 () THROW ((class out_of_input)) { uint32_t c = next_octet (); @@ -2415,7 +2463,7 @@ /*{{{ print pipe */ /*----------------------------------------------------------------------*/ #ifdef PRINTPIPE -FILE * +FILE * ecb_cold rxvt_term::popen_printer () { FILE *stream = popen (rs[Rs_print_pipe] ? rs[Rs_print_pipe] : PRINTPIPE, "w"); @@ -2426,7 +2474,7 @@ return stream; } -int +int ecb_cold rxvt_term::pclose_printer (FILE *stream) { fflush (stream); @@ -2436,7 +2484,7 @@ /* * simulate attached vt100 printer */ -void +void ecb_cold rxvt_term::process_print_pipe () { FILE *fd = popen_printer (); @@ -2501,7 +2549,7 @@ }; /*{{{ process non-printing single characters */ -void +void ecb_hot rxvt_term::process_nonprinting (unicode_t ch) { switch (ch) @@ -2557,7 +2605,7 @@ /*{{{ process VT52 escape sequences */ -void +void ecb_cold rxvt_term::process_escape_vt52 (unicode_t ch) { int row, col; @@ -2617,7 +2665,7 @@ /*{{{ process escape sequences */ -void +void ecb_hot rxvt_term::process_escape_seq () { unicode_t ch = cmd_getc (); @@ -2779,10 +2827,10 @@ make_byte (0,0,0,0,0,0,0,0), /* x, y, z, {, |, }, ~, */ }; -void +void ecb_hot rxvt_term::process_csi_seq () { - unicode_t ch, priv, i; + unicode_t ch, priv, prev_ch, i; unsigned int nargs, p; int n, ndef; int arg[ESC_ARGS] = { }; @@ -2798,6 +2846,7 @@ ch = cmd_getc (); } + prev_ch = 0; /* read any numerical arguments */ for (n = -1; ch < CSI_ICH; ) { @@ -2817,6 +2866,7 @@ else if (IS_CONTROL (ch)) process_nonprinting (ch); + prev_ch = ch; ch = cmd_getc (); } @@ -3060,6 +3110,11 @@ priv_modes |= PrivMode_LFNL; break; + case CSI_71: // DESCUSR: set cursor style + if (prev_ch == ' ') + set_cursor_style (arg[0]); + break; + /* * PRIVATE USE beyond this point. All CSI_7? sequences here */ @@ -3202,7 +3257,7 @@ unicode_t ch; bool seen_esc = false; unsigned int n = 0; - wchar_t string[STRING_MAX]; + wchar_t string[CBUFSIZ]; while ((ch = cmd_getc ()) != NOCHAR) { @@ -3227,7 +3282,7 @@ seen_esc = false; - if (n >= STRING_MAX - 1) + if (n >= sizeof (string) - 1) // stop at some sane length return NULL; @@ -3354,7 +3409,7 @@ && actual_format == 8) str = (const char *)(value); - tt_printf ("\033]%d;%s%c", op, str, resp); + tt_printf ("\033]%d;%s%c", op, option (Opt_insecure) ? str : "", resp); XFree (value); } @@ -3432,14 +3487,15 @@ case URxvt_Color_border: process_color_seq (op, Color_border, str, resp); break; -#if ENABLE_TRANSPARENCY + +#if BG_IMAGE_FROM_ROOT case URxvt_Color_tint: process_color_seq (op, Color_tint, str, resp); { bool changed = false; if (ISSET_PIXCOLOR (Color_tint)) - changed = bg_set_tint (pix_colors_focused [Color_tint]); + changed = root_effects.set_tint (pix_colors_focused [Color_tint]); if (changed) update_background (); @@ -3453,15 +3509,10 @@ if (!strcmp (str, "?")) { char str[256]; - int h_scale = 0, v_scale = 0; - int h_align = 0, v_align = 0; - if (image_vec.size () > 0) - { - h_scale = image_vec[0].h_scale; - v_scale = image_vec[0].v_scale; - h_align = image_vec[0].h_align; - v_align = image_vec[0].v_align; - } + int h_scale = fimage.h_scale; + int v_scale = fimage.v_scale; + int h_align = fimage.h_align; + int v_align = fimage.v_align; sprintf (str, "[%dx%d+%d+%d]", h_scale, v_scale, @@ -3474,22 +3525,20 @@ if (*str != ';') { - if (image_vec.size () > 0) - changed = image_vec[0].set_file_geometry (str); - else + try + { + fimage.set_file_geometry (this, str); + changed = true; + } + catch (const class rxvt_failure_exception &e) { - rxvt_image *image = new_image (); - if (!image->set_file_geometry (str)) - image_vec.pop_back (); - else - changed = true; } } else { str++; - if (image_vec.size () > 0) - changed = image_vec[0].set_geometry (str, true); + if (fimage.set_geometry (str, true)) + changed = true; } if (changed) @@ -3498,7 +3547,8 @@ { int x, y; get_window_origin (x, y); - bg_set_position (x, y); + parent_x = x; + parent_y = y; } update_background (); } @@ -3598,7 +3648,7 @@ * 't' = toggle * so no need for fancy checking */ -int +int ecb_cold rxvt_term::privcases (int mode, unsigned long bit) { int state; @@ -3828,7 +3878,7 @@ /*}}} */ /*{{{ process sgr sequences */ -void +void ecb_hot rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg) { unsigned int i; @@ -3979,6 +4029,22 @@ } } } + +void +rxvt_term::set_cursor_style (int style) +{ + if (!IN_RANGE_INC (style, 0, 4)) + return; + + set_option (Opt_cursorUnderline, style >= 3); + +#ifdef CURSOR_BLINK + set_option (Opt_cursorBlink, !style || (style & 1)); + cursor_blink_reset (); +#endif + + want_refresh = 1; +} /*}}} */ /* ------------------------------------------------------------------------- */