--- rxvt-unicode/src/command.C 2008/10/10 13:23:56 1.419 +++ rxvt-unicode/src/command.C 2010/08/18 17:45:42 1.453 @@ -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); - set_privmode (PrivMode_aplKP, !numlock_state); - } - 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: @@ -765,7 +773,19 @@ { int param = map_function_key (keysym); if (param > 0) - sprintf (kbuf,"\033[%d~", param); + { + int n = sprintf (kbuf,"\033[%d~", param); + /* + * pass Shift/Control indicators for function keys ending with `~' + * + * eg, + * Prior = "ESC[5~" + * Shift+Prior = "ESC[5$" + * Ctrl+Prior = "ESC[5^" + * Ctrl+Shift+Prior = "ESC[5@" + */ + kbuf[n-1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); + } else newlen = 0; } @@ -826,18 +846,8 @@ } /* - * these modifications only affect the static keybuffer - * pass Shift/Control indicators for function keys ending with `~' - * - * eg, - * Prior = "ESC[5~" - * Shift+Prior = "ESC[5$" - * Ctrl+Prior = "ESC[5^" - * Ctrl+Shift+Prior = "ESC[5@" * Meta adds an Escape prefix (with META8_OPTION, if meta == ). */ - if (kbuf[0] == C0_ESC && kbuf[1] == '[' && kbuf[len - 1] == '~') - kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); /* escape prefix */ if (meta @@ -1026,7 +1036,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 +1139,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 +1203,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 (); @@ -1461,7 +1473,7 @@ break; case SelectionClear: - selection_clear (); + selection_clear (ev.xselectionclear.selection == xa[XA_CLIPBOARD]); break; case SelectionNotify: @@ -1475,12 +1487,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. @@ -1684,6 +1696,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 +1720,6 @@ focus = 1; want_refresh = 1; - HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); - #if USE_XIM if (Input_Context != NULL) { @@ -1714,14 +1740,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 +1755,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 +1785,8 @@ scr_recolour (); } #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); } } @@ -1847,7 +1873,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) @@ -2128,7 +2154,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 @@ -2172,10 +2198,9 @@ /*}}} */ -bool +void rxvt_term::cmd_parse () { - bool flag = false; wchar_t ch = NOCHAR; char *seq_begin; // remember start of esc-sequence here @@ -2279,11 +2304,9 @@ */ if (refreshnow) { - flag = true; scr_refresh (); want_refresh = 1; } - } else { @@ -2301,8 +2324,6 @@ ch = NOCHAR; } } - - return flag; } // read the next character @@ -2327,7 +2348,7 @@ if (len == (size_t)-1) { - mbrtowc (0, 0, 0, mbstate); // reset now undefined conversion state + mbstate.reset (); // reset now undefined conversion state return (unsigned char)*cmdbuf_ptr++; // the _occasional_ latin1 character is allowed to slip through } @@ -2681,17 +2702,17 @@ 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 (); @@ -2756,9 +2777,9 @@ priv = 0; ch = cmd_getc (); - if (ch >= '<' && ch <= '?') + if ((ch >= '<' && ch <= '?') || ch == '!') { - /* '<' '=' '>' '?' */ + /* '<' '=' '>' '?' '!' */ priv = ch; ch = cmd_getc (); } @@ -2822,7 +2843,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; } @@ -3199,13 +3235,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); @@ -3219,15 +3254,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) @@ -3261,7 +3296,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; @@ -3312,7 +3347,7 @@ } else { - char *eq = strchr (str, '='); // constness lost, but verified to be ok + char *eq = strchr (str, '='); if (eq) { @@ -3362,15 +3397,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; @@ -3378,6 +3416,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); @@ -3402,7 +3443,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); @@ -3544,6 +3585,7 @@ state = (SavedModes & bit) ? 1 : 0; /* no overlapping */ else state = (mode == 't') ? ! (priv_modes & bit) : mode; + set_privmode (bit, state); } @@ -3562,29 +3604,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/scorll 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 }, @@ -3633,7 +3677,6 @@ break; #endif case 1048: /* alternative cursor save */ - case 1049: if (option (Opt_secondaryScreen)) if (mode == 0) scr_cursor (RESTORE); @@ -3656,10 +3699,7 @@ 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); @@ -3711,6 +3751,7 @@ } else vt_emask_mouse = NoEventMask; + vt_select_input (); break; case 1010: /* scroll to bottom on TTY output inhibit */ @@ -3721,15 +3762,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;