--- rxvt-unicode/src/command.C 2007/06/08 20:04:12 1.324 +++ rxvt-unicode/src/command.C 2012/06/10 13:07:56 1.520 @@ -27,7 +27,8 @@ * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * Copyright (c) 2003 Rob McMullen - * Copyright (c) 2003-2006 Marc Lehmann + * Copyright (c) 2003-2011 Marc Lehmann + * Copyright (c) 2007 Emanuele Giaquinta * * 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 @@ -55,10 +56,10 @@ # include "keyboard.h" #endif -#include +#include #if LINUX_YIELD_HACK -# include +# include #endif /*----------------------------------------------------------------------*/ @@ -97,7 +98,6 @@ XK_Shift_Lock, 0x21eb, XK_ISO_Lock, 0x21eb, - XK_ISO_Lock, 0x21eb, XK_Caps_Lock, 0x21ec, XK_Num_Lock, 0x21ed, XK_ISO_Level3_Shift, 0x21ee, @@ -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,16 +160,13 @@ } } -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); - 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)) { @@ -187,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", @@ -199,9 +199,15 @@ 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 + hey max_it (width, strlen (attr)); if (y >= 0) @@ -210,7 +216,9 @@ x = 0; } - scr_overlay_new (x, y, width, len + 2); + scr_overlay_new (x, y, width, len * 2 + 2); + + scr_overlay_set (0, 0, rowcol); r = SET_STYLE (OVERLAY_RSTYLE, GET_STYLE (r)); @@ -221,16 +229,16 @@ ch = *chr++; sprintf (buf, "%8x", ch); - scr_overlay_set (0, y, buf); - scr_overlay_set (9, y, '='); -# if !UNICODE3 + 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); } // { @@ -238,10 +246,12 @@ // 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, fname); - - free (fname); + scr_overlay_set (0, len + 1, attr); + for (int i = 0; i < len; i++) + { + scr_overlay_set (0, len + 2 + i, fname[i]); + free (fname[i]); + } # if ENABLE_COMBINING if (alloc) @@ -250,25 +260,22 @@ } #endif -void +void ecb_cold rxvt_term::commit_iso14755 () { - wchar_t ch[2]; - - ch[0] = iso14755buf & ISO_14755_MASK; - ch[1] = 0; + wchar_t ch = iso14755buf & ISO_14755_MASK; if (iso14755buf & ISO_14755_51) { - char mb[16]; + char mb[MB_LEN_MAX]; int len; // allow verbatim 0-bytes and control-bytes to be entered - if (ch[0] >= 0x20) - len = wcstombs (mb, ch, 16); + if (ch >= 0x20) + len = wctomb (mb, ch); else { - mb[0] = ch[0]; + mb[0] = ch; len = 1; } @@ -281,10 +288,10 @@ iso14755buf = 0; } -int -rxvt_term::hex_keyval (XKeyEvent &ev) +static int ecb_cold +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 +307,105 @@ } #endif -void +static inline KeySym ecb_cold +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 ecb_cold +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 ecb_cold rxvt_term::key_press (XKeyEvent &ev) { int ctrl, meta, shft, len; - unsigned int newlen; KeySym keysym; int valid_keysym; char kbuf[KBUFSZ]; @@ -324,15 +425,9 @@ 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 +#if USE_XIM if (Input_Context) { Status status_return; @@ -413,6 +508,8 @@ #else lnsppg = nrow * 4 / 5; #endif + max_it (lnsppg, 1); + if (keysym == XK_Prior) { scr_page (UP, lnsppg); @@ -475,10 +572,8 @@ #if TODO /* rxvt extras */ case XK_KP_Add: /* Shift+KP_Add = bigger font */ - change_font (FONT_UP); return; case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */ - change_font (FONT_DN); return; #endif } @@ -487,7 +582,7 @@ #if ENABLE_FRILLS || ISO_14755 // ISO 14755 support - if (shft && ctrl) + if (iso14755buf & (ISO_14755_STARTED | ISO_14755_51)) { int hv; @@ -521,24 +616,25 @@ } else { -# if ENABLE_OVERLAY +# if ISO_14755 scr_overlay_off (); # endif 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; -# if ENABLE_OVERLAY +# 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) { @@ -549,308 +645,165 @@ if (keysym >= 0xFF00 && keysym <= 0xFFFF) { + bool kp = priv_modes & PrivMode_aplKP ? !shft : shft; + unsigned int newlen = 1; + + if (ev.state & ModNumLockMask) + kp = false; + + keysym = translate_keypad (keysym, kp); + + switch (keysym) { - newlen = 1; - 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, key_backspace); - 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 -# ifdef XK_KP_Prior - case XK_KP_Delete: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033On"); - break; - } - /* FALLTHROUGH */ -# endif - case XK_Delete: - strcpy (kbuf, key_delete); - 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; - -#ifdef XK_KP_Left - case XK_KP_Up: /* \033Ox or standard */ - case XK_KP_Down: /* \033Or or standard */ - case XK_KP_Right: /* \033Ov or standard */ - case XK_KP_Left: /* \033Ot or standard */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033OZ"); - kbuf[2] = "txvr"[keysym - XK_KP_Left]; - break; - } - else - /* translate to std. cursor key */ - keysym = XK_Left + (keysym - XK_KP_Left); - /* FALLTHROUGH */ -#endif - 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 -# ifdef XK_KP_Prior - case XK_KP_Prior: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033Oy"); - break; - } - /* FALLTHROUGH */ -# endif - case XK_Prior: - strcpy (kbuf, "\033[5~"); - break; -# ifdef XK_KP_Next - case XK_KP_Next: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033Os"); - break; - } - /* FALLTHROUGH */ -# endif - case XK_Next: - strcpy (kbuf, "\033[6~"); - break; -#endif - case XK_KP_Enter: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033OM"); - break; - } - - /* FALLTHROUGH */ + newlen = 0; + } + 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_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; -#ifdef XK_KP_Begin - case XK_KP_Begin: - strcpy (kbuf, "\033Ou"); + case XK_KP_Enter: + /* allow shift to override */ + if (kp) + { + strcpy (kbuf, "\033OM"); break; + } -#endif - 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 ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - 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; -#ifdef XK_KP_End - case XK_KP_Insert: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033Op"); - break; - } - /* FALLTHROUGH */ -#endif - 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; -#ifdef XK_KP_End - case XK_KP_End: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033Oq"); - break; - } - /* FALLTHROUGH */ -#endif - case XK_End: - strcpy (kbuf, KS_END); - break; -#ifdef XK_KP_Home - case XK_KP_Home: - /* allow shift to override */ - if ((priv_modes & PrivMode_aplKP) ? !shft : shft) - { - strcpy (kbuf, "\033Ow"); - break; - } - /* FALLTHROUGH */ -#endif - 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; } - /* - * Pass meta for all function keys, if 'meta' option set - */ + if (newlen) + len = strlen (kbuf); + + if (len > 0) + { + /* + * 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@" + */ + if (kbuf[0] == C0_ESC && kbuf[1] == '[' && kbuf[len - 1] == '~') + kbuf[len - 1] = (shft ? (ctrl ? '@' : '$') : (ctrl ? '^' : '~')); + + /* + * Pass meta for all function keys, if 'meta' option set + */ #ifdef META8_OPTION - if (meta && (meta_char == 0x80) && len > 0) - kbuf[len - 1] |= 0x80; + if (meta && (meta_char == 0x80)) + kbuf[len - 1] |= 0x80; #endif + } } else if (ctrl && keysym == XK_minus) @@ -894,20 +847,6 @@ want_refresh = 1; } - /* - * 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 #ifdef META8_OPTION @@ -922,7 +861,7 @@ 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 @@ -936,7 +875,7 @@ if (iso14755buf) if (iso14755buf & ISO_14755_52) { -# if ENABLE_OVERLAY +# if ISO_14755 scr_overlay_off (); # endif # if ISO_14755 @@ -952,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]; @@ -969,13 +908,13 @@ } else if ((ev.state & (ShiftMask | ControlMask)) != (ShiftMask | ControlMask)) { -# if ENABLE_OVERLAY +# if ISO_14755 scr_overlay_off (); # endif if (iso14755buf & ISO_14755_51) commit_iso14755 (); #if ISO_14755 - else if (iso14755buf & ISO_14755_STARTED) + else if (option (Opt_iso14755_52) && iso14755buf & ISO_14755_STARTED) { iso14755buf = ISO_14755_52; // iso14755 part 5.2: remember empty begin/end pair @@ -999,49 +938,15 @@ #endif } -#if defined (KEYSYM_RESOURCE) -unsigned int -rxvt_term::cmd_write (const char *str, unsigned int count) -{ - unsigned int n, s; - - n = cmdbuf_ptr - cmdbuf_base; - s = cmdbuf_base + CBUFSIZ - 1 - cmdbuf_endp; - - if (n > 0 && s < count) - { - memmove (cmdbuf_base, cmdbuf_ptr, - (unsigned int) (cmdbuf_endp - cmdbuf_ptr)); - cmdbuf_ptr = cmdbuf_base; - cmdbuf_endp -= n; - s += n; - } - - if (count > s) - { - rxvt_warn ("data loss: cmd_write too large, continuing.\n"); - count = s; - } - - for (; count--;) - *cmdbuf_endp++ = *str++; - - cmd_parse (); - - return 0; -} -#endif - void rxvt_term::flush () { flush_ev.stop (); -#ifdef TRANSPARENT - if (want_full_refresh) +#ifdef HAVE_BG_PIXMAP + if (bg_flags & BG_NEEDS_REFRESH) { - want_full_refresh = 0; - scr_clear (); + bg_flags &= ~BG_NEEDS_REFRESH; scr_touch (false); } #endif @@ -1087,99 +992,118 @@ } scr_refresh (); - scrollbar_show (1); -#ifdef USE_XIM - IMSendSpot (); + scrollBar.show (1); +#if USE_XIM + im_send_spot (); #endif } display->flush (); } +/* checks whether a refresh is requested and starts the refresh timer */ void -rxvt_term::check_cb (check_watcher &w) +rxvt_term::refresh_check () { - make_current (); + if (want_refresh && !flush_ev.is_active ()) + flush_ev.start (1. / 60.); // refresh at max. 60 Hz normally display->flush (); - - if (want_refresh && !flush_ev.active) - flush_ev.start (NOW + 1. / 60.); // refresh at max. 60 hz normally } void -rxvt_term::flush_cb (time_watcher &w) +rxvt_term::flush_cb (ev::timer &w, int revents) { make_current (); - refresh_limit = 1; refresh_count = 0; flush (); } #ifdef CURSOR_BLINK void -rxvt_term::cursor_blink_cb (time_watcher &w) +rxvt_term::cursor_blink_reset () +{ + if (hidden_cursor) + { + hidden_cursor = 0; + want_refresh = 1; + } + + if (option (Opt_cursorBlink)) + cursor_blink_ev.again (); + else + cursor_blink_ev.stop (); +} + +void +rxvt_term::cursor_blink_cb (ev::timer &w, int revents) { hidden_cursor = !hidden_cursor; want_refresh = 1; - - w.start (w.at + CURSOR_BLINK_INTERVAL); + refresh_check (); } #endif #ifdef TEXT_BLINK void -rxvt_term::text_blink_cb (time_watcher &w) +rxvt_term::text_blink_cb (ev::timer &w, int revents) { if (scr_refresh_rend (RS_Blink, RS_Blink)) { hidden_text = !hidden_text; want_refresh = 1; - w.start (w.at + TEXT_BLINK_INTERVAL); + refresh_check (); } + else + w.stop (); } #endif #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING void -rxvt_term::cont_scroll_cb (time_watcher &w) +rxvt_term::cont_scroll_cb (ev::timer &w, int revents) { - if ((scrollbar_isUp() || scrollbar_isDn()) && - scr_page (scrollbar_isUp() ? UP : DN, 1)) + if ((scrollBar.state == SB_STATE_UP || scrollBar.state == SB_STATE_DOWN) + && scr_page (scrollBar.state == SB_STATE_UP ? UP : DN, 1)) { want_refresh = 1; - w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY); + refresh_check (); } + else + w.stop (); } #endif #ifdef SELECTION_SCROLLING void -rxvt_term::sel_scroll_cb (time_watcher &w) +rxvt_term::sel_scroll_cb (ev::timer &w, int revents) { if (scr_page (scroll_selection_dir, scroll_selection_lines)) { selection_extend (selection_save_x, selection_save_y, selection_save_state); want_refresh = 1; - w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY); + refresh_check (); } + else + w.stop (); } #endif #if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING) void -rxvt_term::slip_wheel_cb (time_watcher &w) +rxvt_term::slip_wheel_cb (ev::timer &w, int revents) { - if (mouse_slip_wheel_speed == 0 - || mouse_slip_wheel_speed < 0 ? scr_page (DN, -mouse_slip_wheel_speed) - : scr_page (UP, mouse_slip_wheel_speed)) + if (scr_changeview (view_start - mouse_slip_wheel_speed)) { - if (view_start == top_row || view_start == 0) - mouse_slip_wheel_speed = 0; - want_refresh = 1; - w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY); + refresh_check (); + } + + if (view_start == top_row || view_start == 0 || mouse_slip_wheel_speed == 0) + { + mouse_slip_wheel_speed = 0; + w.stop (); } } #endif @@ -1187,16 +1111,19 @@ #if LINUX_YIELD_HACK static struct event_handler { - check_watcher yield_ev; - - void yield_cb (check_watcher &w) + ev::prepare yield_ev; + + void yield_cb (ev::prepare &w, int revents) { // this should really be sched_yield(), but the linux guys thought // 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 (); @@ -1209,22 +1136,55 @@ } event_handler; #endif +/* make sure all the cmd data is at beginning of cmdbuf */ +void +rxvt_term::cmdbuf_reify () +{ + if (cmdbuf_ptr == cmdbuf_base) + return; + + ssize_t used = cmdbuf_endp - cmdbuf_ptr; + + memmove (cmdbuf_base, cmdbuf_ptr, used); + cmdbuf_ptr = cmdbuf_base; + cmdbuf_endp = cmdbuf_ptr + used; + +} + +#if defined (KEYSYM_RESOURCE) +void +rxvt_term::cmdbuf_append (const char *str, size_t count) +{ + cmdbuf_reify (); + + size_t avail = cmdbuf_base + CBUFSIZ - cmdbuf_endp; + + if (count > avail) + return; + + memcpy (cmdbuf_endp, str, count); + cmdbuf_endp += count; + + cmd_parse (); +} +#endif + bool rxvt_term::pty_fill () { - ssize_t n = cmdbuf_endp - cmdbuf_ptr; + cmdbuf_reify (); - if (CBUFSIZ == n) + size_t avail = cmdbuf_base + CBUFSIZ - cmdbuf_endp; + + if (!avail) { - rxvt_warn ("PLEASE REPORT: pty_fill on full buffer, draining input, continuing.\n"); - n = 0; + // normally this indicates a "too long" command sequence - just drop the data we have + cmdbuf_ptr = cmdbuf_base; + cmdbuf_endp = cmdbuf_ptr; + avail = CBUFSIZ; } - memmove (cmdbuf_base, cmdbuf_ptr, n); - cmdbuf_ptr = cmdbuf_base; - cmdbuf_endp = cmdbuf_ptr + n; - - ssize_t r = read (pty->pty, cmdbuf_endp, CBUFSIZ - n); + ssize_t r = read (pty->pty, cmdbuf_endp, avail); if (r > 0) { @@ -1245,26 +1205,27 @@ if (!option (Opt_hold)) destroy (); } - + return false; } void -rxvt_term::pty_cb (io_watcher &w, short revents) +rxvt_term::pty_cb (ev::io &w, int revents) { make_current (); - if (revents & EVENT_READ) + 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 & EVENT_WRITE) + if (revents & ev::WRITE) pty_write (); + + refresh_check (); } -void +void ecb_cold rxvt_term::pointer_unblank () { XDefineCursor (dpy, vt, TermWin_cursor); @@ -1274,12 +1235,12 @@ hidden_pointer = 0; if (option (Opt_pointerBlank)) - pointer_ev.start (NOW + pointerBlankDelay); + pointer_ev.start (pointerBlankDelay); #endif } #ifdef POINTER_BLANK -void +void ecb_cold rxvt_term::pointer_blank () { if (!option (Opt_pointerBlank)) @@ -1291,8 +1252,8 @@ hidden_pointer = 1; } -void -rxvt_term::pointer_cb (time_watcher &w) +void ecb_cold +rxvt_term::pointer_cb (ev::timer &w, int revents) { make_current (); @@ -1305,10 +1266,20 @@ { int button_number, key_state = 0; int x, y; + int code = 32; + + x = Pixel2Col (ev.x) + 1; + y = Pixel2Row (ev.y) + 1; - x = ev.x; - y = ev.y; - pixel_position (&x, &y); + if (ev.type == MotionNotify) + { + if (x == mouse_row && y == mouse_col) + return; + + mouse_row = x; + mouse_col = y; + code += 32; + } if (MEvent.button == AnyButton) button_number = 3; @@ -1317,7 +1288,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) @@ -1359,18 +1330,31 @@ 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", - (32 + 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 */ -void +void ecb_hot rxvt_term::x_cb (XEvent &ev) { make_current (); @@ -1438,10 +1422,6 @@ } break; - case MappingNotify: - XRefreshKeyboardMapping (&ev.xmapping); - break; - /* * XXX: this is not the _current_ arrangement * Here's my conclusion: @@ -1482,48 +1462,67 @@ break; case ConfigureNotify: - if (ev.xconfigure.window == parent[0]) + if (ev.xconfigure.window == parent) { while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev)) ; + bool want_position_change = SHOULD_INVOKE (HOOK_POSITION_CHANGE); + +#ifdef HAVE_BG_PIXMAP + if (bg_window_position_sensitive ()) + want_position_change = true; +#endif + + bool moved = false; + + if (want_position_change) + { + int x, y; + + if (ev.xconfigure.send_event) + { + x = ev.xconfigure.x; + y = ev.xconfigure.y; + } + else + get_window_origin (x, y); + + 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)); + } + + if (bg_set_position (x, y) + || !(bg_flags & BG_IS_VALID)) + moved = true; + } + if (szHint.width != ev.xconfigure.width || szHint.height != ev.xconfigure.height) { seen_resize = 1; resize_all_windows (ev.xconfigure.width, ev.xconfigure.height, 1); -#ifdef XPM_BACKGROUND - if (!option(Opt_transparent) && bgPixmap.auto_resize) - { - resize_pixmap (); - scr_touch (true); - } + } + else + { +#ifdef HAVE_BG_PIXMAP + if (moved) + update_background (); #endif } HOOK_INVOKE ((this, HOOK_CONFIGURE_NOTIFY, DT_XEVENT, &ev, DT_END)); - -#ifdef TRANSPARENT - if (option (Opt_transparent)) - check_our_parents (); -#endif } break; case PropertyNotify: - if (!HOOK_INVOKE ((this, HOOK_PROPERTY_NOTIFY, DT_XEVENT, &ev, DT_END))) - if (ev.xproperty.atom == xa[XA_VT_SELECTION] - && ev.xproperty.state == PropertyNewValue) - selection_property (ev.xproperty.window, ev.xproperty.atom); - + HOOK_INVOKE ((this, HOOK_PROPERTY_NOTIFY, DT_XEVENT, &ev, DT_END)); break; case SelectionClear: - selection_clear (); - break; - - case SelectionNotify: - if (selection_wait == Sel_normal) - selection_paste (ev.xselection.requestor, ev.xselection.property, true); + selection_clear (ev.xselectionclear.selection == xa[XA_CLIPBOARD]); break; case SelectionRequest: @@ -1531,9 +1530,25 @@ break; 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)) + update_background_ev.start (0.025); +#endif mapped = 1; #ifdef TEXT_BLINK - text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL); + text_blink_ev.start (); #endif HOOK_INVOKE ((this, HOOK_MAP_NOTIFY, DT_XEVENT, &ev, DT_END)); break; @@ -1546,26 +1561,24 @@ HOOK_INVOKE ((this, HOOK_UNMAP_NOTIFY, DT_XEVENT, &ev, DT_END)); break; -#ifdef TRANSPARENT - case ReparentNotify: - rootwin_cb (ev); - break; -#endif /* TRANSPARENT */ - case GraphicsExpose: case Expose: if (ev.xany.window == vt) { do - scr_expose (ev.xexpose.x, ev.xexpose.y, - ev.xexpose.width, ev.xexpose.height, False); + { + scr_expose (ev.xexpose.x, ev.xexpose.y, + ev.xexpose.width, ev.xexpose.height, false); + } while (XCheckTypedWindowEvent (dpy, vt, ev.xany.type, &ev)); ev.xany.type = ev.xany.type == Expose ? GraphicsExpose : Expose; while (XCheckTypedWindowEvent (dpy, vt, ev.xany.type, &ev)) - scr_expose (ev.xexpose.x, ev.xexpose.y, - ev.xexpose.width, ev.xexpose.height, False); + { + scr_expose (ev.xexpose.x, ev.xexpose.y, + ev.xexpose.width, ev.xexpose.height, false); + } want_refresh = 1; } @@ -1578,16 +1591,11 @@ while (XCheckTypedWindowEvent (dpy, ev.xany.window, GraphicsExpose, &unused_event)) ; - if (isScrollbarWindow (ev.xany.window)) + if (scrollBar.state && ev.xany.window == scrollBar.win) { - scrollBar.setIdle (); - scrollbar_show (0); + scrollBar.state = SB_STATE_IDLE; + scrollBar.show (0); } - -#ifdef TRANSPARENT - if (am_transparent && ev.xany.window == parent[0]) - XClearWindow (dpy, ev.xany.window); -#endif } break; @@ -1596,6 +1604,9 @@ if (hidden_pointer) pointer_unblank (); #endif + if ((priv_modes & PrivMode_MouseBtnEvent && ev.xbutton.state & (Button1Mask|Button2Mask|Button3Mask)) + || priv_modes & PrivMode_MouseAnyEvent) + mouse_report (ev.xbutton); if ((priv_modes & PrivMode_mouse_report) && !bypass_keystate) break; @@ -1639,8 +1650,8 @@ /* don't clobber the current delay if we are * already in the middle of scrolling. */ - if (!sel_scroll_ev.active) - sel_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY); + if (!sel_scroll_ev.is_active ()) + sel_scroll_ev.start (SCROLLBAR_INITIAL_DELAY, SCROLLBAR_CONTINUOUS_DELAY); /* save the event params so we can highlight * the selection in the pending-scroll loop @@ -1658,7 +1669,7 @@ else { scroll_selection_dir = DN; - dist = ev.xbutton.y - (int_bwidth + height); + dist = ev.xbutton.y - (int_bwidth + vt_height); } scroll_selection_lines = Pixel2Height (dist) @@ -1672,8 +1683,7 @@ /* we are within the text window, so we * shouldn't be scrolling */ - if (sel_scroll_ev.active) - sel_scroll_ev.stop(); + sel_scroll_ev.stop(); } #endif #ifdef MOUSE_THRESHOLD @@ -1681,7 +1691,7 @@ #endif } } - else if (isScrollbarWindow (ev.xany.window) && scrollbar_isMotion ()) + else if (scrollBar.state == SB_STATE_MOTION && ev.xany.window == scrollBar.win) { while (XCheckTypedWindowEvent (dpy, scrollBar.win, MotionNotify, &ev)) @@ -1692,26 +1702,17 @@ &unused_root_x, &unused_root_y, &ev.xbutton.x, &ev.xbutton.y, &unused_mask); - scr_move_to (scrollbar_position (ev.xbutton.y) - csrO, - scrollbar_size ()); + scr_move_to (scrollBar.position (ev.xbutton.y) - csrO, + scrollBar.size ()); want_refresh = 1; - refresh_limit = 0; - scrollbar_show (1); + scrollBar.show (1); } break; } #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 + CURSOR_BLINK_INTERVAL); - } + if (ev.type == KeyPress) + cursor_blink_reset (); #endif #if defined(POINTER_BLANK) @@ -1727,9 +1728,28 @@ pointer_blank (); } #endif + + refresh_check (); } -void +#if ENABLE_FRILLS +void ecb_cold +rxvt_term::set_urgency (bool enable) +{ + if (enable == urgency_hint) + return; + + if (XWMHints *h = XGetWMHints (dpy, parent)) + { + h->flags = h->flags & ~XUrgencyHint | (enable ? XUrgencyHint : 0); + XSetWMHints (dpy, parent, h); + urgency_hint = enable; + XFree (h); + } +} +#endif + +void ecb_cold rxvt_term::focus_in () { if (!focus) @@ -1737,18 +1757,16 @@ focus = 1; want_refresh = 1; - HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); - #if USE_XIM if (Input_Context != NULL) { - IMSetPosition (); + im_set_position (); XSetICFocus (Input_Context); } #endif #if CURSOR_BLINK if (option (Opt_cursorBlink)) - cursor_blink_ev.start (NOW + CURSOR_BLINK_INTERVAL); + cursor_blink_ev.again (); #endif #if OFF_FOCUS_FADING if (rs[Rs_fade]) @@ -1759,21 +1777,14 @@ #endif #if ENABLE_FRILLS if (option (Opt_urgentOnBell)) - { - XWMHints *h; - - h = XGetWMHints(dpy, parent[0]); - if (h != NULL) - { - h->flags &= ~XUrgencyHint; - XSetWMHints(dpy, parent[0], h); - } - } + set_urgency (0); #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_IN, DT_END)); } } -void +void ecb_cold rxvt_term::focus_out () { if (focus) @@ -1781,13 +1792,15 @@ 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) { iso14755buf = 0; -# if ENABLE_OVERLAY +# if ISO_14755 scr_overlay_off (); # endif } @@ -1799,6 +1812,7 @@ #if CURSOR_BLINK if (option (Opt_cursorBlink)) cursor_blink_ev.stop (); + hidden_cursor = 0; #endif #if OFF_FOCUS_FADING @@ -1808,10 +1822,12 @@ scr_recolour (); } #endif + + HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END)); } } -void +void ecb_cold rxvt_term::update_fade_color (unsigned int idx) { #if OFF_FOCUS_FADING @@ -1824,8 +1840,8 @@ #endif } -#if TRANSPARENT || ENABLE_PERL -void +#if ENABLE_TRANSPARENCY || ENABLE_PERL +void ecb_hot rxvt_term::rootwin_cb (XEvent &ev) { make_current (); @@ -1834,7 +1850,6 @@ && HOOK_INVOKE ((this, HOOK_ROOT_EVENT, DT_XEVENT, &ev, DT_END))) return; -# if TRANSPARENT switch (ev.type) { case PropertyNotify: @@ -1842,17 +1857,22 @@ * if user used some Esetroot compatible prog to set the root bg, * use the property to determine the pixmap. We use it later on. */ - if (ev.xproperty.atom != xa[XA_XROOTPMAP_ID] - && ev.xproperty.atom != xa[XA_ESETROOT_PMAP_ID]) - return; + if (ev.xproperty.atom == xa[XA_XROOTPMAP_ID] + || ev.xproperty.atom == xa[XA_ESETROOT_PMAP_ID]) + { +# if ENABLE_TRANSPARENCY + bg_set_root_pixmap (); + update_background (); +#endif +#if ENABLE_PERL + HOOK_INVOKE ((this, HOOK_ROOTPMAP_CHANGE, DT_END)); +#endif + } - /* FALLTHROUGH */ - case ReparentNotify: - if (option (Opt_transparent)) - check_our_parents (); break; } -# endif + + refresh_check (); } #endif @@ -1893,7 +1913,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) @@ -1917,7 +1937,7 @@ #else MEvent.button = ev.button; mouse_report (ev); -#endif /* MOUSE_REPORT_DOUBLECLICK */ +#endif /* MOUSE_REPORT_DOUBLECLICK */ } else @@ -1975,9 +1995,16 @@ /* * Scrollbar window processing of button press */ - if (isScrollbarWindow (ev.window)) + if (scrollBar.state && ev.window == scrollBar.win) { - scrollBar.setIdle (); + page_dirn direction = NO_DIR; + + if (scrollBar.upButton (ev.y)) + direction = UP; /* up */ + else if (scrollBar.dnButton (ev.y)) + direction = DN; /* down */ + + scrollBar.state = SB_STATE_IDLE; /* * Rxvt-style scrollbar: * move up if mouse is above slider @@ -1996,15 +2023,9 @@ * arrow buttons - send up/down * click on scrollbar - send pageup/down */ - if ((scrollBar.style == R_SB_NEXT - && scrollbarnext_upButton (ev.y)) - || (scrollBar.style == R_SB_RXVT - && scrollbarrxvt_upButton (ev.y))) + if (direction == UP) tt_printf ("\033[A"); - else if ((scrollBar.style == R_SB_NEXT - && scrollbarnext_dnButton (ev.y)) - || (scrollBar.style == R_SB_RXVT - && scrollbarrxvt_dnButton (ev.y))) + else if (direction == DN) tt_printf ("\033[B"); else switch (ev.button) @@ -2021,92 +2042,76 @@ } } else -#endif /* NO_SCROLLBAR_REPORT */ - +#endif /* NO_SCROLLBAR_REPORT */ { - char upordown = 0; - - if (scrollBar.style == R_SB_NEXT) - { - if (scrollbarnext_upButton (ev.y)) - upordown = -1; /* up */ - else if (scrollbarnext_dnButton (ev.y)) - upordown = 1; /* down */ - } - else if (scrollBar.style == R_SB_RXVT) - { - if (scrollbarrxvt_upButton (ev.y)) - upordown = -1; /* up */ - else if (scrollbarrxvt_dnButton (ev.y)) - upordown = 1; /* down */ - } - if (upordown) + if (direction != NO_DIR) { #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING - cont_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY); + 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) - scrollBar.setUp (); + if (direction == UP) + scrollBar.state = SB_STATE_UP; else - scrollBar.setDn (); + scrollBar.state = SB_STATE_DOWN; } } else switch (ev.button) { case Button2: - switch (scrollbar_align) + switch (scrollBar.align) { - case R_SB_ALIGN_TOP: + case SB_ALIGN_TOP: csrO = 0; break; - case R_SB_ALIGN_CENTRE: + case SB_ALIGN_CENTRE: csrO = (scrollBar.bot - scrollBar.top) / 2; break; - case R_SB_ALIGN_BOTTOM: + case SB_ALIGN_BOTTOM: csrO = scrollBar.bot - scrollBar.top; break; } - 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 ()); + if (scrollBar.style == SB_STYLE_XTERM + || scrollBar.above_slider (ev.y) + || scrollBar.below_slider (ev.y)) + scr_move_to (scrollBar.position (ev.y) - csrO, scrollBar.size ()); - scrollBar.setMotion (); + scrollBar.state = SB_STATE_MOTION; break; case Button1: - if (scrollbar_align == R_SB_ALIGN_CENTRE) + if (scrollBar.align == SB_ALIGN_CENTRE) csrO = ev.y - scrollBar.top; /* FALLTHROUGH */ case Button3: - if (scrollBar.style != R_SB_XTERM) + if (scrollBar.style != SB_STYLE_XTERM) { - if (scrollbar_above_slider (ev.y)) + if (scrollBar.above_slider (ev.y)) # ifdef RXVT_SCROLL_FULL scr_page (UP, nrow - 1); # else scr_page (UP, nrow / 4); # endif - else if (scrollbar_below_slider (ev.y)) + else if (scrollBar.below_slider (ev.y)) # ifdef RXVT_SCROLL_FULL scr_page (DN, nrow - 1); # else scr_page (DN, nrow / 4); # endif else - scrollBar.setMotion (); + scrollBar.state = SB_STATE_MOTION; } else { scr_page ((ev.button == Button1 ? DN : UP), (nrow - * scrollbar_position (ev.y) - / scrollbar_size ())); + * scrollBar.position (ev.y) + / scrollBar.size ())); } break; @@ -2126,15 +2131,14 @@ if (!bypass_keystate) reportmode = !! (priv_modes & PrivMode_mouse_report); - if (scrollbar_isUpDn ()) + if (scrollBar.state == SB_STATE_UP || scrollBar.state == SB_STATE_DOWN) { - scrollBar.setIdle (); - scrollbar_show (0); + scrollBar.state = SB_STATE_IDLE; + scrollBar.show (0); } #ifdef SELECTION_SCROLLING - if (sel_scroll_ev.active) - sel_scroll_ev.stop(); + sel_scroll_ev.stop(); #endif if (ev.window == vt) @@ -2168,7 +2172,7 @@ #else /* MOUSE_REPORT_DOUBLECLICK */ MEvent.button = AnyButton; mouse_report (ev); -#endif /* MOUSE_REPORT_DOUBLECLICK */ +#endif /* MOUSE_REPORT_DOUBLECLICK */ return; } @@ -2189,8 +2193,8 @@ break; 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); + if (IN_RANGE_EXC (ev.x, 0, vt_width) && IN_RANGE_EXC (ev.y, 0, vt_height)) // inside window? + selection_request (ev.time, ev.state & ModMetaMask ? Sel_Clipboard : Sel_Primary); break; #ifdef MOUSE_WHEEL @@ -2216,19 +2220,15 @@ if (mouse_slip_wheel_speed < -nrow) mouse_slip_wheel_speed = -nrow; if (mouse_slip_wheel_speed > +nrow) mouse_slip_wheel_speed = +nrow; - if (slip_wheel_ev.at < NOW) - slip_wheel_ev.at = NOW + SCROLLBAR_CONTINUOUS_DELAY; - - slip_wheel_ev.start (); + if (!slip_wheel_ev.is_active ()) + slip_wheel_ev.start (SCROLLBAR_CONTINUOUS_DELAY, SCROLLBAR_CONTINUOUS_DELAY); } else - { # endif + { scr_page (v, i); - scrollbar_show (1); -# ifdef MOUSE_SLIP_WHEELING + scrollBar.show (1); } -# endif } break; #endif @@ -2236,636 +2236,17 @@ } } -#ifdef TRANSPARENT -#if TINTING && !defined(HAVE_AFTERIMAGE) -/* taken from aterm-0.4.2 */ - -typedef uint32_t RUINT32T; - -void ShadeXImage(rxvt_term *term, XImage* srcImage, int shade, int rm, int gm, int bm) -{ - int sh_r, sh_g, sh_b; - RUINT32T mask_r, mask_g, mask_b; - RUINT32T *lookup, *lookup_r, *lookup_g, *lookup_b; - unsigned int lower_lim_r, lower_lim_g, lower_lim_b; - unsigned int upper_lim_r, upper_lim_g, upper_lim_b; - int i; - - Visual *visual = term->visual; - - if( visual->c_class != TrueColor || srcImage->format != ZPixmap ) return ; - - /* for convenience */ - mask_r = visual->red_mask; - mask_g = visual->green_mask; - mask_b = visual->blue_mask; - - /* boring lookup table pre-initialization */ - switch (srcImage->bits_per_pixel) { - case 15: - if ((mask_r != 0x7c00) || - (mask_g != 0x03e0) || - (mask_b != 0x001f)) - return; - lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(32+32+32)); - lookup_r = lookup; - lookup_g = lookup+32; - lookup_b = lookup+32+32; - sh_r = 10; - sh_g = 5; - sh_b = 0; - break; - case 16: - if ((mask_r != 0xf800) || - (mask_g != 0x07e0) || - (mask_b != 0x001f)) - return; - lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(32+64+32)); - lookup_r = lookup; - lookup_g = lookup+32; - lookup_b = lookup+32+64; - sh_r = 11; - sh_g = 5; - sh_b = 0; - break; - case 24: - if ((mask_r != 0xff0000) || - (mask_g != 0x00ff00) || - (mask_b != 0x0000ff)) - return; - lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(256+256+256)); - lookup_r = lookup; - lookup_g = lookup+256; - lookup_b = lookup+256+256; - sh_r = 16; - sh_g = 8; - sh_b = 0; - break; - case 32: - if ((mask_r != 0xff0000) || - (mask_g != 0x00ff00) || - (mask_b != 0x0000ff)) - return; - lookup = (RUINT32T *) malloc (sizeof (RUINT32T)*(256+256+256)); - lookup_r = lookup; - lookup_g = lookup+256; - lookup_b = lookup+256+256; - sh_r = 16; - sh_g = 8; - sh_b = 0; - break; - default: - return; /* we do not support this color depth */ - } - - /* prepare limits for color transformation (each channel is handled separately) */ - if (shade < 0) { - shade = -shade; - if (shade < 0) shade = 0; - if (shade > 100) shade = 100; - - lower_lim_r = 65535-rm; - lower_lim_g = 65535-gm; - lower_lim_b = 65535-bm; - - lower_lim_r = 65535-(unsigned int)(((RUINT32T)lower_lim_r)*((RUINT32T)shade)/100); - lower_lim_g = 65535-(unsigned int)(((RUINT32T)lower_lim_g)*((RUINT32T)shade)/100); - lower_lim_b = 65535-(unsigned int)(((RUINT32T)lower_lim_b)*((RUINT32T)shade)/100); - - upper_lim_r = upper_lim_g = upper_lim_b = 65535; - } else { - if (shade < 0) shade = 0; - if (shade > 100) shade = 100; - - lower_lim_r = lower_lim_g = lower_lim_b = 0; - - upper_lim_r = (unsigned int)((((RUINT32T)rm)*((RUINT32T)shade))/100); - upper_lim_g = (unsigned int)((((RUINT32T)gm)*((RUINT32T)shade))/100); - upper_lim_b = (unsigned int)((((RUINT32T)bm)*((RUINT32T)shade))/100); - } - - /* switch red and blue bytes if necessary, we need it for some weird XServers like XFree86 3.3.3.1 */ - if ((srcImage->bits_per_pixel == 24) && (mask_r >= 0xFF0000 )) - { - unsigned int tmp; - - tmp = lower_lim_r; - lower_lim_r = lower_lim_b; - lower_lim_b = tmp; - - tmp = upper_lim_r; - upper_lim_r = upper_lim_b; - upper_lim_b = tmp; - } - - /* fill our lookup tables */ - for (i = 0; i <= mask_r>>sh_r; i++) - { - RUINT32T tmp; - tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_r-lower_lim_r)); - tmp += ((RUINT32T)(mask_r>>sh_r))*((RUINT32T)lower_lim_r); - lookup_r[i] = (tmp/65535)<>sh_g; i++) - { - RUINT32T tmp; - tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_g-lower_lim_g)); - tmp += ((RUINT32T)(mask_g>>sh_g))*((RUINT32T)lower_lim_g); - lookup_g[i] = (tmp/65535)<>sh_b; i++) - { - RUINT32T tmp; - tmp = ((RUINT32T)i)*((RUINT32T)(upper_lim_b-lower_lim_b)); - tmp += ((RUINT32T)(mask_b>>sh_b))*((RUINT32T)lower_lim_b); - lookup_b[i] = (tmp/65535)<bits_per_pixel) - { - case 15: - { - unsigned short *p1, *pf, *p, *pl; - p1 = (unsigned short *) srcImage->data; - pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); - while (p1 < pf) - { - p = p1; - pl = p1 + srcImage->width; - for (; p < pl; p++) - { - *p = lookup_r[(*p & 0x7c00)>>10] | - lookup_g[(*p & 0x03e0)>> 5] | - lookup_b[(*p & 0x001f)]; - } - p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line); - } - break; - } - case 16: - { - unsigned short *p1, *pf, *p, *pl; - p1 = (unsigned short *) srcImage->data; - pf = (unsigned short *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); - while (p1 < pf) - { - p = p1; - pl = p1 + srcImage->width; - for (; p < pl; p++) - { - *p = lookup_r[(*p & 0xf800)>>11] | - lookup_g[(*p & 0x07e0)>> 5] | - lookup_b[(*p & 0x001f)]; - } - p1 = (unsigned short *) ((char *) p1 + srcImage->bytes_per_line); - } - break; - } - case 24: - { - unsigned char *p1, *pf, *p, *pl; - p1 = (unsigned char *) srcImage->data; - pf = (unsigned char *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); - while (p1 < pf) - { - p = p1; - pl = p1 + srcImage->width * 3; - for (; p < pl; p += 3) - { - p[0] = lookup_r[(p[0] & 0xff0000)>>16]; - p[1] = lookup_r[(p[1] & 0x00ff00)>> 8]; - p[2] = lookup_r[(p[2] & 0x0000ff)]; - } - p1 = (unsigned char *) ((char *) p1 + srcImage->bytes_per_line); - } - break; - } - case 32: - { - RUINT32T *p1, *pf, *p, *pl; - p1 = (RUINT32T *) srcImage->data; - pf = (RUINT32T *) (srcImage->data + srcImage->height * srcImage->bytes_per_line); - - while (p1 < pf) - { - p = p1; - pl = p1 + srcImage->width; - for (; p < pl; p++) - { - *p = lookup_r[(*p & 0xff0000)>>16] | - lookup_g[(*p & 0x00ff00)>> 8] | - lookup_b[(*p & 0x0000ff)] | - (*p & ~0xffffff); - } - p1 = (RUINT32T *) ((char *) p1 + srcImage->bytes_per_line); - } - break; - } - } - - free (lookup); -} -#endif - -/* - * Check our parents are still who we think they are. - * Do transparency updates if required - */ -int -rxvt_term::check_our_parents () -{ -#if TRANSPARENT || ENABLE_PERL - check_our_aprents_ev.stop(); - check_our_aprents_ev.start(NOW + 1./3.); -#endif - return 0; -} - -void -rxvt_term::check_our_parents_cb (time_watcher &w) -{ - int i, pchanged, aformat, have_pixmap, rootdepth; - unsigned long nitems, bytes_after; - Atom atype; - unsigned char *prop = NULL; - Window root, oldp, *list; - Pixmap rootpixmap = None; - XWindowAttributes wattr, wrootattr; - int sx, sy; - Window cr; - - pchanged = 0; - - if (!option (Opt_transparent)) - return /*pchanged*/; /* Don't try any more */ - - XGetWindowAttributes (dpy, display->root, &wrootattr); - rootdepth = wrootattr.depth; - - XGetWindowAttributes (dpy, parent[0], &wattr); - - if (rootdepth != wattr.depth) - { - if (am_transparent) - { - pchanged = 1; - XSetWindowBackground (dpy, vt, pix_colors_focused[Color_bg]); - am_transparent = am_pixmap_trans = 0; - } - - return /*pchanged*/; /* Don't try any more */ - } - - /* Get all X ops out of the queue so that our information is up-to-date. */ - XSync (dpy, False); - - XTranslateCoordinates (dpy, parent[0], display->root, - 0, 0, &sx, &sy, &cr); - - /* check if we are outside of the visible part of the virtual screen : */ - if( sx + (int)szHint.width <= 0 || sy + (int)szHint.height <= 0 - || sx >= wrootattr.width || sy >= wrootattr.height ) - return /* 0 */ ; - /* - * Make the frame window set by the window manager have - * the root background. Some window managers put multiple nested frame - * windows for each client, so we have to take care about that. - */ - i = (xa[XA_XROOTPMAP_ID] - && XGetWindowProperty (dpy, display->root, xa[XA_XROOTPMAP_ID], - 0L, 1L, False, XA_PIXMAP, &atype, &aformat, - &nitems, &bytes_after, &prop) == Success); - - if (!i || prop == NULL) - i = (xa[XA_ESETROOT_PMAP_ID] - && XGetWindowProperty (dpy, display->root, xa[XA_ESETROOT_PMAP_ID], - 0L, 1L, False, XA_PIXMAP, &atype, &aformat, - &nitems, &bytes_after, &prop) == Success); - - if (!i || prop == NULL -#if TINTING - || (!ISSET_PIXCOLOR (Color_tint) && rs[Rs_shade] == NULL -#ifdef HAVE_AFTERIMAGE - && original_asim == NULL && rs[Rs_blurradius] == NULL -#endif - ) -#endif - ) - have_pixmap = 0; - else - { - have_pixmap = 1; - rootpixmap = *(Pixmap *)prop; - XFree (prop); - } - - if (have_pixmap) - { - Bool success = False ; - GC gc; - XGCValues gcvalue; -#ifdef HAVE_AFTERIMAGE - { - Pixmap tmp_pmap = None ; - ShadingInfo shade; - ARGB32 tint ; - unsigned int pmap_w = 0, pmap_h = 0; - - if (get_drawable_size( rootpixmap, &pmap_w, &pmap_h )) - { - int root_x = 0, root_y = 0; - - shade.shading = rs[Rs_shade] ? atoi (rs[Rs_shade]) : 100; - if (ISSET_PIXCOLOR (Color_tint)) - { - rgba c; - pix_colors_focused [Color_tint].get (c); - shade.tintColor.red = c.r; - shade.tintColor.green = c.g; - shade.tintColor.blue = c.b; - } - else - shade.tintColor.red = shade.tintColor.green = shade.tintColor.blue = 0xFFFF; - tint = shading2tint32( &shade ); - gc = XCreateGC (dpy, vt, 0UL, &gcvalue); - if (GetWinPosition (parent[0], &root_x, &root_y) ) - { - ASImageLayer *layers = create_image_layers( 2 ); - ASImage *merged_im = NULL; - int back_x, back_y, back_w, back_h; - /* merge_layers does good job at tiling background appropriately, - so all we need is to cut out smallest possible piece : */ -#define MAKE_ROOTPMAP_GEOM(xy,wh,widthheight) \ - do{ while( root_##xy < 0 ) root_##xy += (int)wrootattr.widthheight; \ - back_##xy = root_##xy % pmap_##wh; /* that gives us left side of the closest tile : */ \ - if( pmap_##wh >= back_##xy + szHint.widthheight ) \ - back_##wh = szHint.widthheight;/* background is large - limit it by our size */ \ - else \ - { /* small background - need the whole of it for successfull tiling :*/ \ - back_##xy = 0; \ - back_##wh = pmap_##wh; \ - }}while(0) - - MAKE_ROOTPMAP_GEOM(x,w,width); - MAKE_ROOTPMAP_GEOM(y,h,height); - - layers[0].im = pixmap2asimage (display->asv, rootpixmap, back_x, back_y, back_w, back_h, AllPlanes, ASA_ASImage, 100); - layers[0].clip_x = (back_w == pmap_w)?root_x:0; - layers[0].clip_y = (back_h == pmap_h)?root_y:0; - layers[0].clip_width = szHint.width; - layers[0].clip_height = szHint.height; - layers[0].tint = tint; - if (rs[Rs_blurradius] && layers[0].im) - { - double r = atof(rs[Rs_blurradius]); - ASImage* tmp = blur_asimage_gauss(display->asv, layers[0].im, r, r, 0xFFFFFFFF, ASA_ASImage, 100, ASIMAGE_QUALITY_DEFAULT ); - if( tmp ) - { - destroy_asimage( &layers[0].im ); - layers[0].im = tmp; - } - } - if (original_asim != NULL) - { - int fore_w, fore_h; - layers[1].im = original_asim; - if( bgPixmap.auto_resize ) - { - fore_w = szHint.width; - fore_h = szHint.height; - } - else - { - fore_w = bgPixmap.w; - fore_h = bgPixmap.h; - } - if (fore_w != original_asim->width - || fore_h != original_asim->height) - { - layers[1].im = scale_asimage( display->asv, - original_asim, - fore_w, fore_h, - ASA_ASImage, 100, - ASIMAGE_QUALITY_DEFAULT ); - } - - layers[1].clip_width = szHint.width; - layers[1].clip_height = szHint.height; - - if (rs[Rs_blendtype]) - { - layers[1].merge_scanlines = blend_scanlines_name2func(rs[Rs_blendtype]); - if( layers[1].merge_scanlines == NULL ) - layers[1].merge_scanlines = alphablend_scanlines; - } - } - merged_im = merge_layers( display->asv, layers, layers[1].im?2:1, - szHint.width, szHint.height, - ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT ); - if (layers[1].im != original_asim) - destroy_asimage( &(layers[1].im) ); - destroy_asimage( &(layers[0].im) ); - if (merged_im != NULL) - { - tmp_pmap = asimage2pixmap( display->asv, DefaultRootWindow(dpy), merged_im, gc, True ); - destroy_asimage( &merged_im ); - } - free( layers ); - } - } - if (tmp_pmap != None) - { - success = True; - if (pixmap != None) - XFreePixmap (dpy, pixmap); - pixmap = tmp_pmap; - } - } -#else /* HAVE_AFTERIMAGE */ - { - /* - * Copy display->root pixmap transparency - */ - int nx, ny; - unsigned int nw, nh; - XImage *image; - - nw = (unsigned int)szHint.width; - nh = (unsigned int)szHint.height; - nx = ny = 0; - - if (sx < 0) - { - nw += sx; - nx = -sx; - sx = 0; - } - - if (sy < 0) - { - nh += sy; - ny = -sy; - sy = 0; - } - - min_it (nw, (unsigned int) (wrootattr.width - sx)); - min_it (nh, (unsigned int) (wrootattr.height - sy)); - - XSync (dpy, False); - allowedxerror = -1; - image = XGetImage (dpy, rootpixmap, sx, sy, nw, nh, AllPlanes, ZPixmap); - - /* XXX: handle BadMatch - usually because we're outside the pixmap */ - /* XXX: may need a delay here? */ - allowedxerror = 0; - if (image != NULL) - { - if (pixmap != None) - XFreePixmap (dpy, pixmap); - -#if TINTING - if (ISSET_PIXCOLOR (Color_tint)) - { - int shade = rs[Rs_shade] ? atoi (rs[Rs_shade]) : 100; - - rgba c; - pix_colors_focused [Color_tint].get (c); - ShadeXImage (this, image, shade, c.r, c.g, c.b); - } -#endif - - pixmap = XCreatePixmap (dpy, vt, szHint.width, szHint.height, image->depth); - gc = XCreateGC (dpy, vt, 0UL, &gcvalue); - XPutImage (dpy, pixmap, gc, image, 0, 0, - nx, ny, image->width, image->height); - XDestroyImage (image); - success = True ; - } - } -#endif /* HAVE_AFTERIMAGE */ - if (gc != NULL) - XFreeGC (dpy, gc); - - if (!success) - { - if (am_transparent && am_pixmap_trans) - { - pchanged = 1; - if (pixmap != None) - { - XFreePixmap (dpy, pixmap); - pixmap = None; - } - } - - am_pixmap_trans = 0; - } - else - { - XSetWindowBackgroundPixmap (dpy, parent[0], pixmap); - XClearWindow (dpy, parent[0]); - - if (!am_transparent || !am_pixmap_trans) - pchanged = 1; - - am_transparent = am_pixmap_trans = 1; - } - } - - if (am_pixmap_trans) - XSetWindowBackgroundPixmap (dpy, vt, ParentRelative); - else - { - unsigned int n; - /* - * InheritPixmap transparency - */ - for (i = 1; i < (int) (sizeof (parent) / sizeof (Window)); i++) - { - oldp = parent[i]; - XQueryTree (dpy, parent[i - 1], &root, &parent[i], &list, &n); - XFree (list); - - if (parent[i] == display->root) - { - if (oldp != None) - pchanged = 1; - - break; - } - - if (oldp != parent[i]) - pchanged = 1; - } - - n = 0; - - if (pchanged) - for (; n < (unsigned int)i; n++) - { - XGetWindowAttributes (dpy, parent[n], &wattr); - - if (wattr.depth != rootdepth || wattr.c_class == InputOnly) - { - n = (int) (sizeof (parent) / sizeof (Window)) + 1; - break; - } - } - - if (n > (sizeof (parent) / sizeof (parent[0]))) - { - XSetWindowBackground (dpy, parent[0], pix_colors_focused[Color_border]); - XSetWindowBackground (dpy, vt, pix_colors_focused[Color_bg]); - am_transparent = 0; - /* XXX: also turn off Opt_transparent? */ - } - else - { - for (n = 0; n < (unsigned int)i; n++) - { - XSetWindowBackgroundPixmap (dpy, parent[n], ParentRelative); - XClearWindow (dpy, parent[n]); - } - - XSetWindowBackgroundPixmap (dpy, vt, ParentRelative); - am_transparent = 1; - } - - for (; i < (int) (sizeof (parent) / sizeof (Window)); i++) - parent[i] = None; - } - - if (scrollBar.win) - { - XSetWindowBackgroundPixmap (dpy, scrollBar.win, ParentRelative); - scrollBar.setIdle (); - scrollbar_show (0); - } - - if (am_transparent) - { - want_refresh = want_full_refresh = 1; - if (am_pixmap_trans) - flush (); - } - -// return pchanged; -} -#endif - /*}}} */ -bool +void ecb_hot 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 (ecb_unlikely (ch == NOCHAR)) { seq_begin = cmdbuf_ptr; ch = next_char (); @@ -2874,9 +2255,9 @@ break; } - if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT) + if (ecb_likely (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT)) { - if (!seen_input) + if (ecb_unlikely (!seen_input)) { seen_input = 1; // many badly-written programs (e.g. jed) contain a race condition: @@ -2899,25 +2280,28 @@ for (;;) { - if (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT)) + if (ecb_unlikely (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT))) break; *str++ = ch; - if (ch == C0_LF || str >= eol) + if (ecb_unlikely (ch == C0_LF || str >= eol)) { if (ch == C0_LF) nlines++; refresh_count++; - if (!option (Opt_jumpScroll) - || (refresh_count >= refresh_limit * (nrow - 1))) + if (!option (Opt_jumpScroll) || refresh_count >= nrow - 1) { - refreshnow = true; refresh_count = 0; - ch = NOCHAR; - break; + + if (!option (Opt_skipScroll) || ev_time () > ev::now () + 1. / 60.) + { + refreshnow = true; + ch = NOCHAR; + break; + } } // scr_add_lines only works for nlines <= nrow - 1. @@ -2955,23 +2339,14 @@ /* * If there have been a lot of new lines, then update the screen - * What the heck I'll cheat and only refresh less than every page-full. - * the number of pages between refreshes is refresh_limit, which - * is incremented here because we must be doing flat-out scrolling. + * What the heck we'll cheat and only refresh less than every page-full. + * if skipScroll is enabled. */ if (refreshnow) { - if (option (Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD) - refresh_limit++; - else - { - flag = true; - //TODO: due to popular request, implement "skipscroll" option here - scr_refresh (); - want_refresh = 1; - } + scr_refresh (); + want_refresh = 1; } - } else { @@ -2989,18 +2364,16 @@ ch = NOCHAR; } } - - return flag; } // read the next character -wchar_t +wchar_t ecb_hot rxvt_term::next_char () NOTHROW { while (cmdbuf_ptr < cmdbuf_endp) { // assume 7-bit to be ascii ALWAYS - if ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b) + if (ecb_likely ((unsigned char)*cmdbuf_ptr <= 0x7f && *cmdbuf_ptr != 0x1b)) return *cmdbuf_ptr++; wchar_t wc; @@ -3014,7 +2387,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; @@ -3025,7 +2401,7 @@ } // read the next octet -uint32_t +uint32_t ecb_hot rxvt_term::next_octet () NOTHROW { return cmdbuf_ptr < cmdbuf_endp @@ -3035,12 +2411,7 @@ static class out_of_input out_of_input; -/* rxvt_cmd_getc () - Return next input character */ -/* - * Return the next input character after first passing any keyboard input - * to the command. - */ -wchar_t +wchar_t ecb_hot rxvt_term::cmd_getc () THROW ((class out_of_input)) { wchar_t c = next_char (); @@ -3051,7 +2422,7 @@ return c; } -uint32_t +uint32_t ecb_hot rxvt_term::cmd_get8 () THROW ((class out_of_input)) { uint32_t c = next_octet (); @@ -3065,10 +2436,10 @@ /*{{{ print pipe */ /*----------------------------------------------------------------------*/ #ifdef PRINTPIPE -FILE * +FILE * ecb_cold 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"); @@ -3076,7 +2447,7 @@ return stream; } -int +int ecb_cold rxvt_term::pclose_printer (FILE *stream) { fflush (stream); @@ -3086,20 +2457,19 @@ /* * simulate attached vt100 printer */ -void +void ecb_cold 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; @@ -3128,7 +2498,7 @@ break; /* done = 1 */ } } - + for (i = 0; i < len; i++) if (putc (buf[i], fd) == EOF) { @@ -3140,10 +2510,9 @@ pclose_printer (fd); } -#endif /* PRINTPIPE */ +#endif /* PRINTPIPE */ /*}}} */ -/* *INDENT-OFF* */ enum { C1_40 = 0x40, C1_41 , C1_BPH, C1_NBH, C1_44 , C1_NEL, C1_SSA, C1_ESA, @@ -3151,10 +2520,9 @@ C1_DCS, C1_PU1, C1_PU2, C1_STS, C1_CCH, C1_MW , C1_SPA, C1_EPA, C1_SOS, C1_59 , C1_SCI, C1_CSI, CS_ST , C1_OSC, C1_PM , C1_APC, }; -/* *INDENT-ON* */ /*{{{ process non-printing single characters */ -void +void ecb_hot rxvt_term::process_nonprinting (unicode_t ch) { switch (ch) @@ -3200,7 +2568,7 @@ case 0x9b: /* CSI */ process_csi_seq (); break; - case 0x9d: /* CSI */ + case 0x9d: /* OSC */ process_osc_seq (); break; #endif @@ -3210,7 +2578,7 @@ /*{{{ process VT52 escape sequences */ -void +void ecb_cold rxvt_term::process_escape_vt52 (unicode_t ch) { int row, col; @@ -3254,7 +2622,7 @@ tt_printf ("\033/Z"); /* I am a VT100 emulating a VT52 */ break; case '<': /* turn off VT52 mode */ - PrivMode (0, PrivMode_vt52); + priv_modes &= ~PrivMode_vt52; break; case 'F': /* use special graphics character set */ case 'G': /* use regular character set */ @@ -3270,7 +2638,7 @@ /*{{{ process escape sequences */ -void +void ecb_hot rxvt_term::process_escape_seq () { unicode_t ch = cmd_getc (); @@ -3283,7 +2651,6 @@ switch (ch) { - /* case 1: do_tek_mode (); break; */ case '#': if (cmd_getc () == '8') scr_E (); @@ -3316,9 +2683,12 @@ scr_forwardindex (); break; #endif + // DECPAM/DECPNM case '=': + priv_modes |= PrivMode_aplKP; + break; case '>': - PrivMode ((ch == '='), PrivMode_aplKP); + priv_modes &= ~PrivMode_aplKP; break; case C1_40: @@ -3332,13 +2702,15 @@ case C1_NEL: /* ESC E */ { wchar_t nlcr[] = { C0_LF, C0_CR }; - scr_add_lines (nlcr, sizeof (nlcr) / sizeof (nlcr [0]), 1); + scr_add_lines (nlcr, ecb_array_length (nlcr), 1); } break; /* kidnapped escape sequence: Should be 8.3.48 */ case C1_ESA: /* ESC G */ - process_graphics (); + // used by original rxvt for rob nations own graphics mode + if (cmd_getc () == 'Q') + tt_printf ("\033G0\012"); /* query graphics - no graphics */ break; /* 8.3.63: CHARACTER TABULATION SET */ @@ -3352,10 +2724,10 @@ break; /* 8.3.142: SINGLE-SHIFT TWO */ - /*case C1_SS2: scr_single_shift (2); break; */ + /* case C1_SS2: break; */ /* 8.3.143: SINGLE-SHIFT THREE */ - /*case C1_SS3: scr_single_shift (3); break; */ + /* case C1_SS3: break; */ /* 8.3.27: DEVICE CONTROL STRING */ case C1_DCS: /* ESC P */ @@ -3367,21 +2739,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) */ @@ -3398,7 +2770,6 @@ /*}}} */ /*{{{ process CONTROL SEQUENCE INTRODUCER (CSI) sequences `ESC[' */ -/* *INDENT-OFF* */ enum { CSI_ICH = 0x40, CSI_CUU, CSI_CUD, CSI_CUF, CSI_CUB, CSI_CNL, CSI_CPL, CSI_CHA, @@ -3411,13 +2782,13 @@ CSI_78 , CSI_79 , CSI_7A , CSI_7B , CSI_7C , CSI_7D , CSI_7E , CSI_7F }; -#define make_byte(b7,b6,b5,b4,b3,b2,b1,b0) \ +#define make_byte(b0,b1,b2,b3,b4,b5,b6,b7) \ (((b7) << 7) | ((b6) << 6) | ((b5) << 5) | ((b4) << 4) \ | ((b3) << 3) | ((b2) << 2) | ((b1) << 1) | (b0)) #define get_byte_array_bit(array, bit) \ - (!! ((array)[ (bit) / 8] & (128 >> ((bit) & 7)))) + (!! ((array)[(bit) >> 3] & (1 << ((bit) & 7)))) -const unsigned char csi_defaults[] = +static const unsigned char csi_defaults[] = { make_byte (1,1,1,1,1,1,1,1), /* @, A, B, C, D, E, F, G, */ make_byte (1,1,0,0,1,1,0,0), /* H, I, J, K, L, M, N, O, */ @@ -3428,23 +2799,22 @@ make_byte (0,0,0,0,0,0,0,0), /* p, q, r, s, t, u, v, w, */ make_byte (0,0,0,0,0,0,0,0), /* x, y, z, {, |, }, ~, */ }; -/* *INDENT-ON* */ -void +void ecb_hot rxvt_term::process_csi_seq () { unicode_t ch, priv, i; unsigned int nargs, p; int n, ndef; - int arg[ESC_ARGS]; + int arg[ESC_ARGS] = { }; - for (nargs = ESC_ARGS; nargs > 0;) - arg[--nargs] = 0; + nargs = 0; priv = 0; ch = cmd_getc (); - if (ch >= '<' && ch <= '?') - { /* '<' '=' '>' '?' */ + if ((ch >= '<' && ch <= '?') || ch == '!') + { + /* '<' '=' '>' '?' '!' */ priv = ch; ch = cmd_getc (); } @@ -3493,21 +2863,37 @@ case '>': if (ch == CSI_DA) /* secondary device attributes */ { - // first parameter is normally 0 for vt100, 1 for some newer vtxxx, 'R' for rxvt, + // first parameter is normally 0 for vt100, 1 for vt220, 'R' for rxvt, // 'U' for rxvt-unicode != 7.[34] (where it was broken). // // second parameter is xterm patch level for xterm, MMmmpp (e.g. 20703) for rxvt - // and Mm (e.g. 72 for 7.2) for urxvt <= 7.2, and 94 for later versions, to signify - // that we do not support xterm mouse reporting (should be 95 when we do). + // and Mm (e.g. 72 for 7.2) for urxvt <= 7.2, 94 for urxvt <= 8.3, and 95 for later + // versions. // - tt_printf ("\033[>%d;94;0c", 'U'); + tt_printf ("\033[>%d;95;0c", 'U'); } break; + case '?': 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, ecb_array_length (pm_h), pm_h); + process_terminal_mode ('l', 0, ecb_array_length (pm_l), pm_l); + } + break; } + return; } @@ -3531,11 +2917,11 @@ #endif case CSI_CUU: /* 8.3.22: (1) CURSOR UP */ - case CSI_VPR: /* 8.3.161: (1) LINE POSITION FORWARD */ + case CSI_VPB: /* 8.3.160: (1) LINE POSITION BACKWARD */ arg[0] = -arg[0]; /* FALLTHROUGH */ case CSI_CUD: /* 8.3.19: (1) CURSOR DOWN */ - case CSI_VPB: /* 8.3.160: (1) LINE POSITION BACKWARD */ + case CSI_VPR: /* 8.3.161: (1) LINE POSITION FORWARD */ scr_gotorc (arg[0], 0, RELATIVE); break; @@ -3732,7 +3118,6 @@ /*}}} */ #if !ENABLE_MINIMAL -/* ARGSUSED */ void rxvt_term::process_window_ops (const int *args, unsigned int nargs) { @@ -3751,22 +3136,22 @@ * commands */ case 1: /* deiconify window */ - XMapWindow (dpy, parent[0]); + XMapWindow (dpy, parent); break; case 2: /* iconify window */ - XIconifyWindow (dpy, parent[0], display->screen); + XIconifyWindow (dpy, parent, display->screen); break; case 3: /* set position (pixels) */ - XMoveWindow (dpy, parent[0], args[1], args[2]); + XMoveWindow (dpy, parent, args[1], args[2]); break; case 4: /* set size (pixels) */ set_widthheight ((unsigned int)args[2], (unsigned int)args[1]); break; case 5: /* raise window */ - XRaiseWindow (dpy, parent[0]); + XRaiseWindow (dpy, parent); break; case 6: /* lower window */ - XLowerWindow (dpy, parent[0]); + XLowerWindow (dpy, parent); break; case 7: /* refresh window */ scr_touch (true); @@ -3779,7 +3164,7 @@ //case 9: NYI, TODO, restore maximized window or maximize window default: if (args[0] >= 24) /* set height (chars) */ - set_widthheight ((unsigned int)width, + set_widthheight ((unsigned int)vt_width, (unsigned int) (args[1] * fheight)); break; @@ -3787,18 +3172,18 @@ * reports - some output format copied from XTerm */ case 11: /* report window state */ - XGetWindowAttributes (dpy, parent[0], &wattr); + XGetWindowAttributes (dpy, parent, &wattr); tt_printf ("\033[%dt", wattr.map_state == IsViewable ? 1 : 2); break; case 13: /* report window position */ - XGetWindowAttributes (dpy, parent[0], &wattr); - XTranslateCoordinates (dpy, parent[0], wattr.root, + XGetWindowAttributes (dpy, parent, &wattr); + XTranslateCoordinates (dpy, parent, wattr.root, -wattr.border_width, -wattr.border_width, &x, &y, &wdummy); tt_printf ("\033[3;%d;%dt", x, y); break; case 14: /* report window size (pixels) */ - XGetWindowAttributes (dpy, parent[0], &wattr); + XGetWindowAttributes (dpy, parent, &wattr); tt_printf ("\033[4;%d;%dt", wattr.height, wattr.width); break; case 18: /* report text area size (chars) */ @@ -3810,7 +3195,7 @@ case 20: /* report icon label */ { char *s; - XGetIconName (dpy, parent[0], &s); + XGetIconName (dpy, parent, &s); tt_printf ("\033]L%-.250s\234", option (Opt_insecure) && s ? s : ""); /* 8bit ST */ XFree (s); } @@ -3818,7 +3203,7 @@ case 21: /* report window title */ { char *s; - XFetchName (dpy, parent[0], &s); + XFetchName (dpy, parent, &s); tt_printf ("\033]l%-.250s\234", option (Opt_insecure) && s ? s : ""); /* 8bit ST */ XFree (s); } @@ -3884,13 +3269,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); @@ -3904,15 +3288,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) @@ -3946,7 +3330,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; @@ -3956,7 +3340,7 @@ dLocal (Display *, dpy); assert (str != NULL); - + if (HOOK_INVOKE ((this, HOOK_OSC_SEQ, DT_INT, op, DT_STR, str, DT_END))) return; @@ -3983,7 +3367,7 @@ const char *str = ""; if (prop - && XGetWindowProperty (dpy, parent[0], + && XGetWindowProperty (dpy, parent, prop, 0, 1<<16, 0, AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &value) == Success @@ -3997,7 +3381,7 @@ } else { - char *eq = strchr (str, '='); // constness lost, but verified to be ok + char *eq = strchr (str, '='); if (eq) { @@ -4005,7 +3389,7 @@ set_utf8_property (display->atom (str), eq + 1); } else - XDeleteProperty (dpy, parent[0], + XDeleteProperty (dpy, parent, display->atom (str)); } break; @@ -4028,9 +3412,11 @@ process_color_seq (op, color, name, resp); } break; + case Rxvt_restoreFG: case XTerm_Color00: process_color_seq (op, Color_fg, str, resp); break; + case Rxvt_restoreBG: case XTerm_Color01: process_color_seq (op, Color_bg, str, resp); break; @@ -4045,15 +3431,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; @@ -4061,60 +3450,69 @@ process_color_seq (op, Color_IT, str, resp); break; #endif -#if TRANSPARENT && TINTING + 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); + { + bool changed = false; - check_our_parents (); + if (ISSET_PIXCOLOR (Color_tint)) + changed = root_effects.set_tint (pix_colors_focused [Color_tint]); - if (am_transparent) - want_full_refresh = want_refresh = 1; + if (changed) + update_background (); + } break; #endif +#if BG_IMAGE_FROM_FILE case Rxvt_Pixmap: - { - if (*str != ';') - { -#if XPM_BACKGROUND - scale_pixmap (""); /* reset to default scaling */ - set_bgPixmap (str); /* change pixmap */ - scr_touch (true); -#endif - } - - int changed = 0; - - while ((str = strchr (str, ';')) != NULL) - { - str++; -#if XPM_BACKGROUND - changed += scale_pixmap (str); -#endif - } + if (!strcmp (str, "?")) + { + char str[256]; + 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, + h_align, v_align); + process_xterm_seq (XTerm_title, str, CHAR_ST); + } + else + { + bool changed = false; - if (changed) - { -#ifdef XPM_BACKGROUND - resize_pixmap (); - scr_touch (true); -#endif - } -#if TRANSPARENT && defined(HAVE_AFTERIMAGE) - if (option(Opt_transparent)) - check_our_parents (); -#endif - - } - break; + if (*str != ';') + { + if (fimage.set_file_geometry (this, str)) + changed = true; + } + else + { + str++; + if (fimage.set_geometry (str, true)) + changed = true; + } - case Rxvt_restoreFG: - set_window_color (Color_fg, str); - break; - case Rxvt_restoreBG: - set_window_color (Color_bg, str); + if (changed) + { + if (bg_window_position_sensitive ()) + { + int x, y; + get_window_origin (x, y); + bg_set_position (x, y); + } + update_background (); + } + } break; +#endif case XTerm_logfile: // TODO, when secure mode? @@ -4191,8 +3589,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 } @@ -4209,14 +3606,17 @@ * 't' = toggle * so no need for fancy checking */ -int +int ecb_cold rxvt_term::privcases (int mode, unsigned long bit) { int state; if (mode == 's') { - SavedModes |= (priv_modes & bit); + if (priv_modes & bit) + SavedModes |= bit; + else + SavedModes &= ~bit; return -1; } else @@ -4225,7 +3625,11 @@ state = (SavedModes & bit) ? 1 : 0; /* no overlapping */ else state = (mode == 't') ? ! (priv_modes & bit) : mode; - PrivMode (state, bit); + + if (state) + priv_modes |= bit; + else + priv_modes &= ~bit; } return state; @@ -4233,55 +3637,61 @@ /* we're not using priv _yet_ */ void -rxvt_term::process_terminal_mode (int mode, int priv UNUSED, unsigned int nargs, const int *arg) +rxvt_term::process_terminal_mode (int mode, int priv ecb_unused, unsigned int nargs, const int *arg) { unsigned int i, j; int state; static const struct - { - const int argval; - const unsigned long bit; - } - - argtopriv[] = { - { 1, PrivMode_aplCUR }, - { 2, PrivMode_vt52 }, - { 3, PrivMode_132 }, - { 4, PrivMode_smoothScroll }, - { 5, PrivMode_rVideo }, - { 6, PrivMode_relOrigin }, - { 7, PrivMode_Autowrap }, - // 8, bi-directional support mode + { + const int argval; + const unsigned long bit; + } argtopriv[] = { + { 1, PrivMode_aplCUR }, // DECCKM + { 2, PrivMode_vt52 }, // DECANM + { 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 }, // DECTCEM 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 }, // DECNKM #ifndef NO_BACKSPACE_KEY - { 67, PrivMode_BackSpace }, + { 67, PrivMode_BackSpace }, // DECBKM #endif { 1000, PrivMode_MouseX11 }, - // 1001 Use Hilite Mouse Tracking. NYI, TODO - // 1002 Use Cell Motion Mouse Tracking. NYI, TODO - // 1003 Use All Motion Mouse Tracking. NYI, TODO + { 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 }, }; if (nargs == 0) @@ -4298,7 +3708,7 @@ state = -1; /* basic handling */ - for (j = 0; j < (sizeof (argtopriv)/sizeof (argtopriv[0])); j++) + for (j = 0; j < ecb_array_length (argtopriv); j++) if (argtopriv[j].argval == arg[i]) { state = privcases (mode, argtopriv[j].bit); @@ -4316,7 +3726,6 @@ break; #endif case 1048: /* alternative cursor save */ - case 1049: if (option (Opt_secondaryScreen)) if (mode == 0) scr_cursor (RESTORE); @@ -4335,11 +3744,11 @@ * parameter. Return from VT52 mode with an ESC < from * within VT52 mode */ - PrivMode (1, PrivMode_vt52); + priv_modes |= PrivMode_vt52; break; case 3: /* 80/132 */ if (priv_modes & PrivMode_132OK) - set_widthheight (((state ? 132 : 80) * fwidth), height); + set_widthheight ((state ? 132 : 80) * fwidth, 24 * fheight); break; case 4: /* smooth scrolling */ set_option (Opt_jumpScroll, !state); @@ -4356,15 +3765,13 @@ /* case 8: - auto repeat, can't do on a per window basis */ case 9: /* X10 mouse reporting */ if (state) /* orthogonal */ - priv_modes &= ~PrivMode_MouseX11; + priv_modes &= ~(PrivMode_MouseX11|PrivMode_MouseBtnEvent|PrivMode_MouseAnyEvent); break; #ifdef scrollBar_esc case scrollBar_esc: - if (scrollbar_mapping (state)) - { - resize_all_windows (0, 0, 0); - scr_touch (true); - } + scrollBar.map (state); + resize_all_windows (0, 0, 0); + scr_touch (true); break; #endif case 25: /* visible/invisible cursor */ @@ -4379,12 +3786,22 @@ /* case 67: - backspace key */ case 1000: /* X11 mouse reporting */ if (state) /* orthogonal */ - priv_modes &= ~PrivMode_MouseX10; + priv_modes &= ~(PrivMode_MouseX10|PrivMode_MouseBtnEvent|PrivMode_MouseAnyEvent); + break; + case 1002: + case 1003: + if (state) + { + 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; -#if 0 - case 1001: - break; /* X11 mouse highlighting */ -#endif case 1010: /* scroll to bottom on TTY output inhibit */ set_option (Opt_scrollTtyOutput, !state); break; @@ -4393,15 +3810,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; @@ -4411,7 +3836,7 @@ /*}}} */ /*{{{ process sgr sequences */ -void +void ecb_hot rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg) { unsigned int i; @@ -4564,24 +3989,6 @@ } /*}}} */ -/*{{{ (do not) process Rob Nation's own graphics mode sequences */ -void -rxvt_term::process_graphics () -{ - unicode_t ch, cmd = cmd_getc (); - - if (cmd == 'Q') - { /* query graphics */ - tt_printf ("\033G0\012"); /* no graphics */ - return; - } - /* swallow other graphics sequences until terminating ':' */ - do - ch = cmd_getc (); - while (ch != ':'); -} -/*}}} */ - /* ------------------------------------------------------------------------- */ /* @@ -4604,7 +4011,7 @@ /* Write data to the pty as typed by the user, pasted with the mouse, * or generated by us in response to a query ESC sequence. */ -const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT +static const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT void rxvt_term::tt_write (const char *data, unsigned int len) @@ -4619,19 +4026,21 @@ { ssize_t written = write (pty->pty, data, min (len, MAX_PTY_WRITE)); - if ((unsigned int)written == len) + max_it (written, 0); + + if (written == len) return; data += written; len -= written; } - v_buffer = (char *)realloc (v_buffer, v_buflen + len); + v_buffer = (char *)rxvt_realloc (v_buffer, v_buflen + len); memcpy (v_buffer + v_buflen, data, len); v_buflen += len; - pty_ev.set (EVENT_READ | EVENT_WRITE); + pty_ev.set (ev::READ | ev::WRITE); } void rxvt_term::pty_write () @@ -4646,16 +4055,15 @@ { free (v_buffer); v_buffer = 0; - v_buflen = 0; - pty_ev.set (EVENT_READ); + pty_ev.set (ev::READ); return; } memmove (v_buffer, v_buffer + written, v_buflen); } else if (written != -1 || (errno != EAGAIN && errno != EINTR)) - pty_ev.set (EVENT_READ); + pty_ev.set (ev::READ); } /*----------------------- end-of-file (C source) -----------------------*/