--- rxvt-unicode/src/command.C 2008/02/01 14:13:52 1.402 +++ rxvt-unicode/src/command.C 2010/12/14 07:59:54 1.463 @@ -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) @@ -281,10 +287,10 @@ iso14755buf = 0; } -int -rxvt_term::hex_keyval (XKeyEvent &ev) +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++) { @@ -300,11 +306,105 @@ } #endif +static inline KeySym +translate_keypad (KeySym keysym, bool kp) +{ +#ifdef XK_KP_Home + static const KeySym keypadtrans[] = { + XK_KP_7, // XK_KP_Home + XK_KP_4, // XK_KP_Left + XK_KP_8, // XK_KP_Up + XK_KP_6, // XK_KP_Right + XK_KP_2, // XK_KP_Down +# ifndef UNSHIFTED_SCROLLKEYS + XK_KP_9, // XK_KP_Prior + XK_KP_3, // XK_KP_Next +# else + XK_Prior, + XK_Next, +# endif + XK_KP_1, // XK_KP_End + XK_KP_5, // XK_KP_Begin + }; + + if (IN_RANGE_INC (keysym, XK_KP_Home, XK_KP_Begin)) + { + unsigned int index = keysym - XK_KP_Home; + keysym = kp ? keypadtrans[index] : XK_Home + index; + } + else if (keysym == XK_KP_Insert) + keysym = kp ? XK_KP_0 : XK_Insert; +# ifndef NO_DELETE_KEY + else if (keysym == XK_KP_Delete) + keysym = kp ? XK_KP_Decimal : XK_Delete; +# endif +#endif + return keysym; +} + +static inline int +map_function_key (KeySym keysym) +{ + int param = 0; + + if (IN_RANGE_INC (keysym, XK_F1, XK_F35)) + { + param = 11 + keysym - XK_F1; + if (keysym >= XK_F17) + param += 4; + else if (keysym >= XK_F15) + param += 3; + else if (keysym >= XK_F11) + param += 2; + else if (keysym >= XK_F6) + param += 1; + } + else + switch (keysym) + { + case XK_Find: + param = 1; + break; + case XK_Insert: + param = 2; + break; +#ifdef DXK_Remove + case DXK_Remove: +#endif + case XK_Execute: + param = 3; + break; + case XK_Select: + param = 4; + break; +#ifndef UNSHIFTED_SCROLLKEYS + case XK_Prior: + param = 5; + break; + case XK_Next: + param = 6; + break; + case XK_Home: + param = 7; + break; + case XK_End: + param = 8; + break; +#endif + case XK_Help: + param = 28; + break; + case XK_Menu: + param = 29; + break; + } + return param; +} + void rxvt_term::key_press (XKeyEvent &ev) { int ctrl, meta, shft, len; - unsigned int newlen; KeySym keysym; int valid_keysym; char kbuf[KBUFSZ]; @@ -324,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 @@ -413,6 +507,8 @@ #else lnsppg = nrow * 4 / 5; #endif + max_it (lnsppg, 1); + if (keysym == XK_Prior) { scr_page (UP, lnsppg); @@ -487,7 +583,7 @@ #if ENABLE_FRILLS || ISO_14755 // ISO 14755 support - if (shft && ctrl) + if (iso14755buf & (ISO_14755_STARTED | ISO_14755_51)) { int hv; @@ -527,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; @@ -549,250 +646,143 @@ if (keysym >= 0xFF00 && keysym <= 0xFFFF) { - { - bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; - newlen = 1; -#ifdef XK_KP_Home - static const KeySym keypadtrans[] = { - XK_KP_7, // XK_KP_Home - XK_KP_4, // XK_KP_Left - XK_KP_8, // XK_KP_Up - XK_KP_6, // XK_KP_Right - XK_KP_2, // XK_KP_Down -#ifndef UNSHIFTED_SCROLLKEYS - XK_KP_9, // XK_KP_Prior - XK_KP_3, // XK_KP_Next -#else - XK_Prior, - XK_Next, -#endif - XK_KP_1, // XK_KP_End - XK_KP_5, // XK_KP_Begin - }; + bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; + unsigned int newlen = 1; - if (IN_RANGE_INC (keysym, XK_KP_Home, XK_KP_Begin)) - { - unsigned int index = keysym - XK_KP_Home; - keysym = kp ? keypadtrans[index] : XK_Home + index; - } - else if (keysym == XK_KP_Insert) - keysym = kp ? XK_KP_0 : XK_Insert; -#ifndef NO_DELETE_KEY - else if (keysym == XK_KP_Delete) - keysym = kp ? XK_KP_Decimal : XK_Delete; -#endif -#endif - switch (keysym) - { + if (ev.state & ModNumLockMask) + kp = false; + + keysym = translate_keypad (keysym, kp); + + switch (keysym) + { #ifndef NO_BACKSPACE_KEY - case XK_BackSpace: - if (priv_modes & PrivMode_HaveBackSpace) - { - kbuf[0] = (!! (priv_modes & PrivMode_BackSpace) - ^ !!ctrl) ? '\b' : '\177'; - kbuf[1] = '\0'; - } - else - strcpy (kbuf, rs[Rs_backspace_key]); - break; + case XK_BackSpace: + if (priv_modes & PrivMode_HaveBackSpace) + { + kbuf[0] = (!! (priv_modes & PrivMode_BackSpace) + ^ !!ctrl) ? '\b' : '\177'; + kbuf[1] = '\0'; + } + else + strcpy (kbuf, rs[Rs_backspace_key]); + break; #endif #ifndef NO_DELETE_KEY - case XK_Delete: - strcpy (kbuf, rs[Rs_delete_key]); - break; + case XK_Delete: + strcpy (kbuf, rs[Rs_delete_key]); + break; #endif - case XK_Tab: - if (shft) - strcpy (kbuf, "\033[Z"); - else - { + case XK_Tab: + if (shft) + strcpy (kbuf, "\033[Z"); + else + { #ifdef CTRL_TAB_MAKES_META - if (ctrl) - meta = 1; + if (ctrl) + meta = 1; #endif #ifdef MOD4_TAB_MAKES_META - if (ev.state & Mod4Mask) - meta = 1; + if (ev.state & Mod4Mask) + meta = 1; #endif - newlen = 0; - } - break; - - case XK_Up: /* "\033[A" */ - case XK_Down: /* "\033[B" */ - case XK_Right: /* "\033[C" */ - case XK_Left: /* "\033[D" */ - strcpy (kbuf, "\033[Z"); - kbuf[2] = "DACB"[keysym - XK_Left]; - /* do Shift first */ - if (shft) - kbuf[2] = "dacb"[keysym - XK_Left]; - else if (ctrl) - { - kbuf[1] = 'O'; - kbuf[2] = "dacb"[keysym - XK_Left]; - } - else if (priv_modes & PrivMode_aplCUR) - kbuf[1] = 'O'; - break; - -#ifndef UNSHIFTED_SCROLLKEYS - case XK_Prior: - strcpy (kbuf, "\033[5~"); - break; - case XK_Next: - strcpy (kbuf, "\033[6~"); - break; -#endif - case XK_KP_Enter: - /* allow shift to override */ - if (kp) - { - strcpy (kbuf, "\033OM"); - break; - } + newlen = 0; + } + break; - /* FALLTHROUGH */ + case XK_Up: /* "\033[A" */ + case XK_Down: /* "\033[B" */ + case XK_Right: /* "\033[C" */ + case XK_Left: /* "\033[D" */ + strcpy (kbuf, "\033[Z"); + kbuf[2] = "DACB"[keysym - XK_Left]; + /* do Shift first */ + if (shft) + kbuf[2] = "dacb"[keysym - XK_Left]; + else if (ctrl) + { + kbuf[1] = 'O'; + kbuf[2] = "dacb"[keysym - XK_Left]; + } + else if (priv_modes & PrivMode_aplCUR) + kbuf[1] = 'O'; + break; - case XK_Return: - if (priv_modes & PrivMode_LFNL) - { - kbuf[0] = '\015'; - kbuf[1] = '\012'; - kbuf[2] = '\0'; - } - else - { - kbuf[0] = '\015'; - kbuf[1] = '\0'; - } + case XK_KP_Enter: + /* allow shift to override */ + if (kp) + { + strcpy (kbuf, "\033OM"); break; + } - case XK_KP_F1: /* "\033OP" */ - case XK_KP_F2: /* "\033OQ" */ - case XK_KP_F3: /* "\033OR" */ - case XK_KP_F4: /* "\033OS" */ - strcpy (kbuf, "\033OP"); - kbuf[2] += (keysym - XK_KP_F1); - break; + /* FALLTHROUGH */ - case XK_KP_Multiply: /* "\033Oj" : "*" */ - case XK_KP_Add: /* "\033Ok" : "+" */ - case XK_KP_Separator: /* "\033Ol" : "," */ - case XK_KP_Subtract: /* "\033Om" : "-" */ - case XK_KP_Decimal: /* "\033On" : "." */ - case XK_KP_Divide: /* "\033Oo" : "/" */ - case XK_KP_0: /* "\033Op" : "0" */ - case XK_KP_1: /* "\033Oq" : "1" */ - case XK_KP_2: /* "\033Or" : "2" */ - case XK_KP_3: /* "\033Os" : "3" */ - case XK_KP_4: /* "\033Ot" : "4" */ - case XK_KP_5: /* "\033Ou" : "5" */ - case XK_KP_6: /* "\033Ov" : "6" */ - case XK_KP_7: /* "\033Ow" : "7" */ - case XK_KP_8: /* "\033Ox" : "8" */ - case XK_KP_9: /* "\033Oy" : "9" */ - /* allow shift to override */ - if (kp) - { - strcpy (kbuf, "\033Oj"); - kbuf[2] += (keysym - XK_KP_Multiply); - } - else - { - kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); - kbuf[1] = '\0'; - } - break; - - case XK_Find: - strcpy (kbuf, "\033[1~"); - break; + case XK_Return: + if (priv_modes & PrivMode_LFNL) + { + kbuf[0] = '\015'; + kbuf[1] = '\012'; + kbuf[2] = '\0'; + } + else + { + kbuf[0] = '\015'; + kbuf[1] = '\0'; + } + break; - case XK_Insert: - strcpy (kbuf, "\033[2~"); - break; -#ifdef DXK_Remove /* support for DEC remove like key */ - case DXK_Remove: - /* FALLTHROUGH */ -#endif - case XK_Execute: - strcpy (kbuf, "\033[3~"); - break; - case XK_Select: - strcpy (kbuf, "\033[4~"); - break; - case XK_End: - strcpy (kbuf, KS_END); - break; - case XK_Home: - strcpy (kbuf, KS_HOME); - break; + case XK_KP_F1: /* "\033OP" */ + case XK_KP_F2: /* "\033OQ" */ + case XK_KP_F3: /* "\033OR" */ + case XK_KP_F4: /* "\033OS" */ + strcpy (kbuf, "\033OP"); + kbuf[2] += (keysym - XK_KP_F1); + break; -#define FKEY(n, fkey) \ - sprintf ((char *)kbuf,"\033[%2d~", (int) ((n) + (keysym - fkey))) + case XK_KP_Multiply: /* "\033Oj" : "*" */ + case XK_KP_Add: /* "\033Ok" : "+" */ + case XK_KP_Separator: /* "\033Ol" : "," */ + case XK_KP_Subtract: /* "\033Om" : "-" */ + case XK_KP_Decimal: /* "\033On" : "." */ + case XK_KP_Divide: /* "\033Oo" : "/" */ + case XK_KP_0: /* "\033Op" : "0" */ + case XK_KP_1: /* "\033Oq" : "1" */ + case XK_KP_2: /* "\033Or" : "2" */ + case XK_KP_3: /* "\033Os" : "3" */ + case XK_KP_4: /* "\033Ot" : "4" */ + case XK_KP_5: /* "\033Ou" : "5" */ + case XK_KP_6: /* "\033Ov" : "6" */ + case XK_KP_7: /* "\033Ow" : "7" */ + case XK_KP_8: /* "\033Ox" : "8" */ + case XK_KP_9: /* "\033Oy" : "9" */ + /* allow shift to override */ + if (kp) + { + strcpy (kbuf, "\033Oj"); + kbuf[2] += (keysym - XK_KP_Multiply); + } + else + { + kbuf[0] = ('*' + (keysym - XK_KP_Multiply)); + kbuf[1] = '\0'; + } + break; - case XK_F1: /* "\033[11~" */ - case XK_F2: /* "\033[12~" */ - case XK_F3: /* "\033[13~" */ - case XK_F4: /* "\033[14~" */ - case XK_F5: /* "\033[15~" */ - FKEY (11, XK_F1); - break; - case XK_F6: /* "\033[17~" */ - case XK_F7: /* "\033[18~" */ - case XK_F8: /* "\033[19~" */ - case XK_F9: /* "\033[20~" */ - case XK_F10: /* "\033[21~" */ - FKEY (17, XK_F6); - break; - case XK_F11: /* "\033[23~" */ - case XK_F12: /* "\033[24~" */ - case XK_F13: /* "\033[25~" */ - case XK_F14: /* "\033[26~" */ - FKEY (23, XK_F11); - break; - case XK_F15: /* "\033[28~" */ - case XK_F16: /* "\033[29~" */ - FKEY (28, XK_F15); - break; - case XK_Help: /* "\033[28~" */ - FKEY (28, XK_Help); - break; - case XK_Menu: /* "\033[29~" */ - FKEY (29, XK_Menu); - break; - case XK_F17: /* "\033[31~" */ - case XK_F18: /* "\033[32~" */ - case XK_F19: /* "\033[33~" */ - case XK_F20: /* "\033[34~" */ - case XK_F21: /* "\033[35~" */ - case XK_F22: /* "\033[36~" */ - case XK_F23: /* "\033[37~" */ - case XK_F24: /* "\033[38~" */ - case XK_F25: /* "\033[39~" */ - case XK_F26: /* "\033[40~" */ - case XK_F27: /* "\033[41~" */ - case XK_F28: /* "\033[42~" */ - case XK_F29: /* "\033[43~" */ - case XK_F30: /* "\033[44~" */ - case XK_F31: /* "\033[45~" */ - case XK_F32: /* "\033[46~" */ - case XK_F33: /* "\033[47~" */ - case XK_F34: /* "\033[48~" */ - case XK_F35: /* "\033[49~" */ - FKEY (31, XK_F17); - break; -#undef FKEY - default: + default: + { + int param = map_function_key (keysym); + if (param > 0) + sprintf (kbuf,"\033[%d~", param); + else newlen = 0; - break; } - - if (newlen) - len = strlen (kbuf); + break; } + if (newlen) + len = strlen (kbuf); + /* * Pass meta for all function keys, if 'meta' option set */ @@ -901,7 +891,7 @@ return; } - for (unsigned short *i = iso14755_symtab; i[0]; i+= 2) + for (unsigned short *i = iso14755_symtab; i[0]; i += 2) if (i[0] == keysym) { iso14755buf = ISO_14755_51 | i[1]; @@ -987,8 +977,9 @@ flush_ev.stop (); #ifdef HAVE_BG_PIXMAP - if (bgPixmap.check_clearChanged ()) + if (bgPixmap.flags & bgPixmap_t::hasChanged) { + bgPixmap.flags &= ~bgPixmap_t::hasChanged; // scr_clear (true); This needs to be researched further! scr_touch (false); } @@ -1035,7 +1026,7 @@ } scr_refresh (); - scrollbar_show (1); + scrollBar.show (1); #ifdef USE_XIM IMSendSpot (); #endif @@ -1044,7 +1035,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 () { @@ -1147,8 +1138,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 (); @@ -1208,9 +1202,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 (); @@ -1261,12 +1254,14 @@ int x, y; int code = 32; - x = Pixel2Col (ev.x); - y = Pixel2Row (ev.y); + x = Pixel2Col (ev.x) + 1; + y = Pixel2Row (ev.y) + 1; + if (ev.type == MotionNotify) { if (x == mouse_row && y == mouse_col) return; + mouse_row = x; mouse_col = y; code += 32; @@ -1279,7 +1274,7 @@ button_number = MEvent.button - Button1; /* add 0x3D for wheel events, like xterm does */ if (button_number >= 3) - button_number += (64 - 3); + button_number += 64 - 3; } if (priv_modes & PrivMode_MouseX10) @@ -1321,14 +1316,27 @@ fputc ('2', stderr); fprintf (stderr, "]: <%d>, %d/%d\n", button_number, - x + 1, - y + 1); + x, + y); #endif - tt_printf ("\033[M%c%c%c", - (code + button_number + key_state), - (32 + x + 1), - (32 + y + 1)); +#if ENABLE_FRILLS + if (priv_modes & PrivMode_ExtMouseRight) + tt_printf ("\033[%d;%d;%dM", + code + button_number + key_state, + x, + y); + else if (priv_modes & PrivMode_ExtModeMouse) + tt_printf ("\033[M%c%lc%lc", + code + button_number + key_state, + wint_t (32 + x), + wint_t (32 + y)); + else +#endif + tt_printf ("\033[M%c%c%c", + code + button_number + key_state, + 32 + x, + 32 + y); } /*{{{ process an X event */ @@ -1440,14 +1448,30 @@ 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)) ; +#ifdef HAVE_BG_PIXMAP + bool moved = false; + if (bgPixmap.window_position_sensitive ()) + { + int x, y; + if (ev.xconfigure.send_event) + { + x = ev.xconfigure.x; + y = ev.xconfigure.y; + } + else + get_window_origin (x, y); + + if (bgPixmap.set_position (x, y) + || (bgPixmap.flags & bgPixmap_t::isInvalid)) + moved = true; + } +#endif + if (szHint.width != ev.xconfigure.width || szHint.height != ev.xconfigure.height) { seen_resize = 1; @@ -1456,7 +1480,7 @@ else { #ifdef HAVE_BG_PIXMAP - if (bgPixmap.window_position_sensitive ()) + if (moved) { if (mapped) update_background (); @@ -1479,7 +1503,7 @@ break; case SelectionClear: - selection_clear (); + selection_clear (ev.xselectionclear.selection == xa[XA_CLIPBOARD]); break; case SelectionNotify: @@ -1493,12 +1517,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. @@ -1556,7 +1580,7 @@ if (scrollBar.state && ev.xany.window == scrollBar.win) { scrollBar.state = STATE_IDLE; - scrollbar_show (0); + scrollBar.show (0); } } break; @@ -1665,9 +1689,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; } @@ -1702,6 +1726,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 () { @@ -1710,8 +1750,6 @@ focus = 1; want_refresh = 1; - HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); - #if USE_XIM if (Input_Context != NULL) { @@ -1732,14 +1770,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)); } } @@ -1751,8 +1785,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) { @@ -1779,6 +1815,8 @@ scr_recolour (); } #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); } } @@ -1865,7 +1903,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) @@ -1949,12 +1987,12 @@ */ if (scrollBar.state && ev.window == scrollBar.win) { - int upordown = 0; + page_dirn direction = NO_DIR; if (scrollBar.upButton (ev.y)) - upordown = -1; /* up */ + direction = UP; /* up */ else if (scrollBar.dnButton (ev.y)) - upordown = 1; /* down */ + direction = DN; /* down */ scrollBar.state = STATE_IDLE; /* @@ -1975,9 +2013,9 @@ * arrow buttons - send up/down * click on scrollbar - send pageup/down */ - if (upordown < 0) + if (direction == UP) tt_printf ("\033[A"); - else if (upordown > 0) + else if (direction == DN) tt_printf ("\033[B"); else switch (ev.button) @@ -1995,17 +2033,16 @@ } else #endif /* NO_SCROLLBAR_REPORT */ - { - if (upordown) + if (direction != NO_DIR) { #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING if (!cont_scroll_ev.is_active ()) cont_scroll_ev.start (SCROLLBAR_INITIAL_DELAY, SCROLLBAR_CONTINUOUS_DELAY); #endif - if (scr_page (upordown < 0 ? UP : DN, 1)) + if (scr_page (direction, 1)) { - if (upordown < 0) + if (direction == UP) scrollBar.state = STATE_UP; else scrollBar.state = STATE_DOWN; @@ -2031,7 +2068,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; @@ -2064,7 +2101,7 @@ scr_page ((ev.button == Button1 ? DN : UP), (nrow * scrollbar_position (ev.y) - / scrollbar_size ())); + / scrollBar.size ())); } break; @@ -2087,7 +2124,7 @@ if (scrollBar.state == STATE_UP || scrollBar.state == STATE_DOWN) { scrollBar.state = STATE_IDLE; - scrollbar_show (0); + scrollBar.show (0); } #ifdef SELECTION_SCROLLING @@ -2147,7 +2184,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 @@ -2180,7 +2217,7 @@ # endif { scr_page (v, i); - scrollbar_show (1); + scrollBar.show (1); } } break; @@ -2191,16 +2228,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 (); @@ -2209,9 +2245,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: @@ -2234,12 +2270,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++; @@ -2298,11 +2334,9 @@ */ if (refreshnow) { - flag = true; scr_refresh (); want_refresh = 1; } - } else { @@ -2320,8 +2354,6 @@ ch = NOCHAR; } } - - return flag; } // read the next character @@ -2331,7 +2363,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; @@ -2345,7 +2377,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; @@ -2399,7 +2434,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"); @@ -2420,17 +2455,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; @@ -2585,7 +2619,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 */ @@ -2649,7 +2683,7 @@ #endif case '=': case '>': - PrivMode ((ch == '='), PrivMode_aplKP); + set_privmode (PrivMode_aplKP, ch == '='); break; case C1_40: @@ -2698,21 +2732,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) */ @@ -2773,9 +2807,9 @@ priv = 0; ch = cmd_getc (); - if (ch >= '<' && ch <= '?') + if ((ch >= '<' && ch <= '?') || ch == '!') { - /* '<' '=' '>' '?' */ + /* '<' '=' '>' '?' '!' */ priv = ch; ch = cmd_getc (); } @@ -2839,7 +2873,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, 1005, 1015, 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; } @@ -3216,13 +3265,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); @@ -3236,15 +3284,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) @@ -3278,7 +3326,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; @@ -3329,7 +3377,7 @@ } else { - char *eq = strchr (str, '='); // constness lost, but verified to be ok + char *eq = strchr (str, '='); if (eq) { @@ -3379,15 +3427,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 Rxvt_Color_BD: + case XTerm_Color_HTC: + process_color_seq (op, Color_HTC, str, resp); + break; +#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; @@ -3395,6 +3446,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); @@ -3419,7 +3473,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); @@ -3430,25 +3484,33 @@ if (*str != ';') { - /* reset to default scaling :*/ - bgPixmap.unset_geometry (); if (bgPixmap.set_file (str)) /* change pixmap */ - changed++; - str = strchr (str, ';'); - if (str == NULL) - bgPixmap.set_defaultGeometry (); + { + changed++; + str = strchr (str, ';'); + if (str == NULL) + bgPixmap.set_defaultGeometry (); + else + bgPixmap.set_geometry (str+1); + } } - - while (str) + else { str++; - if (bgPixmap.set_geometry (str)) + if (bgPixmap.set_geometry (str, true)) changed++; - str = strchr (str, ';'); } if (changed) - update_background (); + { + if (bgPixmap.window_position_sensitive ()) + { + int x, y; + get_window_origin (x, y); + bgPixmap.set_position (x, y); + } + update_background (); + } } break; #endif @@ -3528,8 +3590,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 } @@ -3562,7 +3623,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; @@ -3580,40 +3642,48 @@ 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 }, { 1003, PrivMode_MouseAnyEvent }, +#if ENABLE_FRILLS + { 1005, PrivMode_ExtModeMouse }, +#endif { 1010, PrivMode_TtyOutputInh }, // rxvt extension { 1011, PrivMode_Keypress }, // rxvt extension +#if ENABLE_FRILLS + { 1015, PrivMode_ExtMouseRight }, // urxvt extension of 1005 +#endif // 1035 enable modifiers for alt, numlock NYI // 1036 send ESC for meta keys NYI // 1037 send DEL for keypad delete NYI { 1047, PrivMode_Screen }, - // 1048 save and restore cursor + // 1048 save and restore cursor, implemented in code { 1049, PrivMode_Screen }, /* xterm extension, clear screen on ti rather than te */ // 1051, 1052, 1060, 1061 keyboard emulation NYI { 2004, PrivMode_BracketPaste }, @@ -3651,7 +3721,6 @@ break; #endif case 1048: /* alternative cursor save */ - case 1049: if (option (Opt_secondaryScreen)) if (mode == 0) scr_cursor (RESTORE); @@ -3670,14 +3739,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); @@ -3698,7 +3764,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); @@ -3725,10 +3791,12 @@ { priv_modes &= ~(PrivMode_MouseX10|PrivMode_MouseX11); priv_modes &= arg[i] == 1003 ? ~PrivMode_MouseBtnEvent : ~PrivMode_MouseAnyEvent; + mouse_row = mouse_col = 0; vt_emask_mouse = PointerMotionMask; } else vt_emask_mouse = NoEventMask; + vt_select_input (); break; case 1010: /* scroll to bottom on TTY output inhibit */ @@ -3739,15 +3807,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;