--- rxvt-unicode/src/command.C 2010/11/19 23:29:30 1.460 +++ rxvt-unicode/src/command.C 2011/04/07 12:19:40 1.482 @@ -27,7 +27,7 @@ * Copyright (c) 2001 Marius Gedminas * - Ctrl/Mod4+Tab works like Meta+Tab (options) * Copyright (c) 2003 Rob McMullen - * Copyright (c) 2003-2007 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 @@ -891,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]; @@ -938,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 HAVE_BG_PIXMAP - if (bgPixmap.flags & bgPixmap_t::hasChanged) + if (bg_flags & BG_NEEDS_REFRESH) { - bgPixmap.flags &= ~bgPixmap_t::hasChanged; -// scr_clear (true); This needs to be researched further! + bg_flags &= ~BG_NEEDS_REFRESH; scr_touch (false); } #endif @@ -1155,22 +1121,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 (); + + size_t avail = cmdbuf_base + CBUFSIZ - cmdbuf_endp; - if (CBUFSIZ == n) + 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) { @@ -1254,12 +1253,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; @@ -1272,7 +1273,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) @@ -1314,14 +1315,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 */ @@ -1433,14 +1447,14 @@ break; case ConfigureNotify: - if (ev.xconfigure.window == parent[0]) + if (ev.xconfigure.window == parent) { while (XCheckTypedWindowEvent (dpy, ev.xconfigure.window, ConfigureNotify, &ev)) ; #ifdef HAVE_BG_PIXMAP bool moved = false; - if (bgPixmap.window_position_sensitive ()) + if (bg_window_position_sensitive ()) { int x, y; if (ev.xconfigure.send_event) @@ -1451,8 +1465,8 @@ else get_window_origin (x, y); - if (bgPixmap.set_position (x, y) - || (bgPixmap.flags & bgPixmap_t::isInvalid)) + if (bg_set_position (x, y) + || !(bg_flags & BG_IS_VALID)) moved = true; } #endif @@ -1470,7 +1484,7 @@ if (mapped) update_background (); else - bgPixmap.invalidate (); + bg_invalidate (); } #endif } @@ -1480,22 +1494,13 @@ 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 (ev.xselectionclear.selection == xa[XA_CLIPBOARD]); break; - case SelectionNotify: - if (selection_wait == Sel_normal) - selection_paste (ev.xselection.requestor, ev.xselection.property, true); - break; - case SelectionRequest: selection_send (ev.xselectionrequest); break; @@ -1514,7 +1519,7 @@ * We should render background PRIOR to drawing any text, but AFTER all * of ConfigureNotifys for the best results. */ - if (bgPixmap.flags & bgPixmap_t::isInvalid) + if (!(bg_flags & BG_IS_VALID)) update_background_ev.start (0.025); #endif mapped = 1; @@ -1539,7 +1544,7 @@ do { scr_expose (ev.xexpose.x, ev.xexpose.y, - ev.xexpose.width, ev.xexpose.height, False); + ev.xexpose.width, ev.xexpose.height, false); } while (XCheckTypedWindowEvent (dpy, vt, ev.xany.type, &ev)); @@ -1548,7 +1553,7 @@ while (XCheckTypedWindowEvent (dpy, vt, ev.xany.type, &ev)) { scr_expose (ev.xexpose.x, ev.xexpose.y, - ev.xexpose.width, ev.xexpose.height, False); + ev.xexpose.width, ev.xexpose.height, false); } want_refresh = 1; @@ -1718,10 +1723,10 @@ if (enable == urgency_hint) return; - if (XWMHints *h = XGetWMHints (dpy, parent[0])) + if (XWMHints *h = XGetWMHints (dpy, parent)) { h->flags = h->flags & ~XUrgencyHint | (enable ? XUrgencyHint : 0); - XSetWMHints (dpy, parent[0], h); + XSetWMHints (dpy, parent, h); urgency_hint = enable; } } @@ -1839,7 +1844,7 @@ if (ev.xproperty.atom == xa[XA_XROOTPMAP_ID] || ev.xproperty.atom == xa[XA_ESETROOT_PMAP_ID]) { - bgPixmap.set_root_pixmap (); + bg_set_root_pixmap (); update_background (); } @@ -2682,13 +2687,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, 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 */ @@ -2761,13 +2768,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, */ @@ -2866,10 +2873,10 @@ scr_soft_reset (); static const int pm_h[] = { 7, 25 }; - static const int pm_l[] = { 1, 3, 4, 5, 6, 9, 66, 1000, 1001, 1049 }; + 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); + process_terminal_mode ('h', 0, ARRAY_LENGTH(pm_h), pm_h); + process_terminal_mode ('l', 0, ARRAY_LENGTH(pm_l), pm_l); } break; } @@ -3117,22 +3124,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); @@ -3153,18 +3160,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) */ @@ -3176,7 +3183,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); } @@ -3184,7 +3191,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); } @@ -3348,7 +3355,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 @@ -3370,7 +3377,7 @@ set_utf8_property (display->atom (str), eq + 1); } else - XDeleteProperty (dpy, parent[0], + XDeleteProperty (dpy, parent, display->atom (str)); } break; @@ -3441,9 +3448,7 @@ bool changed = false; if (ISSET_PIXCOLOR (Color_tint)) - changed = bgPixmap.set_tint (pix_colors_focused [Color_tint]); - else - changed = bgPixmap.unset_tint (); + changed = bg_set_tint (pix_colors_focused [Color_tint]); if (changed) update_background (); @@ -3459,8 +3464,8 @@ char str[256]; 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)); + min (h_scale, 32767), min (v_scale, 32767), + min (h_align, 32767), min (v_align, 32767)); process_xterm_seq (XTerm_title, str, CHAR_ST); } else @@ -3469,30 +3474,30 @@ if (*str != ';') { - if (bgPixmap.set_file (str)) /* change pixmap */ + if (bg_set_file (str)) /* change pixmap */ { changed++; str = strchr (str, ';'); if (str == NULL) - bgPixmap.set_defaultGeometry (); + bg_set_default_geometry (); else - bgPixmap.set_geometry (str+1); + bg_set_geometry (str+1); } } else { str++; - if (bgPixmap.set_geometry (str, true)) + if (bg_set_geometry (str, true)) changed++; } if (changed) { - if (bgPixmap.window_position_sensitive ()) + if (bg_window_position_sensitive ()) { int x, y; get_window_origin (x, y); - bgPixmap.set_position (x, y); + bg_set_position (x, y); } update_background (); } @@ -3656,13 +3661,19 @@ { 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 }, @@ -3682,7 +3693,7 @@ state = -1; /* basic handling */ - for (j = 0; j < (sizeof (argtopriv)/sizeof (argtopriv[0])); j++) + for (j = 0; j < ARRAY_LENGTH(argtopriv); j++) if (argtopriv[j].argval == arg[i]) { state = privcases (mode, argtopriv[j].bit); @@ -3770,6 +3781,7 @@ { 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 @@ -3964,25 +3976,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 != ':'); -} -/*}}} */ - /* ------------------------------------------------------------------------- */ /* @@ -4005,7 +3998,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) @@ -4020,14 +4013,16 @@ { 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;