--- rxvt-unicode/src/command.C 2008/02/16 16:07:29 1.411 +++ rxvt-unicode/src/command.C 2010/10/22 16:49:26 1.456 @@ -164,12 +164,9 @@ rxvt_term::iso14755_51 (unicode_t ch, rend_t r, int x, int y) { rxvt_fontset *fs = FONTSET (r); - rxvt_font *f = (*fs)[fs->find_font (ch)]; - wchar_t *chr, *alloc, ch2, *fname; + wchar_t *chr, *alloc, ch2, **fname; int len; - fname = rxvt_utf8towcs (f->name); - # if ENABLE_COMBINING if (IS_COMPOSE (ch)) { @@ -199,7 +196,14 @@ r & RS_Uline ? " uline" : "", r & RS_Careful ? " careful" : ""); - int width = wcswidth (fname, wcslen (fname)); + int width = 0; + fname = rxvt_temp_buf (len); + for (int i = 0; i < len; i++) + { + rxvt_font *f = (*fs)[fs->find_font_idx (chr[i])]; + fname[i] = rxvt_utf8towcs (f->name); + max_it (width, wcswidth (fname[i], wcslen (fname[i]))); + } max_it (width, 8+5); // for char + hex max_it (width, strlen (attr)); @@ -210,7 +214,7 @@ x = 0; } - scr_overlay_new (x, y, width, len + 2); + scr_overlay_new (x, y, width, len * 2 + 1); r = SET_STYLE (OVERLAY_RSTYLE, GET_STYLE (r)); @@ -239,9 +243,11 @@ // scr_overlay_set (0, 0, buf); // } scr_overlay_set (0, len , attr); - scr_overlay_set (0, len + 1, fname); - - free (fname); + for (int i = 0; i < len; i++) + { + scr_overlay_set (0, len + 1 + i, fname[i]); + free (fname[i]); + } # if ENABLE_COMBINING if (alloc) @@ -284,7 +290,7 @@ static int hex_keyval (XKeyEvent &ev) { - // check wether this event corresponds to a hex digit + // check whether this event corresponds to a hex digit // if the modifiers had not been pressed. for (int index = 0; index < 8; index++) { @@ -418,12 +424,6 @@ ctrl = ev.state & ControlMask; meta = ev.state & ModMetaMask; - if (numlock_state || (ev.state & ModNumLockMask)) - { - numlock_state = (ev.state & ModNumLockMask); - PrivMode ((!numlock_state), PrivMode_aplKP); - } - kbuf[0] = 0; #ifdef USE_XIM @@ -507,6 +507,8 @@ #else lnsppg = nrow * 4 / 5; #endif + max_it (lnsppg, 1); + if (keysym == XK_Prior) { scr_page (UP, lnsppg); @@ -581,7 +583,7 @@ #if ENABLE_FRILLS || ISO_14755 // ISO 14755 support - if (shft && ctrl) + if (iso14755buf & (ISO_14755_STARTED | ISO_14755_51)) { int hv; @@ -621,8 +623,9 @@ iso14755buf = 0; } } - else if ((ctrl && (keysym == XK_Shift_L || keysym == XK_Shift_R)) - || (shft && (keysym == XK_Control_L || keysym == XK_Control_R))) + 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; @@ -646,7 +649,12 @@ bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; unsigned int newlen = 1; - switch (translate_keypad (keysym, kp)) + if (ev.state & ModNumLockMask) + kp = false; + + keysym = translate_keypad (keysym, kp); + + switch (keysym) { #ifndef NO_BACKSPACE_KEY case XK_BackSpace: @@ -1017,7 +1025,7 @@ } scr_refresh (); - scrollbar_show (1); + scrollBar.show (1); #ifdef USE_XIM IMSendSpot (); #endif @@ -1026,7 +1034,7 @@ display->flush (); } -/* checks wether a refresh is requested and starts the refresh timer */ +/* checks whether a refresh is requested and starts the refresh timer */ void rxvt_term::refresh_check () { @@ -1129,8 +1137,11 @@ // that giving a process calling sched_yield () less cpu time than // ones with high nice levels is a useful thing to do. It surely is is // allowed by the sus... as is returning ENOSYS. + // since the linux guys additionally thought that breaking the only + // known workaround against their unusable sched_yield hack is cool, + // we just nanosleep a bit and hope for the best. - struct timespec ts = { 0, 0 }; + struct timespec ts = { 0, 1000 }; nanosleep (&ts, 0); w.stop (); @@ -1190,9 +1201,8 @@ if (revents & ev::READ) // loop, but don't allow a single term to monopolize us - while (pty_fill ()) - if (cmd_parse ()) - break; + for (int i = CBUFCNT; i-- && pty_fill (); ) + cmd_parse (); if (revents & ev::WRITE) pty_write (); @@ -1422,9 +1432,6 @@ break; case ConfigureNotify: - /*fprintf (stderr, "ConfigureNotify for %X, parent is %X, geom is %dx%d%+d%+d, old geom was %dx%d\n", - ev.xconfigure.window, parent[0], ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.x, ev.xconfigure.y, - szHint.width, szHint.height);*/ if (ev.xconfigure.window == parent[0]) { while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev)) @@ -1461,7 +1468,7 @@ break; case SelectionClear: - selection_clear (); + selection_clear (ev.xselectionclear.selection == xa[XA_CLIPBOARD]); break; case SelectionNotify: @@ -1475,12 +1482,12 @@ case MapNotify: #ifdef HAVE_BG_PIXMAP - /* This is needed spcifically to fix the case of no window manager or a + /* 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 arriwing while WM does + * care of multiplicity of ConfigureNotify events arriving while WM does * reparenting. - * We should not render background immidiately, as there could be several + * 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. @@ -1538,7 +1545,7 @@ if (scrollBar.state && ev.xany.window == scrollBar.win) { scrollBar.state = STATE_IDLE; - scrollbar_show (0); + scrollBar.show (0); } } break; @@ -1647,9 +1654,9 @@ &ev.xbutton.x, &ev.xbutton.y, &unused_mask); scr_move_to (scrollbar_position (ev.xbutton.y) - csrO, - scrollbar_size ()); + scrollBar.size ()); want_refresh = 1; - scrollbar_show (1); + scrollBar.show (1); } break; } @@ -1684,6 +1691,22 @@ refresh_check (); } +#if ENABLE_FRILLS +void +rxvt_term::set_urgency (bool enable) +{ + if (enable == urgency_hint) + return; + + if (XWMHints *h = XGetWMHints (dpy, parent[0])) + { + h->flags = h->flags & ~XUrgencyHint | (enable ? XUrgencyHint : 0); + XSetWMHints (dpy, parent[0], h); + urgency_hint = enable; + } +} +#endif + void rxvt_term::focus_in () { @@ -1692,8 +1715,6 @@ focus = 1; want_refresh = 1; - HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); - #if USE_XIM if (Input_Context != NULL) { @@ -1714,14 +1735,10 @@ #endif #if ENABLE_FRILLS if (option (Opt_urgentOnBell)) - { - if (XWMHints *h = XGetWMHints(dpy, parent[0])) - { - h->flags &= ~XUrgencyHint; - XSetWMHints (dpy, parent[0], h); - } - } + set_urgency (0); #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); } } @@ -1733,8 +1750,10 @@ focus = 0; want_refresh = 1; - HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); - +#if ENABLE_FRILLS + if (option (Opt_urgentOnBell)) + set_urgency (0); +#endif #if ENABLE_FRILLS || ISO_14755 if (iso14755buf) { @@ -1761,6 +1780,8 @@ scr_recolour (); } #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); } } @@ -1847,7 +1868,7 @@ #ifdef MOUSE_REPORT_DOUBLECLICK if (ev.button == MEvent.button && clickintime) { - /* same button, within alloted time */ + /* same button, within allowed time */ MEvent.clicks++; if (MEvent.clicks > 1) @@ -2012,7 +2033,7 @@ if (scrollBar.style == R_SB_XTERM || scrollbar_above_slider (ev.y) || scrollbar_below_slider (ev.y)) - scr_move_to (scrollbar_position (ev.y) - csrO, scrollbar_size ()); + scr_move_to (scrollbar_position (ev.y) - csrO, scrollBar.size ()); scrollBar.state = STATE_MOTION; break; @@ -2045,7 +2066,7 @@ scr_page ((ev.button == Button1 ? DN : UP), (nrow * scrollbar_position (ev.y) - / scrollbar_size ())); + / scrollBar.size ())); } break; @@ -2068,7 +2089,7 @@ if (scrollBar.state == STATE_UP || scrollBar.state == STATE_DOWN) { scrollBar.state = STATE_IDLE; - scrollbar_show (0); + scrollBar.show (0); } #ifdef SELECTION_SCROLLING @@ -2128,7 +2149,7 @@ case Button2: if (IN_RANGE_EXC (ev.x, 0, width) && IN_RANGE_EXC (ev.y, 0, height)) // inside window? - selection_request (ev.time, ev.state & ModMetaMask ? Sel_Clipboard : Sel_Primary); + selection_request (ev.time, ev.state & ModMetaMask ? Sel_Clipboard : Sel_Primary); break; #ifdef MOUSE_WHEEL @@ -2161,7 +2182,7 @@ # endif { scr_page (v, i); - scrollbar_show (1); + scrollBar.show (1); } } break; @@ -2172,16 +2193,15 @@ /*}}} */ -bool +void rxvt_term::cmd_parse () { - bool flag = false; wchar_t ch = NOCHAR; char *seq_begin; // remember start of esc-sequence here for (;;) { - if (ch == NOCHAR) + if (expect_false (ch == NOCHAR)) { seq_begin = cmdbuf_ptr; ch = next_char (); @@ -2190,9 +2210,9 @@ break; } - if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT) + if (expect_true (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT)) { - if (!seen_input) + if (expect_false (!seen_input)) { seen_input = 1; // many badly-written programs (e.g. jed) contain a race condition: @@ -2215,12 +2235,12 @@ for (;;) { - if (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT)) + if (expect_false (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT))) break; *str++ = ch; - if (ch == C0_LF || str >= eol) + if (expect_false (ch == C0_LF || str >= eol)) { if (ch == C0_LF) nlines++; @@ -2279,11 +2299,9 @@ */ if (refreshnow) { - flag = true; scr_refresh (); want_refresh = 1; } - } else { @@ -2301,8 +2319,6 @@ ch = NOCHAR; } } - - return flag; } // read the next character @@ -2312,7 +2328,7 @@ while (cmdbuf_ptr < cmdbuf_endp) { // assume 7-bit to be ascii ALWAYS - if ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b) + if (expect_true ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b)) return *cmdbuf_ptr++; wchar_t wc; @@ -2326,7 +2342,10 @@ } if (len == (size_t)-1) - return (unsigned char)*cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through + { + mbstate.reset (); // reset now undefined conversion state + return (unsigned char)*cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through + } // assume wchar == unicode cmdbuf_ptr += len; @@ -2380,7 +2399,7 @@ FILE * rxvt_term::popen_printer () { - FILE *stream = popen (rs[Rs_print_pipe], "w"); + FILE *stream = popen (rs[Rs_print_pipe] ? rs[Rs_print_pipe] : PRINTPIPE, "w"); if (stream == NULL) rxvt_warn ("can't open printer pipe, not printing.\n"); @@ -2401,17 +2420,16 @@ void rxvt_term::process_print_pipe () { - int done; - FILE *fd; + FILE *fd = popen_printer (); - if ((fd = popen_printer ()) == NULL) + if (!fd) return; /* * Send all input to the printer until either ESC[4i or ESC[?4i * is received. */ - for (done = 0; !done;) + for (int done = 0; !done; ) { unsigned char buf[8]; unicode_t ch; @@ -2566,7 +2584,7 @@ tt_printf ("\033/Z"); /* I am a VT100 emulating a VT52 */ break; case '<': /* turn off VT52 mode */ - PrivMode (0, PrivMode_vt52); + set_privmode (PrivMode_vt52, 0); break; case 'F': /* use special graphics character set */ case 'G': /* use regular character set */ @@ -2630,7 +2648,7 @@ #endif case '=': case '>': - PrivMode ((ch == '='), PrivMode_aplKP); + set_privmode (PrivMode_aplKP, ch == '='); break; case C1_40: @@ -2679,21 +2697,21 @@ tt_write (ESCZ_ANSWER, sizeof (ESCZ_ANSWER) - 1); break; /* steal obsolete ESC [ c */ - /* 8.3.16: CONTROL SEQUENCE INTRODUCER */ + /* 8.3.16: CONTROL SEQUENCE INTRODUCER (CSI) */ case C1_CSI: /* ESC [ */ process_csi_seq (); break; - /* 8.3.90: OPERATING SYSTEM COMMAND */ + /* 8.3.90: OPERATING SYSTEM COMMAND (OSC) */ case C1_OSC: /* ESC ] */ process_osc_seq (); break; - /* 8.3.106: RESET TO INITIAL STATE */ + /* 8.3.106: RESET TO INITIAL STATE (RIS) */ case 'c': mbstate.reset (); scr_poweron (); - scrollbar_show (1); + scrollBar.show (1); break; /* 8.3.79: LOCKING-SHIFT TWO (see ISO2022) */ @@ -2754,9 +2772,9 @@ priv = 0; ch = cmd_getc (); - if (ch >= '<' && ch <= '?') + if ((ch >= '<' && ch <= '?') || ch == '!') { - /* '<' '=' '>' '?' */ + /* '<' '=' '>' '?' '!' */ priv = ch; ch = cmd_getc (); } @@ -2820,7 +2838,22 @@ if (ch == 'h' || ch == 'l' || ch == 'r' || ch == 's' || ch == 't') process_terminal_mode (ch, priv, nargs, arg); break; + + case '!': + if (ch == CSI_70) + { + /* DECSTR: soft terminal reset, used by our terminfo since 9.06 */ + scr_soft_reset (); + + static const int pm_h[] = { 7, 25 }; + static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1049 }; + + process_terminal_mode ('h', 0, sizeof (pm_h) / sizeof (pm_h[0]), pm_h); + process_terminal_mode ('l', 0, sizeof (pm_l) / sizeof (pm_l[0]), pm_l); + } + break; } + return; } @@ -3197,13 +3230,12 @@ void rxvt_term::process_dcs_seq () { - char *s; - unicode_t eh; - /* * Not handled yet */ - s = get_to_st (eh); + + unicode_t eh; + char *s = get_to_st (eh); if (s) free (s); @@ -3217,15 +3249,15 @@ void rxvt_term::process_osc_seq () { - unicode_t ch, eh; int arg; - ch = cmd_getc (); + unicode_t ch = cmd_getc (); for (arg = 0; isdigit (ch); ch = cmd_getc ()) arg = arg * 10 + (ch - '0'); if (ch == ';') { + unicode_t eh; char *s = get_to_st (eh); if (s) @@ -3259,7 +3291,7 @@ * XTerm escape sequences: ESC ] Ps;Pt (ST|BEL) */ void -rxvt_term::process_xterm_seq (int op, const char *str, char resp) +rxvt_term::process_xterm_seq (int op, char *str, char resp) { int color; char *buf, *name; @@ -3310,7 +3342,7 @@ } else { - char *eq = strchr (str, '='); // constness lost, but verified to be ok + char *eq = strchr (str, '='); if (eq) { @@ -3360,15 +3392,18 @@ case XTerm_Color_pointer_bg: process_color_seq (op, Color_pointer_bg, str, resp); break; -#ifndef NO_BOLD_UNDERLINE_REVERSE - case XTerm_Color_RV: - process_color_seq (op, Color_RV, str, resp); +#ifdef OPTION_HC + case XTerm_Color_HC: + process_color_seq (op, Color_HC, str, resp); + break; + case XTerm_Color_HTC: + process_color_seq (op, Color_HTC, str, resp); break; - case Rxvt_Color_BD: +#endif +#ifndef NO_BOLD_UNDERLINE_REVERSE case URxvt_Color_BD: process_color_seq (op, Color_BD, str, resp); break; - case Rxvt_Color_UL: case URxvt_Color_UL: process_color_seq (op, Color_UL, str, resp); break; @@ -3376,6 +3411,9 @@ process_color_seq (op, Color_IT, str, resp); break; #endif + case URxvt_Color_border: + process_color_seq (op, Color_border, str, resp); + break; #if ENABLE_TRANSPARENCY case URxvt_Color_tint: process_color_seq (op, Color_tint, str, resp); @@ -3400,7 +3438,7 @@ { char str[256]; - sprintf (str, "[%dx%d+%d+%d]", /* can't presume snprintf () ! */ + sprintf (str, "[%dx%d+%d+%d]", min (bgPixmap.h_scale, 32767), min (bgPixmap.v_scale, 32767), min (bgPixmap.h_align, 32767), min (bgPixmap.v_align, 32767)); process_xterm_seq (XTerm_title, str, CHAR_ST); @@ -3509,8 +3547,7 @@ #if ENABLE_PERL case URxvt_perl: - if (HOOK_INVOKE ((this, HOOK_OSC_SEQ_PERL, DT_STR, str, DT_END))) - ; // no responses yet + HOOK_INVOKE ((this, HOOK_OSC_SEQ_PERL, DT_STR, str, DT_STR_LEN, &resp, 1, DT_END)); break; #endif } @@ -3543,7 +3580,8 @@ state = (SavedModes & bit) ? 1 : 0; /* no overlapping */ else state = (mode == 't') ? ! (priv_modes & bit) : mode; - PrivMode (state, bit); + + set_privmode (bit, state); } return state; @@ -3561,29 +3599,31 @@ const int argval; const unsigned long bit; } argtopriv[] = { - { 1, PrivMode_aplCUR }, + { 1, PrivMode_aplCUR }, // DECCKM { 2, PrivMode_vt52 }, - { 3, PrivMode_132 }, - { 4, PrivMode_smoothScroll }, - { 5, PrivMode_rVideo }, - { 6, PrivMode_relOrigin }, - { 7, PrivMode_Autowrap }, - // 8, bi-directional support mode + { 3, PrivMode_132 }, // DECCOLM + { 4, PrivMode_smoothScroll }, // DECSCLM + { 5, PrivMode_rVideo }, // DECSCNM + { 6, PrivMode_relOrigin }, // DECOM + { 7, PrivMode_Autowrap }, // DECAWM + // 8, auto-repeat keys // DECARM { 9, PrivMode_MouseX10 }, - // 18, 19 printing-related - { 25, PrivMode_VisibleCursor }, + // 18 end FF to printer after print screen + // 19 Print screen prints full screen/scroll region + { 25, PrivMode_VisibleCursor }, // cnorm/cvvis/civis #ifdef scrollBar_esc { scrollBar_esc, PrivMode_scrollBar }, #endif - { 35, PrivMode_ShiftKeys }, // rxvt extension + { 35, PrivMode_ShiftKeys }, // rxvt extension + // 38, tektronix mode // DECTEK { 40, PrivMode_132OK }, // 41 xterm more fixes NYI // 45 margin bell NYI // 46 start logging { 47, PrivMode_Screen }, - { 66, PrivMode_aplKP }, + { 66, PrivMode_aplKP }, // DECPAM/DECPNM #ifndef NO_BACKSPACE_KEY - { 67, PrivMode_BackSpace }, + { 67, PrivMode_BackSpace }, // DECBKM #endif { 1000, PrivMode_MouseX11 }, { 1002, PrivMode_MouseBtnEvent }, @@ -3632,7 +3672,6 @@ break; #endif case 1048: /* alternative cursor save */ - case 1049: if (option (Opt_secondaryScreen)) if (mode == 0) scr_cursor (RESTORE); @@ -3651,14 +3690,11 @@ * parameter. Return from VT52 mode with an ESC < from * within VT52 mode */ - PrivMode (1, PrivMode_vt52); + set_privmode (PrivMode_vt52, 1); break; case 3: /* 80/132 */ if (priv_modes & PrivMode_132OK) - { - scr_poweron (); - set_widthheight (((state ? 132 : 80) * fwidth), 24 * fheight); - } + set_widthheight ((state ? 132 : 80) * fwidth, 24 * fheight); break; case 4: /* smooth scrolling */ set_option (Opt_jumpScroll, !state); @@ -3679,7 +3715,7 @@ break; #ifdef scrollBar_esc case scrollBar_esc: - if (scrollbar_mapping (state)) + if (scrollBar.map (state)) { resize_all_windows (0, 0, 0); scr_touch (true); @@ -3710,6 +3746,7 @@ } else vt_emask_mouse = NoEventMask; + vt_select_input (); break; case 1010: /* scroll to bottom on TTY output inhibit */ @@ -3720,15 +3757,23 @@ break; case 1047: /* secondary screen w/ clearing last */ if (option (Opt_secondaryScreen)) - if (current_screen != PRIMARY) + if (!state) scr_erase_screen (2); + scr_change_screen (state); break; case 1049: /* secondary screen w/ clearing first */ + if (option (Opt_secondaryScreen)) + if (state) + scr_cursor (SAVE); + scr_change_screen (state); + if (option (Opt_secondaryScreen)) - if (current_screen != PRIMARY) + if (state) scr_erase_screen (2); + else + scr_cursor (RESTORE); break; default: break;