*** empty log message ***
[dana/urxvt.git] / src / command.C
index 27fe1e2..338e812 100644 (file)
@@ -1,5 +1,5 @@
 /*--------------------------------*-C-*---------------------------------*
- * File:       command.c
+ * File:       command.C
  *----------------------------------------------------------------------*
  *
  * All portions of code are copyright by their respective author/s.
 // exception thrown when the command parser runs out of input data
 class out_of_input { } out_of_input;
 
+#if ENABLE_FRILLS || ISO_14755
+
+#define ISO_14755_STARTED      0x80000000UL
+#define ISO_14755_51           0x40000000UL // basic (section 5.1)
+#define ISO_14755_52           0x20000000UL // keycap (section 5.2)
+#define ISO_14755_54           0x10000000UL // code feedback (section 5.4)
+#define ISO_14755_MASK         0x0fffffffUL
+
+#if ISO_14755
+static unsigned short iso14755_symtab[] = {
+  // keysym,           unicode
+  XK_Left,             0x2190,
+  XK_KP_Left,          0x2190,
+  XK_Up,               0x2191,
+  XK_KP_Up,            0x2191,
+  XK_Right,            0x2192,
+  XK_KP_Right,         0x2192,
+  XK_Down,             0x2193,
+  XK_KP_Down,          0x2193,
+  XK_Linefeed,         0x21b4,
+  XK_Return,           0x21b5,
+  XK_KP_Enter,         0x21b5,
+
+  XK_Prior,            0x21de,
+  XK_Next,             0x21df,
+  XK_Tab,              0x21e5,
+  XK_ISO_Left_Tab,     0x21e6,
+  XK_Shift_L,          0x21e7,
+  XK_Shift_R,          0x21e7,
+
+  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,
+  XK_ISO_Level3_Lock,  0x21ef,
+  XK_ISO_Group_Lock,   0x21f0,
+  XK_Home,             0x21f1,
+  XK_End,              0x21f2,
+
+  XK_Execute,          0x2318,
+  XK_Begin,            0x2320,
+  XK_Delete,           0x2326,
+  XK_Clear,            0x2327,
+  XK_BackSpace,                0x232b,
+  XK_Insert,           0x2380,
+  XK_Control_L,                0x2388,
+  XK_Control_R,                0x2388,
+  XK_Pause,            0x2389,
+  XK_Break,            0x238a,
+  XK_Escape,           0x238b,
+  XK_Undo,             0x238c,
+  XK_Print,            0x2399,
+
+  XK_space,            0x2423,
+  XK_KP_Space,         0x2422,
+  0,
+};
+
+void
+rxvt_term::iso14755_54 (int x, int y)
+{
+  x = Pixel2Col (x);
+  y = Pixel2Row (y);
+
+  if (x < 0 || x >= TermWin.ncol
+      || y < 0 || y >= TermWin.nrow)
+    return;
+
+  for (;;)
+    {
+      text_t t = screen.text[y + TermWin.saveLines - TermWin.view_start][x];
+
+      if (t != NOCHAR || !x)
+        {
+          iso14755_51 (screen.text[y + TermWin.saveLines - TermWin.view_start][x],
+                       screen.rend[y + TermWin.saveLines - TermWin.view_start][x]);
+          iso14755buf = ISO_14755_54;
+          break;
+        }
+
+      x--;
+    }
+
+}
+#endif
+
+#if ENABLE_OVERLAY
+void
+rxvt_term::iso14755_51 (unicode_t ch, rend_t r)
+{
+  rxvt_fontset *fs = FONTSET (r);
+  rxvt_font *f = (*fs)[fs->find_font (ch)];
+  wchar_t *chr, *alloc, ch2;
+  int len;
+
+#if ENABLE_COMBINING
+  if (IS_COMPOSE (ch))
+    {
+      len = rxvt_composite.expand (ch, 0);
+      alloc = chr = new wchar_t[len];
+      rxvt_composite.expand (ch, chr);
+    }
+  else
+#endif
+    {
+      ch2 = ch;
+
+      alloc = 0;
+      chr = &ch2;
+      len = 1;
+    }
+
+  int width = strlen (f->name);
+
+  scr_overlay_new (0, -1, width < 8+5 ? 8+5 : width, len + 1);
+
+  r = SET_STYLE (OVERLAY_RSTYLE, GET_STYLE (r));
+
+  for (int y = 0; y < len; y++)
+    {
+      char buf[9];
+
+      ch = *chr++;
+
+      sprintf (buf, "%8x", ch);
+      scr_overlay_set (0, y, buf);
+      scr_overlay_set (9, y, '=');
+#if !UNICODE3
+      if (ch >= 0x10000)
+        ch = 0xfffd;
+#endif
+      scr_overlay_set (11, y, ch, r);
+      scr_overlay_set (12, y, NOCHAR, r);
+    }
+
+  scr_overlay_set (0, len, f->name);
+
+#if ENABLE_COMBINING
+  if (alloc)
+    delete [] alloc;
+#endif
+}
+#endif
+
+void
+rxvt_term::commit_iso14755 ()
+{
+  wchar_t ch[2];
+
+  ch[0] = iso14755buf & ISO_14755_MASK;
+  ch[1] = 0;
+
+  if (iso14755buf & ISO_14755_51)
+    {
+      char mb[16];
+      int len;
+
+      // allow verbatim 0-bytes and control-bytes to be entered
+      if (ch[0] >= 0x20)
+        len = wcstombs (mb, ch, 16);
+      else
+        {
+          mb[0] = ch[0];
+          len = 1;
+        }
+
+      if (len > 0)
+        tt_write ((unsigned char *)mb, len);
+      else
+        scr_bell ();
+    }
+
+  iso14755buf = 0;
+}
+
+int
+rxvt_term::hex_keyval (XKeyEvent &ev)
+{
+  // check wether this event corresponds to a hex digit
+  // if the modifiers had not been pressed.
+  for (int index = 0; index < 8; index++)
+    {
+      KeySym k = XLookupKeysym (&ev, index);
+
+      if (k >= XK_KP_0 && k <= XK_KP_9) return k - XK_KP_0;
+      else if (k >= XK_0 && k <= XK_9)  return k - XK_0;
+      else if (k >= XK_a && k <= XK_f)  return k - XK_a + 10;
+      else if (k >= XK_A && k <= XK_F)  return k - XK_A + 10;
+    }
+
+  return -1;
+}
+#endif
+
 /*{{{ Convert the keypress event into a string */
 void
 rxvt_term::lookup_key (XKeyEvent &ev)
@@ -153,11 +349,10 @@ rxvt_term::lookup_key (XKeyEvent &ev)
         {
 #ifdef UNSHIFTED_SCROLLKEYS
           if (!ctrl && !meta)
-            {
 #else
           if (IS_SCROLL_MOD)
-            {
 #endif
+            {
               int lnsppg;
 
 #ifdef PAGING_CONTEXT_LINES
@@ -216,7 +411,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
               keysym += (XK_F11 - XK_F1);
               shft = 0;        /* turn off Shift */
             }
-          else if (!ctrl && !meta && (PrivateModes & PrivMode_ShiftKeys))
+          else if (!ctrl && !meta && (priv_modes & PrivMode_ShiftKeys))
             {
               switch (keysym)
                 {
@@ -224,6 +419,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                   case XK_Insert:      /* Shift+Insert = paste mouse selection */
                     selection_request (ev.time, 0, 0);
                     return;
+#if TODO // TODO
                     /* rxvt extras */
                   case XK_KP_Add:      /* Shift+KP_Add = bigger font */
                     change_font (FONT_UP);
@@ -231,9 +427,57 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                   case XK_KP_Subtract: /* Shift+KP_Subtract = smaller font */
                     change_font (FONT_DN);
                     return;
+#endif
                 }
             }
         }
+
+#if ENABLE_FRILLS || ISO_14755
+      // ISO 14755 support
+      if (shft && ctrl)
+        {
+          int hv;
+
+          if (iso14755buf & ISO_14755_51
+              && (keysym == XK_space || keysym == XK_KP_Space
+                  || keysym == XK_Return || keysym == XK_KP_Enter))
+            {
+              commit_iso14755 ();
+              iso14755buf = ISO_14755_51;
+# if ISO_14755
+              iso14755_51 (0);
+# endif
+              return;
+            }
+          else if ((hv = hex_keyval (ev)) >= 0)
+            {
+              iso14755buf = ((iso14755buf << 4) & ISO_14755_MASK)
+                          | hv | ISO_14755_51;
+# if ISO_14755
+              iso14755_51 (iso14755buf & ISO_14755_MASK);
+# endif
+              return;
+            }
+          else
+            {
+# if ENABLE_OVERLAY
+              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)))
+        if (!(iso14755buf & ISO_14755_STARTED))
+          {
+            iso14755buf |= ISO_14755_STARTED;
+# if ENABLE_OVERLAY
+            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)
         {
@@ -275,24 +519,24 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                 {
 #ifndef NO_BACKSPACE_KEY
                   case XK_BackSpace:
-                    if (PrivateModes & PrivMode_HaveBackSpace)
+                    if (priv_modes & PrivMode_HaveBackSpace)
                       {
-                        kbuf[0] = (!! (PrivateModes & PrivMode_BackSpace)
+                        kbuf[0] = (!! (priv_modes & PrivMode_BackSpace)
                                    ^ !!ctrl) ? '\b' : '\177';
                         kbuf[1] = '\0';
                       }
                     else
-                      STRCPY (kbuf, key_backspace);
+                      strcpy (kbuf, key_backspace);
                     break;
 #endif
 #ifndef NO_DELETE_KEY
                   case XK_Delete:
-                    STRCPY (kbuf, key_delete);
+                    strcpy (kbuf, key_delete);
                     break;
 #endif
                   case XK_Tab:
                     if (shft)
-                      STRCPY (kbuf, "\033[Z");
+                      strcpy (kbuf, "\033[Z");
                     else
                       {
 #ifdef CTRL_TAB_MAKES_META
@@ -308,13 +552,13 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                     break;
 
 #ifdef XK_KP_Left
-                  case XK_KP_Up:               /* \033Ox or standard */
+                  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 ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033OZ");
+                        strcpy (kbuf, "\033OZ");
                         kbuf[2] = "txvr"[keysym - XK_KP_Left];
                         break;
                       }
@@ -327,7 +571,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                   case XK_Down:        /* "\033[B" */
                   case XK_Right:       /* "\033[C" */
                   case XK_Left:        /* "\033[D" */
-                    STRCPY (kbuf, "\033[Z");
+                    strcpy (kbuf, "\033[Z");
                     kbuf[2] = "DACB"[keysym - XK_Left];
                     /* do Shift first */
                     if (shft)
@@ -337,7 +581,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                         kbuf[1] = 'O';
                         kbuf[2] = "dacb"[keysym - XK_Left];
                       }
-                    else if (PrivateModes & PrivMode_aplCUR)
+                    else if (priv_modes & PrivMode_aplCUR)
                       kbuf[1] = 'O';
                     break;
 
@@ -345,61 +589,72 @@ rxvt_term::lookup_key (XKeyEvent &ev)
 # ifdef XK_KP_Prior
                   case XK_KP_Prior:
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033Oy");
+                        strcpy (kbuf, "\033Oy");
                         break;
                       }
                     /* FALLTHROUGH */
 # endif
                   case XK_Prior:
-                    STRCPY (kbuf, "\033[5~");
+                    strcpy (kbuf, "\033[5~");
                     break;
 # ifdef XK_KP_Next
                   case XK_KP_Next:
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033Os");
+                        strcpy (kbuf, "\033Os");
                         break;
                       }
                     /* FALLTHROUGH */
 # endif
                   case XK_Next:
-                    STRCPY (kbuf, "\033[6~");
+                    strcpy (kbuf, "\033[6~");
                     break;
 #endif
                   case XK_KP_Enter:
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
+                      {
+                        strcpy (kbuf, "\033OM");
+                        break;
+                      }
+
+                    /* FALLTHROUGH */
+
+                  case XK_Return:
+                    if (priv_modes & PrivMode_LFNL)
                       {
-                        STRCPY (kbuf, "\033OM");
+                        kbuf[0] = '\015';
+                        kbuf[1] = '\012';
+                        kbuf[2] = '\0';
                       }
                     else
                       {
-                        kbuf[0] = '\r';
+                        kbuf[0] = '\015';
                         kbuf[1] = '\0';
                       }
                     break;
 
 #ifdef XK_KP_Begin
                   case XK_KP_Begin:
-                    STRCPY (kbuf, "\033Ou");
+                    strcpy (kbuf, "\033Ou");
                     break;
 
                   case XK_KP_Insert:
-                    STRCPY (kbuf, "\033Op");
+                    strcpy (kbuf, "\033Op");
                     break;
 
                   case XK_KP_Delete:
-                    STRCPY (kbuf, "\033On");
+                    strcpy (kbuf, "\033On");
                     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");
+                    strcpy (kbuf, "\033OP");
                     kbuf[2] += (keysym - XK_KP_F1);
                     break;
 
@@ -420,9 +675,9 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                   case XK_KP_8:                /* "\033Ox" : "8" */
                   case XK_KP_9:                /* "\033Oy" : "9" */
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033Oj");
+                        strcpy (kbuf, "\033Oj");
                         kbuf[2] += (keysym - XK_KP_Multiply);
                       }
                     else
@@ -433,46 +688,46 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                     break;
 
                   case XK_Find:
-                    STRCPY (kbuf, "\033[1~");
+                    strcpy (kbuf, "\033[1~");
                     break;
                   case XK_Insert:
-                    STRCPY (kbuf, "\033[2~");
+                    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~");
+                    strcpy (kbuf, "\033[3~");
                     break;
                   case XK_Select:
-                    STRCPY (kbuf, "\033[4~");
+                    strcpy (kbuf, "\033[4~");
                     break;
 #ifdef XK_KP_End
                   case XK_KP_End:
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033Oq");
+                        strcpy (kbuf, "\033Oq");
                         break;
                       }
                     /* FALLTHROUGH */
 #endif
                   case XK_End:
-                    STRCPY (kbuf, KS_END);
+                    strcpy (kbuf, KS_END);
                     break;
 #ifdef XK_KP_Home
                   case XK_KP_Home:
                     /* allow shift to override */
-                    if ((PrivateModes & PrivMode_aplKP) ? !shft : shft)
+                    if ((priv_modes & PrivMode_aplKP) ? !shft : shft)
                       {
-                        STRCPY (kbuf, "\033Ow");
+                        strcpy (kbuf, "\033Ow");
                         break;
                       }
                     /* FALLTHROUGH */
 #endif
                   case XK_Home:
-                    STRCPY (kbuf, KS_HOME);
+                    strcpy (kbuf, KS_HOME);
                     break;
 
 #define FKEY(n, fkey)                                                  \
@@ -535,7 +790,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
                     break;
                 }
               if (newlen)
-                len = STRLEN (kbuf);
+                len = strlen (kbuf);
             }
 
           /*
@@ -573,7 +828,7 @@ rxvt_term::lookup_key (XKeyEvent &ev)
   if (len <= 0)
     return;                    /* not mapped */
 
-  if (Options & Opt_scrollTtyKeypress)
+  if (options & Opt_scrollTtyKeypress)
     if (TermWin.view_start)
       {
         TermWin.view_start = 0;
@@ -632,7 +887,7 @@ rxvt_term::cmd_write (const unsigned char *str, unsigned int count)
 
   if (n > 0 && s < count)
     {
-      MEMMOVE (cmdbuf_base, cmdbuf_ptr,
+      memmove (cmdbuf_base, cmdbuf_ptr,
               (unsigned int) (cmdbuf_endp - cmdbuf_ptr));
       cmdbuf_ptr = cmdbuf_base;
       cmdbuf_endp -= n;
@@ -663,7 +918,6 @@ rxvt_term::flush ()
       want_full_refresh = 0;
       scr_clear ();
       scr_touch (false);
-      want_refresh = 1;
     }
 #endif
 
@@ -674,10 +928,11 @@ rxvt_term::flush ()
 #ifdef USE_XIM
       IMSendSpot ();
 #endif
-
     }
 
   display->flush ();
+
+  flush_ev.stop ();
 }
 
 void
@@ -686,6 +941,20 @@ rxvt_term::check_cb (check_watcher &w)
   SET_R (this);
   SET_LOCALE (locale);
 
+  display->flush ();
+
+  if (want_refresh && !flush_ev.active)
+    flush_ev.start (NOW + 0.01);
+}
+
+void
+rxvt_term::flush_cb (time_watcher &w)
+{
+  SET_R (this);
+  SET_LOCALE (locale);
+
+  refresh_limit = 1;
+  refresh_count = 0;
   flush ();
 }
 
@@ -713,16 +982,65 @@ rxvt_term::text_blink_cb (time_watcher &w)
 }
 #endif
 
+#ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING
+void
+rxvt_term::cont_scroll_cb (time_watcher &w)
+{
+  if ((scrollbar_isUp() || scrollbar_isDn()) &&
+      scr_page (scrollbar_isUp() ? UP : DN, 1))
+    {
+      refresh_type |= SMOOTH_REFRESH;
+      want_refresh = 1;
+      w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY);
+    }
+}
+#endif
+
+#ifdef SELECTION_SCROLLING
+void
+rxvt_term::sel_scroll_cb (time_watcher &w)
+{
+  if (scr_page (scroll_selection_dir, scroll_selection_lines))
+    {
+      selection_extend (selection_save_x, selection_save_y, selection_save_state);
+      refresh_type |= SMOOTH_REFRESH;
+      want_refresh = 1;
+      w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY);
+    }
+}
+#endif
+
+#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
+void
+rxvt_term::slip_wheel_cb (time_watcher &w)
+{
+  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))
+    {
+      refresh_type |= SMOOTH_REFRESH;
+      want_refresh = 1;
+      w.start (w.at + SCROLLBAR_CONTINUOUS_DELAY);
+    }
+}
+#endif
+
 bool
 rxvt_term::pty_fill ()
 {
   ssize_t n = cmdbuf_endp - cmdbuf_ptr;
 
+  if (CBUFSIZ == n)
+    {
+      rxvt_warn ("pty_fill on full buffer, draining input, continuing.\n");
+      n = 0;
+    }
+
   memmove (cmdbuf_base, cmdbuf_ptr, n);
   cmdbuf_ptr = cmdbuf_base;
   cmdbuf_endp = cmdbuf_ptr + n;
 
-  n = read (cmd_fd, cmdbuf_endp, CBUFSIZ - n);
+  n = read (pty.pty, cmdbuf_endp, CBUFSIZ - n);
 
   if (n > 0)
     {
@@ -744,42 +1062,31 @@ rxvt_term::pty_cb (io_watcher &w, short revents)
   if (revents & EVENT_WRITE)
     tt_write (0, 0);
   else if (revents & EVENT_READ)
-    {
-      // loop, but don't allow a single term to monopolize us
-      // the number of loops is fully arbitrary, and thus wrong
-      while (pty_fill ())
-        {
-          if (!seen_input)
-            {
-              seen_input = 1;
-              /* once we know the shell is running, send the screen size.  Again! */
-              // I don't know why, btw.
-              tt_winch ();
-            }
-
-          if (cmd_parse ())
-            break;
-        }
-    }
+    // loop, but don't allow a single term to monopolize us
+    while (pty_fill ())
+      if (cmd_parse ())
+        break;
 }
 
-#ifdef POINTER_BLANK
 void
 rxvt_term::pointer_unblank ()
 {
   XDefineCursor (display->display, TermWin.vt, TermWin_cursor);
   recolour_cursor ();
 
+#ifdef POINTER_BLANK
   hidden_pointer = 0;
 
-  if (Options & Opt_pointerBlank)
+  if (options & Opt_pointerBlank)
     pointer_ev.start (NOW + pointerBlankDelay);
+#endif
 }
 
+#ifdef POINTER_BLANK
 void
 rxvt_term::pointer_blank ()
 {
-  if (! (Options & Opt_pointerBlank))
+  if (! (options & Opt_pointerBlank))
     return;
 
   XDefineCursor (display->display, TermWin.vt, blank_cursor);
@@ -809,9 +1116,7 @@ rxvt_term::mouse_report (XButtonEvent &ev)
   pixel_position (&x, &y);
 
   if (MEvent.button == AnyButton)
-    {
-      button_number = 3;
-    }
+    button_number = 3;
   else
     {
       button_number = MEvent.button - Button1;
@@ -820,7 +1125,7 @@ rxvt_term::mouse_report (XButtonEvent &ev)
         button_number += (64 - 3);
     }
 
-  if (PrivateModes & PrivMode_MouseX10)
+  if (priv_modes & PrivMode_MouseX10)
     {
       /*
        * do not report ButtonRelease
@@ -845,10 +1150,9 @@ rxvt_term::mouse_report (XButtonEvent &ev)
 #ifdef MOUSE_REPORT_DOUBLECLICK
       key_state += ((MEvent.clicks > 1) ? 32 : 0);
 #endif
-
     }
 
-#ifdef DEBUG_MOUSEREPORT
+#if DEBUG_MOUSEREPORT
   fprintf (stderr, "Mouse [");
   if (key_state & 16)
     fputc ('C', stderr);
@@ -862,12 +1166,12 @@ rxvt_term::mouse_report (XButtonEvent &ev)
           button_number,
           x + 1,
           y + 1);
-#else
+#endif
+
   tt_printf ("\033[M%c%c%c",
             (32 + button_number + key_state),
             (32 + x + 1),
             (32 + y + 1));
-#endif
 }
 
 #ifdef USING_W11LIB
@@ -888,7 +1192,7 @@ rxvt_term::x_cb (XEvent &ev)
   SET_LOCALE (locale);
 
 #if defined(CURSOR_BLINK)
-  if ((Options & Opt_cursorBlink) && ev.type == KeyPress)
+  if ((options & Opt_cursorBlink) && ev.type == KeyPress)
     {
       if (hidden_cursor)
         {
@@ -901,7 +1205,7 @@ rxvt_term::x_cb (XEvent &ev)
 #endif
 
 #if defined(POINTER_BLANK)
-  if ((Options & Opt_pointerBlank) && pointerBlankDelay > 0)
+  if ((options & Opt_pointerBlank) && pointerBlankDelay > 0)
     {
       if (ev.type == MotionNotify
           || ev.type == ButtonPress
@@ -923,77 +1227,86 @@ rxvt_term::x_cb (XEvent &ev)
   int             unused_root_x, unused_root_y;
   unsigned int    unused_mask;
 
-#ifdef DEBUG_X
-  const char *const eventnames[] =
-    {                          /* mason - this matches my system */
-      "",
-      "",
-      "KeyPress",
-      "KeyRelease",
-      "ButtonPress",
-      "ButtonRelease",
-      "MotionNotify",
-      "EnterNotify",
-      "LeaveNotify",
-      "FocusIn",
-      "FocusOut",
-      "KeymapNotify",
-      "Expose",
-      "GraphicsExpose",
-      "NoExpose",
-      "VisibilityNotify",
-      "CreateNotify",
-      "DestroyNotify",
-      "UnmapNotify",
-      "MapNotify",
-      "MapRequest",
-      "ReparentNotify",
-      "ConfigureNotify",
-      "ConfigureRequest",
-      "GravityNotify",
-      "ResizeRequest",
-      "CirculateNotify",
-      "CirculateRequest",
-      "PropertyNotify",
-      "SelectionClear",
-      "SelectionRequest",
-      "SelectionNotify",
-      "ColormapNotify",
-      "ClientMessage",
-      "MappingNotify"
-    };
-#endif
-
-#ifdef DEBUG_X
-  struct timeval  tp;
-  struct tm      *ltt;
-  (void)gettimeofday (&tp, NULL);
-  ltt = localtime (& (tp.tv_sec));
-  D_X ((stderr, "Event: %-16s %-7s %08lx (%4d-%02d-%02d %02d:%02d:%02d.%.6ld) %s %lu", eventnames[ev.type], (ev.xany.window == TermWin.parent[0] ? "parent" : (ev.xany.window == TermWin.vt ? "vt" : (ev.xany.window == scrollBar.win ? "scroll" : (ev.xany.window == menuBar.win ? "menubar" : "UNKNOWN")))), (ev.xany.window == TermWin.parent[0] ? TermWin.parent[0] : (ev.xany.window == TermWin.vt ? TermWin.vt : (ev.xany.window == scrollBar.win ? scrollBar.win : (ev.xany.window == menuBar.win ? menuBar.win : 0)))), ltt->tm_year + 1900, ltt->tm_mon + 1, ltt->tm_mday, ltt->tm_hour, ltt->tm_min, ltt->tm_sec, tp.tv_usec, ev.xany.send_event ? "S" : " ", ev.xany.serial));
-#endif
-
   switch (ev.type)
     {
       case KeyPress:
-        lookup_key (ev.xkey);
+#if ISO_14755
+        if (!(iso14755buf & ISO_14755_52))
+#endif
+          lookup_key (ev.xkey);
+
         break;
 
-#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
       case KeyRelease:
         {
-          if (! (ev.xkey.state & ControlMask))
-            mouse_slip_wheel_speed = 0;
-          else
-            {
-              KeySym          ks;
+#if (MOUSE_WHEEL && MOUSE_SLIP_WHEELING) || ISO_14755
+          KeySym ks;
 
-              ks = XKeycodeToKeysym (display->display, ev.xkey.keycode, 0);
-              if (ks == XK_Control_L || ks == XK_Control_R)
-                mouse_slip_wheel_speed = 0;
-            }
+          ks = XLookupKeysym (&ev.xkey, ev.xkey.state & ShiftMask ? 1 : 0); // sorry, only shift supported :/
+#endif
+
+#if ENABLE_FRILLS || ISO_14755
+          // ISO 14755 support
+          if (iso14755buf)
+            if (iso14755buf & ISO_14755_52)
+              {
+# if ENABLE_OVERLAY
+                scr_overlay_off ();
+# endif
+# if ISO_14755
+                // iso14755 part 5.2 handling: release time
+                // first: controls
+                if ((ev.xkey.state & ControlMask)
+                     && ((ks >= 0x40 && ks <= 0x5f)
+                         || (ks >= 0x61 && ks <= 0x7f)))
+                  {
+                    iso14755buf = ISO_14755_51 | 0x2400 | (ks & 0x1f);
+                    commit_iso14755 ();
+                    return; // case-break;
+                  }
+
+                for (unsigned short *i = iso14755_symtab; i[0]; i+= 2)
+                  if (i[0] == ks)
+                    {
+                      iso14755buf = ISO_14755_51 | i[1];
+                      commit_iso14755 ();
+                      return; // case-break;
+                    }
+
+                scr_bell ();
+# endif
+                iso14755buf = 0;
+                break;
+              }
+            else if ((ev.xkey.state & (ShiftMask | ControlMask)) != (ShiftMask | ControlMask))
+              {
+# if ENABLE_OVERLAY
+                scr_overlay_off ();
+# endif
+                if (iso14755buf & ISO_14755_51)
+                  commit_iso14755 ();
+#if ISO_14755
+                else if (iso14755buf & ISO_14755_STARTED)
+                  {
+                    iso14755buf = ISO_14755_52; // iso14755 part 5.2: remember empty begin/end pair
+
+                    scr_overlay_new (0, -1, sizeof ("KEYCAP PICTURE INSERT MODE") - 1, 1);
+                    scr_overlay_set (0, 0, "KEYCAP PICTURE INSERT MODE");
+                  }
+# endif
+                else
+                  iso14755buf = 0;
+              }
+#endif
+
+#if defined(MOUSE_WHEEL) && defined(MOUSE_SLIP_WHEELING)
+          if (!(ev.xkey.state & ControlMask))
+            slip_wheel_ev.stop ();
+          else if (ks == XK_Control_L || ks == XK_Control_R)
+            mouse_slip_wheel_speed = 0;
+#endif
           break;
         }
-#endif
 
       case ButtonPress:
         button_press (ev.xbutton);
@@ -1015,10 +1328,10 @@ rxvt_term::x_cb (XEvent &ev)
                      || ev.xclient.data.l[0] == DndLink))
           {
             /* Get Dnd data */
-            Atom            ActualType;
-            int             ActualFormat;
-            unsigned char  *data;
-            unsigned long   Size, RemainingBytes;
+            Atom ActualType;
+            int ActualFormat;
+            unsigned char *data;
+            unsigned long Size, RemainingBytes;
 
             XGetWindowProperty (display->display, display->root,
                                xa[XA_DNDSELECTION],
@@ -1030,7 +1343,8 @@ rxvt_term::x_cb (XEvent &ev)
             XChangeProperty (display->display, display->root,
                             XA_CUT_BUFFER0, XA_STRING,
                             8, PropModeReplace,
-                            data, STRLEN (data));
+                            data, strlen (data));
+            XFree (data);
             selection_paste (display->root, XA_CUT_BUFFER0, True);
             XSetInputFocus (display->display, display->root, RevertToNone, CurrentTime);
           }
@@ -1038,7 +1352,7 @@ rxvt_term::x_cb (XEvent &ev)
         break;
 
       case MappingNotify:
-        XRefreshKeyboardMapping (& (ev.xmapping));
+        XRefreshKeyboardMapping (&ev.xmapping);
         break;
 
         /*
@@ -1073,12 +1387,22 @@ rxvt_term::x_cb (XEvent &ev)
             want_refresh = 1;
 #ifdef USE_XIM
             if (Input_Context != NULL)
-              XSetICFocus (Input_Context);
+              {
+                IMSetStatusPosition ();
+                XSetICFocus (Input_Context);
+              }
 #endif
 #ifdef CURSOR_BLINK
-            if (Options & Opt_cursorBlink)
+            if (options & Opt_cursorBlink)
               cursor_blink_ev.start (NOW + BLINK_INTERVAL);
 #endif
+#ifdef OFF_FOCUS_FADING
+            if (rs[Rs_fade])
+              {
+                pix_colors = pix_colors_focused;
+                scr_recolour ();
+              }
+#endif
 
           }
         break;
@@ -1088,16 +1412,29 @@ rxvt_term::x_cb (XEvent &ev)
           {
             TermWin.focus = 0;
             want_refresh = 1;
+
+#if ENABLE_FRILLS || ISO_14755
+            iso14755buf = 0;
+#endif
+#if ENABLE_OVERLAY
+            scr_overlay_off ();
+#endif
 #ifdef USE_XIM
             if (Input_Context != NULL)
               XUnsetICFocus (Input_Context);
 #endif
 #ifdef CURSOR_BLINK
-            if (Options & Opt_cursorBlink)
+            if (options & Opt_cursorBlink)
               cursor_blink_ev.stop ();
             hidden_cursor = 0;
 #endif
-
+#ifdef OFF_FOCUS_FADING
+            if (rs[Rs_fade])
+              {
+                pix_colors = pix_colors_unfocused;
+                scr_recolour ();
+              }
+#endif
           }
         break;
 
@@ -1116,27 +1453,28 @@ rxvt_term::x_cb (XEvent &ev)
 
             if (szHint.width != width || szHint.height != height)
               {
-                D_SIZE ((stderr, "Size: Resizing from: %4d x %4d", szHint.width, szHint.height));
+                seen_resize = 1;
                 resize_all_windows (width, height, 1);
               }
-#ifdef DEBUG_SIZE
-            else
-              {
-                D_SIZE ((stderr, "Size: Not resizing"));
-              }
-#endif
+
 #ifdef TRANSPARENT             /* XXX: maybe not needed - leave in for now */
-            if (Options & Opt_transparent)
+            if (options & Opt_transparent)
               {
                 check_our_parents ();
                 if (am_transparent)
-                  want_full_refresh = 1;
+                  want_refresh = want_full_refresh = 1;
               }
 #endif
-
           }
         break;
 
+      case PropertyNotify:
+        if (ev.xproperty.atom == xa[XA_VT_SELECTION]
+            && ev.xproperty.state == PropertyNewValue)
+          selection_property (ev.xproperty.window, ev.xproperty.atom);
+
+        break;
+
       case SelectionClear:
         selection_clear ();
         break;
@@ -1175,28 +1513,28 @@ rxvt_term::x_cb (XEvent &ev)
       case Expose:
         if (ev.xany.window == TermWin.vt)
           {
-#ifdef NO_SLOW_LINK_SUPPORT
-            scr_expose (ev.xexpose.x, ev.xexpose.y,
-                        ev.xexpose.width, ev.xexpose.height, False);
-#else
-            // don't understand this, so commented it out
-            scr_expose (ev.xexpose.x, ev.xexpose.y,
-                        ev.xexpose.width, ev.xexpose.height, False);
-            //scr_expose (ev.xexpose.x, 0,
-            //             ev.xexpose.width, TermWin.height, False);
-#endif
-            want_refresh = 1;
+            do
+              scr_expose (ev.xexpose.x, ev.xexpose.y,
+                          ev.xexpose.width, ev.xexpose.height, False);
+            while (XCheckTypedWindowEvent (display->display, TermWin.vt, ev.xany.type, &ev));
+
+            ev.xany.type = ev.xany.type == Expose ? GraphicsExpose : Expose;
+
+            while (XCheckTypedWindowEvent (display->display, TermWin.vt, ev.xany.type, &ev))
+              scr_expose (ev.xexpose.x, ev.xexpose.y,
+                          ev.xexpose.width, ev.xexpose.height, False);
+
+            scr_refresh (refresh_type);
           }
         else
           {
             XEvent unused_event;
 
-            while (XCheckTypedWindowEvent (display->display, ev.xany.window,
-                                          Expose,
-                                          &unused_event)) ;
-            while (XCheckTypedWindowEvent (display->display, ev.xany.window,
-                                          GraphicsExpose,
-                                          &unused_event)) ;
+            while (XCheckTypedWindowEvent (display->display, ev.xany.window, Expose, &unused_event))
+              ;
+            while (XCheckTypedWindowEvent (display->display, ev.xany.window, GraphicsExpose, &unused_event))
+              ;
+
             if (isScrollbarWindow (ev.xany.window))
               {
                 scrollBar.setIdle ();
@@ -1206,6 +1544,11 @@ rxvt_term::x_cb (XEvent &ev)
             if (menubar_visible () && isMenuBarWindow (ev.xany.window))
               menubar_expose ();
 #endif
+
+#ifdef TRANSPARENT
+            if (am_transparent && ev.xany.window == TermWin.parent[0])
+              XClearWindow (display->display, ev.xany.window);
+#endif
           }
         break;
 
@@ -1221,27 +1564,35 @@ rxvt_term::x_cb (XEvent &ev)
             break;
           }
 #endif
-        if ((PrivateModes & PrivMode_mouse_report) && ! (bypass_keystate))
+        if ((priv_modes & PrivMode_mouse_report) && ! (bypass_keystate))
           break;
 
         if (ev.xany.window == TermWin.vt)
           {
-            if ((ev.xbutton.state & (Button1Mask | Button3Mask)))
+            if (ev.xbutton.state & (Button1Mask | Button3Mask))
               {
                 while (XCheckTypedWindowEvent (display->display, TermWin.vt, MotionNotify, &ev))
                   ;
 
                 XQueryPointer (display->display, TermWin.vt,
-                              &unused_root, &unused_child,
-                              &unused_root_x, &unused_root_y,
-                              & (ev.xbutton.x), & (ev.xbutton.y),
-                              &unused_mask);
+                               &unused_root, &unused_child,
+                               &unused_root_x, &unused_root_y,
+                               & (ev.xbutton.x), & (ev.xbutton.y),
+                               &unused_mask);
 #ifdef MOUSE_THRESHOLD
                 /* deal with a `jumpy' mouse */
                 if ((ev.xmotion.time - MEvent.time) > MOUSE_THRESHOLD)
                   {
 #endif
-                    selection_extend ((ev.xbutton.x), (ev.xbutton.y),
+#if ISO_14755
+                    // 5.4
+                    if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
+                      {
+                        iso14755_54 (ev.xbutton.x, ev.xbutton.y);
+                        break;
+                      }
+#endif
+                    selection_extend (ev.xbutton.x, ev.xbutton.y,
                                       (ev.xbutton.state & Button3Mask) ? 2 : 0);
 #ifdef SELECTION_SCROLLING
                     if (ev.xbutton.y < TermWin.int_bwidth
@@ -1249,21 +1600,18 @@ rxvt_term::x_cb (XEvent &ev)
                       {
                         int dist;
 
-                        pending_scroll_selection=1;
-
                         /* don't clobber the current delay if we are
                          * already in the middle of scrolling.
                          */
-                        if (scroll_selection_delay<=0)
-                          scroll_selection_delay=SCROLLBAR_CONTINUOUS_DELAY;
+                        if (!sel_scroll_ev.active)
+                          sel_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY);
 
                         /* save the event params so we can highlight
                          * the selection in the pending-scroll loop
                          */
-                        selection_save_x=ev.xbutton.x;
-                        selection_save_y=ev.xbutton.y;
-                        selection_save_state=
-                          (ev.xbutton.state & Button3Mask) ? 2 : 0;
+                        selection_save_x = ev.xbutton.x;
+                        selection_save_y = ev.xbutton.y;
+                        selection_save_state = (ev.xbutton.state & Button3Mask) ? 2 : 0;
 
                         /* calc number of lines to scroll */
                         if (ev.xbutton.y<TermWin.int_bwidth)
@@ -1274,33 +1622,33 @@ rxvt_term::x_cb (XEvent &ev)
                         else
                           {
                             scroll_selection_dir = DN;
-                            dist = ev.xbutton.y -
-                                   (TermWin.int_bwidth + TermWin.height);
+                            dist = ev.xbutton.y - (TermWin.int_bwidth + TermWin.height);
                           }
-                        scroll_selection_lines= (Pixel2Height (dist)/
-                                                SELECTION_SCROLL_LINE_SPEEDUP)+1;
+
+                        scroll_selection_lines = Pixel2Height (dist)
+                                                 / SELECTION_SCROLL_LINE_SPEEDUP
+                                                 + 1;
                         MIN_IT (scroll_selection_lines,
-                               SELECTION_SCROLL_MAX_LINES);
+                                SELECTION_SCROLL_MAX_LINES);
                       }
                     else
                       {
                         /* we are within the text window, so we
                          * shouldn't be scrolling
                          */
-                        pending_scroll_selection = 0;
+                        if (sel_scroll_ev.active)
+                          sel_scroll_ev.stop();
                       }
 #endif
 #ifdef MOUSE_THRESHOLD
-
                   }
 #endif
-
               }
           }
         else if (isScrollbarWindow (ev.xany.window) && scrollbar_isMotion ())
           {
             while (XCheckTypedWindowEvent (display->display, scrollBar.win,
-                                          MotionNotify, &ev)) ;
+                                           MotionNotify, &ev)) ;
             XQueryPointer (display->display, scrollBar.win,
                           &unused_root, &unused_child,
                           &unused_root_x, &unused_root_y,
@@ -1316,6 +1664,7 @@ rxvt_term::x_cb (XEvent &ev)
     }
 }
 
+#if TRANSPARENT
 void
 rxvt_term::rootwin_cb (XEvent &ev)
 {
@@ -1325,35 +1674,24 @@ rxvt_term::rootwin_cb (XEvent &ev)
   switch (ev.type)
     {
       case PropertyNotify:
-        if (ev.xproperty.atom == xa[XA_VT_SELECTION])
-          {
-            if (ev.xproperty.state == PropertyNewValue)
-              selection_property (ev.xproperty.window, ev.xproperty.atom);
-            break;
-          }
-#ifdef TRANSPARENT
-        else
-          {
-            /*
-             * 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 (xa[XA_XROOTPMAPID] == 0)
-              xa[XA_XROOTPMAPID] = XInternAtom (display->display, "_XROOTPMAP_ID", False);
-
-            if (ev.xproperty.atom != xa[XA_XROOTPMAPID])
-              return;
-          }
+        /*
+         * 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 (xa[XA_XROOTPMAPID] == 0)
+          xa[XA_XROOTPMAPID] = XInternAtom (display->display, "_XROOTPMAP_ID", False);
+
+        if (ev.xproperty.atom != xa[XA_XROOTPMAPID])
+          return;
 
         /* FALLTHROUGH */
       case ReparentNotify:
-        if ((Options & Opt_transparent) && check_our_parents ())
-          if (am_transparent)
-            want_full_refresh = 1;
+        if ((options & Opt_transparent) && check_our_parents () && am_transparent)
+          want_refresh = want_full_refresh = 1;
         break;
-#endif
     }
 }
+#endif
 
 void
 rxvt_term::button_press (XButtonEvent &ev)
@@ -1362,12 +1700,22 @@ rxvt_term::button_press (XButtonEvent &ev)
 
   bypass_keystate = ev.state & (ModMetaMask | ShiftMask);
   if (!bypass_keystate)
-    reportmode = !! (PrivateModes & PrivMode_mouse_report);
+    reportmode = !! (priv_modes & PrivMode_mouse_report);
+
   /*
    * VT window processing of button press
    */
   if (ev.window == TermWin.vt)
     {
+#if ISO_14755
+      // 5.4
+      if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
+        {
+          iso14755_54 (ev.x, ev.y);
+          return;
+        }
+#endif
+
       clickintime = ev.time - MEvent.time < MULTICLICK_TIME;
       if (reportmode)
         {
@@ -1411,7 +1759,7 @@ rxvt_term::button_press (XButtonEvent &ev)
             {
               case Button1:
                 /* allow shift+left click to extend selection */
-                if (ev.state & ShiftMask && ! (PrivateModes & PrivMode_mouse_report))
+                if (ev.state & ShiftMask && ! (priv_modes & PrivMode_mouse_report))
                   {
                     if (MEvent.button == Button1 && clickintime)
                       selection_rotate (ev.x, ev.y);
@@ -1436,10 +1784,12 @@ rxvt_term::button_press (XButtonEvent &ev)
                   selection_rotate (ev.x, ev.y);
                 else
                   selection_extend (ev.x, ev.y, 1);
+
                 MEvent.button = Button3;
                 break;
             }
         }
+
       MEvent.time = ev.time;
       return;
     }
@@ -1515,7 +1865,7 @@ rxvt_term::button_press (XButtonEvent &ev)
           if (upordown)
             {
 #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING
-              scroll_arrow_delay = SCROLLBAR_INITIAL_DELAY;
+              cont_scroll_ev.start (NOW + SCROLLBAR_INITIAL_DELAY);
 #endif
               if (scr_page (upordown < 0 ? UP : DN, 1))
                 {
@@ -1541,11 +1891,12 @@ rxvt_term::button_press (XButtonEvent &ev)
                         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 ());
+                    scr_move_to (scrollbar_position (ev.y) - csrO, scrollbar_size ());
+
                   scrollBar.setMotion ();
                   break;
 
@@ -1579,6 +1930,7 @@ rxvt_term::button_press (XButtonEvent &ev)
                                  * scrollbar_position (ev.y)
                                  / scrollbar_size ()));
                     }
+
                   break;
               }
         }
@@ -1600,7 +1952,7 @@ rxvt_term::button_release (XButtonEvent &ev)
 
   csrO = 0;            /* reset csr Offset */
   if (!bypass_keystate)
-    reportmode = !! (PrivateModes & PrivMode_mouse_report);
+    reportmode = !! (priv_modes & PrivMode_mouse_report);
 
   if (scrollbar_isUpDn ())
     {
@@ -1609,13 +1961,20 @@ rxvt_term::button_release (XButtonEvent &ev)
 #ifndef NO_SCROLLBAR_BUTTON_CONTINUAL_SCROLLING
       refresh_type &= ~SMOOTH_REFRESH;
 #endif
-
     }
+
 #ifdef SELECTION_SCROLLING
-  pending_scroll_selection=0;
+  if (sel_scroll_ev.active)
+    sel_scroll_ev.stop();
 #endif
+
   if (ev.window == TermWin.vt)
     {
+#if ISO_14755
+      // 5.4
+      if (iso14755buf & (ISO_14755_STARTED | ISO_14755_54))
+        return;
+#endif
       if (reportmode)
         {
           /* mouse report from vt window */
@@ -1639,11 +1998,12 @@ rxvt_term::button_release (XButtonEvent &ev)
 #endif                         /* MOUSE_REPORT_DOUBLECLICK */
           return;
         }
+
       /*
        * dumb hack to compensate for the failure of click-and-drag
        * when overriding mouse reporting
        */
-      if (PrivateModes & PrivMode_mouse_report
+      if (priv_modes & PrivMode_mouse_report
           && bypass_keystate
           && ev.button == Button1 && MEvent.clicks <= 1)
         selection_extend (ev.x, ev.y, 0);
@@ -1664,37 +2024,48 @@ rxvt_term::button_release (XButtonEvent &ev)
               int i;
               page_dirn v;
 
-              v = (ev.button == Button4) ? UP : DN;
+              v = ev.button == Button4 ? UP : DN;
+
               if (ev.state & ShiftMask)
                 i = 1;
-              else if ((Options & Opt_mouseWheelScrollPage))
+              else if (options & Opt_mouseWheelScrollPage)
                 i = TermWin.nrow - 1;
               else
                 i = 5;
+
 # ifdef MOUSE_SLIP_WHEELING
               if (ev.state & ControlMask)
                 {
-                  mouse_slip_wheel_speed += (v ? -1 : 1);
-                  mouse_slip_wheel_delay = SCROLLBAR_CONTINUOUS_DELAY;
+                  mouse_slip_wheel_speed += v ? -1 : 1;
+                  if (mouse_slip_wheel_speed < -TermWin.nrow) mouse_slip_wheel_speed = -TermWin.nrow;
+                  if (mouse_slip_wheel_speed > +TermWin.nrow) mouse_slip_wheel_speed = +TermWin.nrow;
+
+                  if (slip_wheel_ev.at < NOW)
+                    slip_wheel_ev.at = NOW + SCROLLBAR_CONTINUOUS_DELAY;
+
+                  slip_wheel_ev.start ();
                 }
+              else
+                {
 # endif
 # ifdef JUMP_MOUSE_WHEEL
-              scr_page (v, i);
-              scr_refresh (SMOOTH_REFRESH);
-              scrollbar_show (1);
-# else
-              while (i--)
-                {
-                  scr_page (v, 1);
+                  scr_page (v, i);
                   scr_refresh (SMOOTH_REFRESH);
                   scrollbar_show (1);
-                }
+# else
+                  while (i--)
+                    {
+                      scr_page (v, 1);
+                      scr_refresh (SMOOTH_REFRESH);
+                      scrollbar_show (1);
+                    }
 # endif
-
+# ifdef MOUSE_SLIP_WHEELING
+                }
+#endif
             }
             break;
 #endif
-
         }
     }
 #ifdef MENUBAR
@@ -1703,8 +2074,238 @@ rxvt_term::button_release (XButtonEvent &ev)
 #endif
 }
 
-
 #ifdef TRANSPARENT
+#if TINTING
+/* taken from aterm-0.4.2 */
+
+typedef uint32_t RUINT32T;
+
+void ShadeXImage(rxvt_display *display, 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 = display->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_r;
+  }
+  for (i = 0; i <= mask_g>>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_g;
+  }
+  for (i = 0; i <= mask_b>>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)<<sh_b;
+  }
+
+  /* apply table to input image (replacing colors by newly calculated ones) */
+  switch (srcImage->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
@@ -1712,32 +2313,33 @@ rxvt_term::button_release (XButtonEvent &ev)
 int
 rxvt_term::check_our_parents ()
 {
-  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;
+  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;
 
   pchanged = 0;
 
-  if (! (Options & Opt_transparent))
+  if (!(options & Opt_transparent))
     return pchanged;   /* Don't try any more */
 
   XGetWindowAttributes (display->display, display->root, &wrootattr);
   rootdepth = wrootattr.depth;
 
   XGetWindowAttributes (display->display, TermWin.parent[0], &wattr);
+
   if (rootdepth != wattr.depth)
     {
       if (am_transparent)
         {
           pchanged = 1;
-          XSetWindowBackground (display->display, TermWin.vt,
-                               PixColors[Color_bg]);
+          XSetWindowBackground (display->display, TermWin.vt, pix_colors_focused[Color_bg]);
           am_transparent = am_pixmap_trans = 0;
         }
+
       return pchanged; /* Don't try any more */
     }
 
@@ -1749,18 +2351,30 @@ rxvt_term::check_our_parents ()
    * 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_XROOTPMAPID] != 0
-       && (XGetWindowProperty (display->display, display->root, xa[XA_XROOTPMAPID],
+  i = (xa[XA_XROOTPMAPID]
+       && XGetWindowProperty (display->display, display->root, xa[XA_XROOTPMAPID],
                               0L, 1L, False, XA_PIXMAP, &atype, &aformat,
-                              &nitems, &bytes_after, &prop) == Success));
+                              &nitems, &bytes_after, &prop) == Success);
+
   if (!i || prop == NULL)
+     i = (xa[XA_XSETROOTID]
+          && XGetWindowProperty (display->display, display->root, xa[XA_XSETROOTID],
+                                 0L, 1L, False, XA_PIXMAP, &atype, &aformat,
+                                 &nitems, &bytes_after, &prop) == Success);
+
+  if (!i || prop == NULL
+#if TINTING
+      || !rs[Rs_color + Color_tint]
+#endif
+      )
     have_pixmap = 0;
   else
     {
       have_pixmap = 1;
-      rootpixmap = * ((Pixmap *)prop);
+      rootpixmap = *(Pixmap *)prop;
       XFree (prop);
     }
+
   if (have_pixmap)
     {
       /*
@@ -1774,7 +2388,7 @@ rxvt_term::check_our_parents ()
       XGCValues gcvalue;
 
       XTranslateCoordinates (display->display, TermWin.parent[0], display->root,
-                            0, 0, &sx, &sy, &cr);
+                             0, 0, &sx, &sy, &cr);
       nw = (unsigned int)szHint.width;
       nh = (unsigned int)szHint.height;
       nx = ny = 0;
@@ -1796,11 +2410,12 @@ rxvt_term::check_our_parents ()
       MIN_IT (nw, (unsigned int) (wrootattr.width - sx));
       MIN_IT (nh, (unsigned int) (wrootattr.height - sy));
       allowedxerror = -1;
-      image = XGetImage (display->display, rootpixmap, sx, sy, nw, nh, AllPlanes,
-                        ZPixmap);
+      image = XGetImage (display->display, 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 (am_transparent && am_pixmap_trans)
@@ -1812,51 +2427,64 @@ rxvt_term::check_our_parents ()
                   TermWin.pixmap = None;
                 }
             }
+
           am_pixmap_trans = 0;
         }
       else
         {
           if (TermWin.pixmap != None)
             XFreePixmap (display->display, TermWin.pixmap);
+
+#if TINTING
+          if (ISSET_PIXCOLOR (Color_tint))
+            {
+              unsigned short rm, gm, bm;
+              int shade = rs[Rs_shade] ? atoi (rs[Rs_shade]) : 100;
+
+              pix_colors_focused[Color_tint].get (display, rm, gm, bm);
+
+              ShadeXImage (display, image, shade, rm, gm, bm);
+            }
+#endif
+
           TermWin.pixmap = XCreatePixmap (display->display, TermWin.vt,
-                                         (unsigned int)szHint.width,
-                                         (unsigned int)szHint.height,
-                                         (unsigned int)image->depth);
+                                          szHint.width, szHint.height, image->depth);
           gc = XCreateGC (display->display, TermWin.vt, 0UL, &gcvalue);
           XPutImage (display->display, TermWin.pixmap, gc, image, 0, 0,
-                    nx, ny, (unsigned int)image->width,
-                    (unsigned int)image->height);
+                     nx, ny, image->width, image->height);
           XFreeGC (display->display, gc);
           XDestroyImage (image);
-          XSetWindowBackgroundPixmap (display->display, TermWin.vt,
-                                     TermWin.pixmap);
+          XSetWindowBackgroundPixmap (display->display, TermWin.parent[0], TermWin.pixmap);
+          XClearWindow (display->display, TermWin.parent[0]);
+
           if (!am_transparent || !am_pixmap_trans)
             pchanged = 1;
+
           am_transparent = am_pixmap_trans = 1;
         }
     }
 
   if (!am_pixmap_trans)
     {
-      unsigned int    n;
+      unsigned int n;
       /*
        * InheritPixmap transparency
        */
-      D_X ((stderr, "InheritPixmap Seeking to  %08lx", display->root));
-      for (i = 1; i < (int) (sizeof (TermWin.parent) / sizeof (Window));
-           i++)
+      for (i = 1; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++)
         {
           oldp = TermWin.parent[i];
           XQueryTree (display->display, TermWin.parent[i - 1], &root,
-                     &TermWin.parent[i], &list, &n);
+                      &TermWin.parent[i], &list, &n);
           XFree (list);
-          D_X ((stderr, "InheritPixmap Parent[%d] = %08lx", i, TermWin.parent[i]));
+
           if (TermWin.parent[i] == display->root)
             {
               if (oldp != None)
                 pchanged = 1;
+
               break;
             }
+
           if (oldp != TermWin.parent[i])
             pchanged = 1;
         }
@@ -1868,7 +2496,6 @@ rxvt_term::check_our_parents ()
           for (; n < (unsigned int)i; n++)
             {
               XGetWindowAttributes (display->display, TermWin.parent[n], &wattr);
-              D_X ((stderr, "InheritPixmap Checking Parent[%d]: %s", n, (wattr.depth == rootdepth && wattr.class != InputOnly) ? "OK" : "FAIL"));
               if (wattr.depth != rootdepth || wattr.c_class == InputOnly)
                 {
                   n = (int) (sizeof (TermWin.parent) / sizeof (Window)) + 1;
@@ -1877,42 +2504,41 @@ rxvt_term::check_our_parents ()
             }
         }
 
-      if (n > (int) (sizeof (TermWin.parent)
-                    / sizeof (TermWin.parent[0])))
+      if (n > (int) (sizeof (TermWin.parent) / sizeof (TermWin.parent[0])))
         {
-          D_X ((stderr, "InheritPixmap Turning off"));
-          XSetWindowBackground (display->display, TermWin.parent[0],
-                               PixColors[Color_fg]);
-          XSetWindowBackground (display->display, TermWin.vt,
-                               PixColors[Color_bg]);
+          XSetWindowBackground (display->display, TermWin.parent[0], pix_colors_focused[Color_fg]);
+          XSetWindowBackground (display->display, TermWin.vt, pix_colors_focused[Color_bg]);
           am_transparent = 0;
           /* XXX: also turn off Opt_transparent? */
         }
       else
         {
+#if WAIT_FOR_WM
           /* wait (an arbitrary period) for the WM to do its thing
            * needed for fvwm2.2.2 (and before?) */
-# ifdef HAVE_NANOSLEEP
-          struct timespec rqt;
-
-          rqt.tv_sec = 1;
-          rqt.tv_nsec = 0;
-          nanosleep (&rqt, NULL);
-# else
           sleep (1);
-# endif
-          D_X ((stderr, "InheritPixmap Turning on (%d parents)", i - 1));
+#endif
           for (n = 0; n < (unsigned int)i; n++)
-            XSetWindowBackgroundPixmap (display->display, TermWin.parent[n],
-                                       ParentRelative);
-          XSetWindowBackgroundPixmap (display->display, TermWin.vt,
-                                     ParentRelative);
+            {
+              XSetWindowBackgroundPixmap (display->display, TermWin.parent[n], ParentRelative);
+              XClearWindow (display->display, TermWin.parent[n]);
+            }
+
+          XSetWindowBackgroundPixmap (display->display, TermWin.vt, ParentRelative);
           am_transparent = 1;
         }
 
       for (; i < (int) (sizeof (TermWin.parent) / sizeof (Window)); i++)
         TermWin.parent[i] = None;
     }
+
+  if (scrollBar.win)
+    {
+      XSetWindowBackgroundPixmap (display->display, scrollBar.win, ParentRelative);
+      scrollBar.setIdle ();
+      scrollbar_show (0);
+    }
+
   return pchanged;
 }
 #endif
@@ -1937,41 +2563,49 @@ rxvt_term::cmd_parse ()
       if (ch == NOCHAR) // TODO: improve
         break;
 
-      if (!IS_CONTROL (ch) || ch == '\t' || ch == '\n' || ch == '\r')
+      if (!IS_CONTROL (ch) || ch == C0_LF || ch == C0_CR || ch == C0_HT)
         {
+          if (!seen_input)
+            {
+              seen_input = 1;
+              // many badly-written programs (e.g. jed) contain a race condition:
+              // they first read the screensize and then install a SIGWINCH handler.
+              // some window managers resize the window early, and these programs
+              // then sometimes get the size wrong.
+              // unfortunately other programs are even more buggy and dislike
+              // being sent SIGWINCH, so only do it when we were in fact being
+              // resized.
+              if (seen_resize)
+                kill (-cmd_pid, SIGWINCH);
+            }
+
           /* Read a text string from the input buffer */
           unicode_t buf[UBUFSIZ];
           bool refreshnow = false;
           int nlines = 0;
           unicode_t *str = buf;
 
-          *str++ = ch;
-
           for (;;)
             {
-              seq_begin = cmdbuf_ptr;
-              ch = next_char ();
-
-              if (ch == NOCHAR || (IS_CONTROL (ch) && ch != '\t' && ch != '\n' && ch != '\r'))
+              if (ch == NOCHAR || (IS_CONTROL (ch) && ch != C0_LF && ch != C0_CR && ch != C0_HT))
                 break;
 
               *str++ = ch;
 
-              if (ch == '\n')
+              if (ch == C0_LF)
                 {
                   nlines++;
                   refresh_count++;
 
-                  if (! (Options & Opt_jumpScroll)
-                      || (refresh_count >= (refresh_limit * (TermWin.nrow - 1))))
+                  if (!(options & Opt_jumpScroll)
+                      || (refresh_count >= refresh_limit * (TermWin.nrow - 1)))
                     {
                       refreshnow = true;
-                      flag = true;
                       ch = NOCHAR;
                       break;
                     }
 
-                  // scr_add_lines only works for nlines < TermWin.nrow - 1.
+                  // scr_add_lines only works for nlines <= TermWin.nrow - 1.
                   if (nlines >= TermWin.nrow - 1)
                     {
                       scr_add_lines (buf, nlines, str - buf);
@@ -1985,6 +2619,9 @@ rxvt_term::cmd_parse ()
                   ch = NOCHAR;
                   break;
                 }
+
+              seq_begin = cmdbuf_ptr;
+              ch = next_char ();
             }
 
           scr_add_lines (buf, nlines, str - buf);
@@ -1994,16 +2631,16 @@ rxvt_term::cmd_parse ()
            * 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.
-           *
-           * refreshing should be correct for small scrolls, because of the
-           * time-out
            */
           if (refreshnow)
             {
-              if ((Options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD)
+              if ((options & Opt_jumpScroll) && refresh_limit < REFRESH_PERIOD)
                 refresh_limit++;
-
-              scr_refresh (refresh_type);
+              else
+                {
+                  flag = true;
+                  scr_refresh (refresh_type);
+                }
             }
 
         }
@@ -2027,6 +2664,15 @@ rxvt_term::cmd_parse ()
   return flag;
 }
 
+// read the next octet
+unicode_t
+rxvt_term::next_octet ()
+{
+  return cmdbuf_ptr < cmdbuf_endp
+         ? *cmdbuf_ptr++
+         : NOCHAR;
+}
+
 // read the next character
 unicode_t
 rxvt_term::next_char ()
@@ -2074,6 +2720,17 @@ rxvt_term::cmd_getc ()
   return c;
 }
 
+unicode_t
+rxvt_term::cmd_get8 ()
+{
+  unicode_t c = next_octet ();
+
+  if (c == NOCHAR)
+    throw out_of_input;
+
+  return c;
+}
+
 /*{{{ print pipe */
 /*----------------------------------------------------------------------*/
 #ifdef PRINTPIPE
@@ -2158,10 +2815,10 @@ rxvt_term::process_print_pipe ()
 /* *INDENT-OFF* */
 enum {
   C1_40 = 0x40,
-  C1_41 , C1_BPH, C1_NBH, C1_44 , C1_NEL, C1_SSA, C1_ESA,
+          C1_41 , C1_BPH, C1_NBH, C1_44 , C1_NEL, C1_SSA, C1_ESA,
   C1_HTS, C1_HTJ, C1_VTS, C1_PLD, C1_PLU, C1_RI , C1_SS2, C1_SS3,
   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
+  C1_SOS, C1_59 , C1_SCI, C1_CSI, CS_ST , C1_OSC, C1_PM , C1_APC,
 };
 /* *INDENT-ON* */
 
@@ -2176,12 +2833,11 @@ rxvt_term::process_nonprinting (unicode_t ch)
         break;
       case C0_ENQ:     /* terminal Status */
         if (rs[Rs_answerbackstring])
-          tt_write (
-            (const unsigned char *)rs[Rs_answerbackstring],
-            (unsigned int)STRLEN (rs[Rs_answerbackstring]));
+          tt_write ((const unsigned char *)rs[Rs_answerbackstring],
+                    (unsigned int)strlen (rs[Rs_answerbackstring]));
         else
           tt_write ((unsigned char *)VT100_ANS,
-                   (unsigned int)STRLEN (VT100_ANS));
+                    (unsigned int)strlen (VT100_ANS));
         break;
       case C0_BEL:     /* bell */
         scr_bell ();
@@ -2207,6 +2863,7 @@ rxvt_term::process_nonprinting (unicode_t ch)
         scr_charset_choose (0);
         break;
 
+#ifdef EIGHT_BIT_CONTROLS
       // 8-bit controls
       case 0x90:       /* DCS */
         process_dcs_seq ();
@@ -2217,6 +2874,7 @@ rxvt_term::process_nonprinting (unicode_t ch)
       case 0x9d:       /* CSI */
         process_osc_seq ();
         break;
+#endif
     }
 }
 /*}}} */
@@ -2288,7 +2946,7 @@ rxvt_term::process_escape_seq ()
 {
   unicode_t ch = cmd_getc ();
 
-  if (PrivateModes & PrivMode_vt52)
+  if (priv_modes & PrivMode_vt52)
     {
       process_escape_vt52 (ch);
       return;
@@ -2313,7 +2971,7 @@ rxvt_term::process_escape_seq ()
       case '+':
         scr_charset_set (3, (unsigned int)cmd_getc ());
         break;
-#ifndef NO_FRILLS
+#if ENABLE_FRILLS
       case '6':
         scr_backindex ();
         break;
@@ -2324,7 +2982,7 @@ rxvt_term::process_escape_seq ()
       case '8':
         scr_cursor (RESTORE);
         break;
-#ifndef NO_FRILLS
+#if ENABLE_FRILLS
       case '9':
         scr_forwardindex ();
         break;
@@ -2344,7 +3002,7 @@ rxvt_term::process_escape_seq ()
         /* 8.3.87: NEXT LINE */
       case C1_NEL:             /* ESC E */
         {
-          unicode_t nlcr[] = { L'\n', L'\r' };
+          unicode_t nlcr[] = { C0_LF, C0_CR };
           scr_add_lines (nlcr, 1, 2);
         }
         break;
@@ -2365,10 +3023,10 @@ rxvt_term::process_escape_seq ()
         break;
 
         /* 8.3.142: SINGLE-SHIFT TWO */
-        /*case C1_SS2: scr_single_shift (2);   break; */
+      /*case C1_SS2: scr_single_shift (2);   break; */
 
         /* 8.3.143: SINGLE-SHIFT THREE */
-        /*case C1_SS3: scr_single_shift (3);   break; */
+      /*case C1_SS3: scr_single_shift (3);   break; */
 
         /* 8.3.27: DEVICE CONTROL STRING */
       case C1_DCS:             /* ESC P */
@@ -2393,6 +3051,7 @@ rxvt_term::process_escape_seq ()
 
         /* 8.3.106: RESET TO INITIAL STATE */
       case 'c':
+        mbstate.reset ();
         scr_poweron ();
         scrollbar_show (1);
         break;
@@ -2414,7 +3073,7 @@ rxvt_term::process_escape_seq ()
 /* *INDENT-OFF* */
 enum {
   CSI_ICH = 0x40,
-  CSI_CUU, CSI_CUD, CSI_CUF, CSI_CUB, CSI_CNL, CSI_CPL, CSI_CHA,
+           CSI_CUU, CSI_CUD, CSI_CUF, CSI_CUB, CSI_CNL, CSI_CPL, CSI_CHA,
   CSI_CUP, CSI_CHT, CSI_ED , CSI_EL , CSI_IL , CSI_DL , CSI_EF , CSI_EA ,
   CSI_DCH, CSI_SEE, CSI_CPR, CSI_SU , CSI_SD , CSI_NP , CSI_PP , CSI_CTC,
   CSI_ECH, CSI_CVT, CSI_CBT, CSI_SRS, CSI_PTX, CSI_SDS, CSI_SIMD, CSI_5F,
@@ -2439,7 +3098,7 @@ const unsigned char csi_defaults[] =
     make_byte (1,1,1,0,1,1,1,0),       /* `, a, b, c, d, e, f, g, */
     make_byte (0,0,1,1,0,0,0,0),       /* h, i, j, k, l, m, n, o, */
     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, {, |, }, ~,    */
+    make_byte (0,0,0,0,0,0,0,0),       /* x, y, z, {, |, }, ~,    */
   };
 /* *INDENT-ON* */
 
@@ -2632,7 +3291,7 @@ rxvt_term::process_csi_seq ()
 
       case CSI_DA:             /* 8.3.24: (0) DEVICE ATTRIBUTES */
         tt_write ((const unsigned char *)VT100_ANS,
-                 (unsigned int) (sizeof (VT100_ANS) - 1));
+                  (unsigned int) (sizeof (VT100_ANS) - 1));
         break;
 
       case CSI_SGR:            /* 8.3.118: (0) SELECT GRAPHIC RENDITION */
@@ -2648,13 +3307,12 @@ rxvt_term::process_csi_seq ()
             case 6:                    /* CPR requested */
               scr_report_position ();
               break;
-#if defined (ENABLE_DISPLAY_ANSWER)
             case 7:                    /* unofficial extension */
-              tt_printf ("%-.250s\n", rs[Rs_display_name]);
+              if (options & Opt_insecure)
+                tt_printf ("%-.250s\012", rs[Rs_display_name]);
               break;
-#endif
             case 8:                    /* unofficial extension */
-              xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST);
+              process_xterm_seq (XTerm_title, RESNAME "-" VERSION, CHAR_ST);
               break;
           }
         break;
@@ -2697,11 +3355,15 @@ rxvt_term::process_csi_seq ()
       case CSI_RM:             /* 8.3.107: RESET MODE */
         if (arg[0] == 4)
           scr_insert_mode (0);
+        else if (arg[0] == 20)
+          priv_modes &= ~PrivMode_LFNL;
         break;
 
       case CSI_SM:             /* 8.3.126: SET MODE */
         if (arg[0] == 4)
           scr_insert_mode (1);
+        else if (arg[0] == 20)
+          priv_modes |= PrivMode_LFNL;
         break;
 
         /*
@@ -2723,7 +3385,7 @@ rxvt_term::process_csi_seq ()
         scr_cursor (RESTORE);
         break;
 
-#ifndef NO_FRILLS
+#if ENABLE_FRILLS
       case CSI_74:
         process_window_ops (arg, nargs);
         break;
@@ -2740,7 +3402,7 @@ rxvt_term::process_csi_seq ()
 }
 /*}}} */
 
-#ifndef NO_FRILLS
+#if ENABLE_FRILLS
 /* ARGSUSED */
 void
 rxvt_term::process_window_ops (const int *args, unsigned int nargs)
@@ -2802,8 +3464,8 @@ rxvt_term::process_window_ops (const int *args, unsigned int nargs)
       case 13:                 /* report window position */
         XGetWindowAttributes (display->display, TermWin.parent[0], &wattr);
         XTranslateCoordinates (display->display, TermWin.parent[0], wattr.root,
-                              -wattr.border_width, -wattr.border_width,
-                              &x, &y, &wdummy);
+                               -wattr.border_width, -wattr.border_width,
+                               &x, &y, &wdummy);
         tt_printf ("\033[3;%d;%dt", x, y);
         break;
       case 14:                 /* report window size (pixels) */
@@ -2816,16 +3478,22 @@ rxvt_term::process_window_ops (const int *args, unsigned int nargs)
       case 19:                 /* report window size (chars) */
         tt_printf ("\033[9;%d;%dt", TermWin.nrow, TermWin.ncol);
         break;
-#if 0 /* XXX: currently disabled due to security concerns */
       case 20:                 /* report icon label */
-        XGetIconName (display->display, TermWin.parent[0], &s);
-        tt_printf ("\033]L%-.200s\234", s ? s : "");   /* 8bit ST */
+        {
+          char *s;
+          XGetIconName (display->display, TermWin.parent[0], &s);
+          tt_printf ("\033]L%-.250s\234", (options & Opt_insecure) && s ? s : "");     /* 8bit ST */
+          XFree (s);
+        }
         break;
       case 21:                 /* report window title */
-        XFetchName (display->display, TermWin.parent[0], &s);
-        tt_printf ("\033]l%-.200s\234", s ? s : "");   /* 8bit ST */
+        {
+          char *s;
+          XFetchName (display->display, TermWin.parent[0], &s);
+          tt_printf ("\033]l%-.250s\234", (options & Opt_insecure) && s ? s : "");     /* 8bit ST */
+          XFree (s);
+        }
         break;
-#endif
     }
 }
 #endif
@@ -2833,38 +3501,45 @@ rxvt_term::process_window_ops (const int *args, unsigned int nargs)
 /*----------------------------------------------------------------------*/
 /*
  * get input up until STRING TERMINATOR (or BEL)
- * ends_how is terminator used. returned input must be free ()d
+ * ends_how is terminator used. returned input must be free()'d
  */
 unsigned char *
 rxvt_term::get_to_st (unicode_t &ends_how)
 {
-  int seen_esc = 0;    /* seen escape? */
+  unicode_t seen_esc = 0, ch;
   unsigned int n = 0;
   unsigned char *s;
-  unicode_t ch;
   unsigned char string[STRING_MAX];
 
-  while ((ch = cmd_getc ()))
+  while ((ch = cmd_getc ()) != NOCHAR)
     {
-      if (ch == C0_BEL
-          || ch == CHAR_ST
-          || (ch == 0x5c && seen_esc)) /* 7bit ST */
-        break;
-
-      if (ch == C0_ESC)
+      if (seen_esc)
+        {
+          if (ch == 0x5c)      /* 7bit ST */
+            break;
+          else
+            return NULL;
+        }
+      else if (ch == C0_ESC)
         {
           seen_esc = 1;
           continue;
         }
-      else if (ch == '\t')
-        ch = ' ';      /* translate '\t' to space */
-      else if (ch < 0x08 || (ch > 0x0d && ch < 0x20))
+      else if (ch == C0_BEL || ch == CHAR_ST)
+        break;
+      else if (ch < 0x20)
         return NULL;   /* other control character - exit */
 
-      if (n < sizeof (string) - 1)
-        string[n++] = ch;
-
       seen_esc = 0;
+
+      if (n >= sizeof (string) - 1)
+        // stop at some sane length
+        return NULL;
+
+      if (ch == C0_SYN)
+        string[n++] = cmd_get8 ();
+      else
+        string[n++] = ch;
     }
 
   string[n++] = '\0';
@@ -2873,7 +3548,7 @@ rxvt_term::get_to_st (unicode_t &ends_how)
     return NULL;
 
   ends_how = (ch == 0x5c ? C0_ESC : ch);
-  STRNCPY (s, string, n);
+  strncpy (s, string, n);
   return s;
 }
 
@@ -2917,29 +3592,33 @@ rxvt_term::process_osc_seq ()
 
       if (s)
         {
-          /*
-           * rxvt_menubar_dispatch () violates the constness of the string,
-           * so do it here
-           */
-          if (arg == XTerm_Menu)
-#if 0 /* XXX: currently disabled due to security concerns */
-            menubar_dispatch ((char *)s);
-#else
-            (void)0;
-#endif
-          else
-            xterm_seq (arg, (char *)s, eh);
-
+          process_xterm_seq (arg, (char *)s, eh);
           free (s);
         }
     }
 }
+
+void
+rxvt_term::process_color_seq (int report, int color, const char *str, unsigned char resp)
+{
+  if (str[0] == '?' && !str[1])
+    {
+      unsigned short r, g, b;
+      pix_colors_focused[color].get (display, r, g, b);
+      tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, r, g, b, resp);
+    }
+  else
+    set_window_color (color, str);
+}
+
 /*
  * XTerm escape sequences: ESC ] Ps;Pt (ST|BEL)
  *       0 = change iconName/title
  *       1 = change iconName
  *       2 = change title
  *       4 = change color
+ *      10 = change fg color
+ *      11 = change bg color
  *      12 = change text color
  *      13 = change mouse foreground color 
  *      17 = change highlight character colour
@@ -2949,20 +3628,22 @@ rxvt_term::process_osc_seq ()
  *      50 = change font
  *
  * rxvt extensions:
- *      10 = menu (may change in future)
  *      20 = bg pixmap
  *      39 = change default fg color
  *      49 = change default bg color
  *      55 = dump scrollback buffer and all of screen
  *     701 = change locale
  *     702 = find font
+ *     703 = menu
  */
 void
-rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__ ((unused)))
+rxvt_term::process_xterm_seq (int op, const char *str, unsigned char resp)
 {
   int changed = 0;
   int color;
   char *buf, *name;
+  bool query = str[0] == '?' && !str[1];
+  int saveop = op;
 
   assert (str != NULL);
   switch (op)
@@ -2976,10 +3657,52 @@ rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__
       case XTerm_title:
         set_title (str);
         break;
+      case XTerm_property:
+        if (str[0] == '?')
+          {
+            Atom prop = XInternAtom (display->display, str + 1, True);
+            Atom actual_type;
+            int actual_format;
+            unsigned long nitems;
+            unsigned long bytes_after;
+            unsigned char *value = 0;
+            const char *str = "";
+
+            if (prop
+                && XGetWindowProperty (display->display, TermWin.parent[0],
+                                       prop, 0, 1<<16, 0, AnyPropertyType,
+                                       &actual_type, &actual_format,
+                                       &nitems, &bytes_after, &value) == Success
+                && actual_type != None
+                && actual_format == 8)
+              str = (const char *)(value);
+
+            tt_printf ("\033]%d;%s%c", XTerm_property, str, resp);
+
+            XFree (value);
+          }
+        else
+          {
+            char *eq = strchr (str, '='); // constness lost, but verified to be ok
+
+            if (eq)
+              {
+                *eq = 0;
+                XChangeProperty (display->display, TermWin.parent[0],
+                                 display->atom (str), XA_STRING, 8,
+                                 PropModeReplace, (unsigned char *)eq + 1,
+                                 strlen (eq + 1));
+              }
+            else
+              XDeleteProperty (display->display, TermWin.parent[0],
+                               display->atom (str));
+          }
+        break;
+
       case XTerm_Color:
         for (buf = (char *)str; buf && *buf;)
           {
-            if ((name = STRCHR (buf, ';')) == NULL)
+            if ((name = strchr (buf, ';')) == NULL)
               break;
 
             *name++ = '\0';
@@ -2988,38 +3711,59 @@ rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__
             if (color < 0 || color >= TOTAL_COLORS)
               break;
 
-            if ((buf = STRCHR (name, ';')) != NULL)
+            if ((buf = strchr (name, ';')) != NULL)
               *buf++ = '\0';
 
-            set_window_color (color + minCOLOR, name);
+            if (name[0] == '?' && !name[1])
+              {
+                unsigned short r, g, b;
+                pix_colors_focused[color + minCOLOR].get (display, r, g, b);
+                tt_printf ("\033]%d;%d;rgb:%04x/%04x/%04x%c", XTerm_Color, color, r, g, b, resp);
+              }
+            else
+              set_window_color (color + minCOLOR, name);
           }
         break;
+      case XTerm_Color00:
+        process_color_seq (XTerm_Color00, Color_fg, str, resp);
+        break;
+      case XTerm_Color01:
+        process_color_seq (XTerm_Color00, Color_bg, str, resp);
+        break;
 #ifndef NO_CURSORCOLOR
       case XTerm_Color_cursor:
-        set_window_color (Color_cursor, str);
+        process_color_seq (XTerm_Color_cursor, Color_cursor, str, resp);
         break;
 #endif
-      case XTerm_Color_pointer:
-        set_window_color (Color_pointer, str);
+      case XTerm_Color_pointer_fg:
+        process_color_seq (XTerm_Color_pointer_fg, Color_pointer_fg, str, resp);
+        break;
+      case XTerm_Color_pointer_bg:
+        process_color_seq (XTerm_Color_pointer_bg, Color_pointer_bg, str, resp);
         break;
 #ifndef NO_BOLD_UNDERLINE_REVERSE
       case XTerm_Color_BD:
-        set_window_color (Color_BD, str);
+        process_color_seq (XTerm_Color_BD, Color_BD, str, resp);
+        break;
+      case XTerm_Color_IT:
+        process_color_seq (XTerm_Color_IT, Color_IT, str, resp);
         break;
       case XTerm_Color_UL:
-        set_window_color (Color_UL, str);
+        process_color_seq (XTerm_Color_UL, Color_UL, str, resp);
         break;
       case XTerm_Color_RV:
-        set_window_color (Color_RV, str);
+        process_color_seq (XTerm_Color_RV, Color_RV, str, resp);
         break;
 #endif
-
-      case XTerm_Menu:
-        /*
-         * rxvt_menubar_dispatch () violates the constness of the string,
-         * so DON'T do it here
-         */
+#if TRANSPARENT || TINTING
+      case XTerm_Color_tint:
+        process_color_seq (XTerm_Color_tint, Color_tint, str, resp);
+        check_our_parents ();
+        if (am_transparent)
+          want_full_refresh = want_refresh = 1;
         break;
+#endif
+
       case XTerm_Pixmap:
         if (*str != ';')
           {
@@ -3029,7 +3773,7 @@ rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__
 #endif
             scr_touch (true);
           }
-        while ((str = STRCHR (str, ';')) != NULL)
+        while ((str = strchr (str, ';')) != NULL)
           {
             str++;
 #if XPM_BACKGROUND
@@ -3052,16 +3796,38 @@ rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__
       case XTerm_restoreBG:
         set_window_color (Color_bg, str);
         break;
+
       case XTerm_logfile:
         // TODO, when secure mode?
         break;
+
       case XTerm_font:
-        change_font (str);
+        op = URxvt_font;
+      case URxvt_font:
+#if ENABLE_STYLES
+      case URxvt_boldFont:
+      case URxvt_italicFont:
+      case URxvt_boldItalicFont:
+#endif
+        if (query)
+          tt_printf ("\33]%d;%-.250s%c", saveop,
+                     (options & Opt_insecure) && TermWin.fontset[op - URxvt_font]->fontdesc
+                       ? TermWin.fontset[op - URxvt_font]->fontdesc : "",
+                     resp);
+        else
+          {
+            const char *&res = rs[Rs_font + (op - URxvt_font)];
+
+            res = strdup (str);
+            allocated.push_back ((void *)res);
+            set_fonts ();
+          }
         break;
-#ifndef NO_FRILLS
+
+#if ENABLE_FRILLS
       case XTerm_locale:
-        if (str[0] == '?' && !str[1])
-          tt_printf ("%-.250s\n", locale);
+        if (query)
+          tt_printf ("\33]%d;%-.250s%c", XTerm_locale, (options & Opt_insecure) ? locale : "", resp);
         else
           {
             set_locale (str);
@@ -3070,17 +3836,18 @@ rxvt_term::xterm_seq (int op, const char *str, unsigned char resp __attribute__
 # endif
           }
         break;
-      case XTerm_findfont:
-        {
-          int fid = TermWin.fontset->find_font (atoi (str));
-          tt_printf ("%d %-.250s\n", fid, (*TermWin.fontset)[fid]->name);
-        }
-        break;
+#endif
+
+#ifdef MENUBAR
+     case XTerm_Menu:
+       if (options & Opt_insecure)
+         menubar_dispatch (const_cast<char *>(str)); // casting away constness is checked
+       break;
 #endif
 #if 0
       case XTerm_dumpscreen:   /* no error notices */
         {
-          int             fd;
+          int fd;
           if ((fd = open (str, O_RDWR | O_CREAT | O_EXCL, 0600)) >= 0)
             {
               scr_dump (fd);
@@ -3110,7 +3877,7 @@ rxvt_term::privcases (int mode, unsigned long bit)
 
   if (mode == 's')
     {
-      SavedModes |= (PrivateModes & bit);
+      SavedModes |= (priv_modes & bit);
       return -1;
     }
   else
@@ -3118,7 +3885,7 @@ rxvt_term::privcases (int mode, unsigned long bit)
       if (mode == 'r')
         state = (SavedModes & bit) ? 1 : 0;    /* no overlapping */
       else
-        state = (mode == 't') ? ! (PrivateModes & bit) : mode;
+        state = (mode == 't') ? ! (priv_modes & bit) : mode;
       PrivMode (state, bit);
     }
 
@@ -3146,16 +3913,16 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
                   { 5, PrivMode_rVideo },
                   { 6, PrivMode_relOrigin },
                   { 7, PrivMode_Autowrap },
+                 // 8, bi-directional support mode
                   { 9, PrivMode_MouseX10 },
 #ifdef menuBar_esc
                   { menuBar_esc, PrivMode_menuBar },
 #endif
+                 // 18, 19 printing-related
+                  { 25, PrivMode_VisibleCursor },
 #ifdef scrollBar_esc
                   { scrollBar_esc, PrivMode_scrollBar },
 #endif
-                 // 18, 19 printing-related
-                  { 25, PrivMode_VisibleCursor },
-                 // 30 show scrollbar rxvt. extension
                   { 35, PrivMode_ShiftKeys }, // rxvt extension
                   { 40, PrivMode_132OK },
                  // 41 xterm more fixes NYI
@@ -3177,7 +3944,7 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
                  // 1037 send DEL for keypad delete NYI
                   { 1047, PrivMode_Screen },
                  // 1048 save and restore cursor
-                  { 1049, PrivMode_Screen }, /* xterm extension, not fully implemented */
+                  { 1049, PrivMode_Screen }, /* xterm extension, clear screen on ti rather than te */
                  // 1051, 1052, 1060, 1061 keyboard emulation NYI
                 };
 
@@ -3207,11 +3974,12 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
         {
           case 1048:           /* alternative cursor save */
           case 1049:
-            if (mode == 0)
-              scr_cursor (RESTORE);
-            else if (mode == 1)
-              scr_cursor (SAVE);
-            /* FALLTHROUGH */
+            if (options & Opt_secondaryScreen)
+              if (mode == 0)
+                scr_cursor (RESTORE);
+              else if (mode == 1)
+                scr_cursor (SAVE);
+            break;
         }
 
       if (state >= 0)
@@ -3227,14 +3995,14 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
               PrivMode (1, PrivMode_vt52);
               break;
             case 3:                    /* 80/132 */
-              if (PrivateModes & PrivMode_132OK)
+              if (priv_modes & PrivMode_132OK)
                 set_widthheight (((state ? 132 : 80) * TermWin.fwidth), TermWin.height);
               break;
             case 4:                    /* smooth scrolling */
               if (state)
-                Options &= ~Opt_jumpScroll;
+                options &= ~Opt_jumpScroll;
               else
-                Options |= Opt_jumpScroll;
+                options |= Opt_jumpScroll;
               break;
             case 5:                    /* reverse video */
               scr_rvideo_mode (state);
@@ -3245,10 +4013,10 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
             case 7:                    /* autowrap */
               scr_autowrap (state);
               break;
-              /* case 8:       - auto repeat, can't do on a per window basis */
+            /* case 8: - auto repeat, can't do on a per window basis */
             case 9:                    /* X10 mouse reporting */
               if (state)               /* orthogonal */
-                PrivateModes &= ~PrivMode_MouseX11;
+                priv_modes &= ~PrivMode_MouseX11;
               break;
 #ifdef menuBar_esc
             case menuBar_esc:
@@ -3269,16 +4037,16 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
             case 25:           /* visible/invisible cursor */
               scr_cursor_visible (state);
               break;
-              /* case 35:      - shift keys */
-              /* case 40:      - 80 <--> 132 mode */
+            /* case 35:        - shift keys */
+            /* case 40:        - 80 <--> 132 mode */
             case 47:           /* secondary screen */
               scr_change_screen (state);
               break;
-              /* case 66:      - application key pad */
-              /* case 67:      - backspace key */
+            /* case 66:        - application key pad */
+            /* case 67:        - backspace key */
             case 1000:         /* X11 mouse reporting */
               if (state)               /* orthogonal */
-                PrivateModes &= ~PrivMode_MouseX10;
+                priv_modes &= ~PrivMode_MouseX10;
               break;
 #if 0
             case 1001:
@@ -3286,23 +4054,28 @@ rxvt_term::process_terminal_mode (int mode, int priv __attribute__ ((unused)), u
 #endif
             case 1010:         /* scroll to bottom on TTY output inhibit */
               if (state)
-                Options &= ~Opt_scrollTtyOutput;
+                options &= ~Opt_scrollTtyOutput;
               else
-                Options |= Opt_scrollTtyOutput;
+                options |= Opt_scrollTtyOutput;
               break;
             case 1011:         /* scroll to bottom on key press */
               if (state)
-                Options |= Opt_scrollTtyKeypress;
+                options |= Opt_scrollTtyKeypress;
               else
-                Options &= ~Opt_scrollTtyKeypress;
+                options &= ~Opt_scrollTtyKeypress;
               break;
-            case 1047:         /* secondary screen w/ clearing */
-            case 1049:         /* better secondary screen w/ clearing, but not fully implemented */
-              if (current_screen != PRIMARY)
-                scr_erase_screen (2);
-
+            case 1047:         /* secondary screen w/ clearing last */
+              if (options & Opt_secondaryScreen)
+                if (current_screen != PRIMARY)
+                  scr_erase_screen (2);
+              scr_change_screen (state);
+              break;
+            case 1049:         /* secondary screen w/ clearing first */
               scr_change_screen (state);
-              /* FALLTHROUGH */
+              if (options & Opt_secondaryScreen)
+                if (current_screen != PRIMARY)
+                  scr_erase_screen (2);
+              break;
             default:
               break;
           }
@@ -3335,33 +4108,54 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
           case 1:
             rendset = 1, rendstyle = RS_Bold;
             break;
+          //case 2: // low intensity
+          case 3:
+            rendset = 1, rendstyle = RS_Italic;
+            break;
           case 4:
             rendset = 1, rendstyle = RS_Uline;
             break;
-          case 5:
+          case 5: // slowly blinking
+          case 6: // rapidly blinking
             rendset = 1, rendstyle = RS_Blink;
             break;
+          //case 6: // scoansi light background
           case 7:
             rendset = 1, rendstyle = RS_RVid;
             break;
           case 8:
             // invisible. NYI
             break;
-          case 22:
+          //case 9: // crossed out
+          //case 10: // scoansi acs off, primary font
+          //case 11: // scoansi acs on, first alt font
+          //case 12: // scoansi acs on, |0x80, second alt font
+          //...
+          //case 19: // ninth alt font
+          //case 20: // gothic
+          case 21: // disable bold, faint, sometimes doubly underlined (iso 8613)
+            rendset = 0, rendstyle = RS_Bold;
+            break;
+          case 22: // normal intensity
             rendset = 0, rendstyle = RS_Bold;
             break;
+          case 23: // disable italic
+            rendset = 0, rendstyle = RS_Italic;
+            break;
           case 24:
             rendset = 0, rendstyle = RS_Uline;
             break;
           case 25:
             rendset = 0, rendstyle = RS_Blink;
             break;
+          case 26: // variable spacing (iso 8613)
+            rendset = 0, rendstyle = RS_Blink;
+            break;
           case 27:
             rendset = 0, rendstyle = RS_RVid;
             break;
-          case 28:
-            // visible. NYI
-            break;
+          //case 28: // visible. NYI
+          //case 29: // not crossed-out
         }
 
       if (rendset != -1)
@@ -3382,15 +4176,13 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
           case 37:
             scr_color ((unsigned int) (minCOLOR + (arg[i] - 30)), Color_fg);
             break;
-#ifdef TTY_256COLOR
-          case 38:
+          case 38: // set fg color, ISO 8613-6
             if (nargs > i + 2 && arg[i + 1] == 5)
               {
                 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_fg);
                 i += 2;
               }
             break;
-#endif
           case 39:             /* default fg */
             scr_color (Color_fg, Color_fg);
             break;
@@ -3405,19 +4197,19 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
           case 47:
             scr_color ((unsigned int) (minCOLOR + (arg[i] - 40)), Color_bg);
             break;
-#ifdef TTY_256COLOR
-          case 48:
+          case 48: // set bg color, ISO 8613-6
             if (nargs > i + 2 && arg[i + 1] == 5)
               {
                 scr_color ((unsigned int) (minCOLOR + arg[i + 2]), Color_bg);
                 i += 2;
               }
             break;
-#endif
           case 49:             /* default bg */
             scr_color (Color_bg, Color_bg);
             break;
 
+          //case 50: // not variable spacing
+
 #ifndef NO_BRIGHTCOLOR
           case 90:
           case 91:             /* set bright fg color */
@@ -3427,8 +4219,7 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
           case 95:
           case 96:
           case 97:
-            scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 90)),
-                       Color_fg);
+            scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 90)), Color_fg);
             break;
           case 100:
           case 101:            /* set bright bg color */
@@ -3438,8 +4229,7 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
           case 105:
           case 106:
           case 107:
-            scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 100)),
-                       Color_bg);
+            scr_color ((unsigned int) (minBrightCOLOR + (arg[i] - 100)), Color_bg);
             break;
 #endif
 
@@ -3448,7 +4238,7 @@ rxvt_term::process_sgr_mode (unsigned int nargs, const int *arg)
 }
 /*}}} */
 
-/*{{{ process Rob Nation's own graphics mode sequences */
+/*{{{ (do not) process Rob Nation's own graphics mode sequences */
 void
 rxvt_term::process_graphics ()
 {
@@ -3456,7 +4246,7 @@ rxvt_term::process_graphics ()
 
   if (cmd == 'Q')
     {          /* query graphics */
-      tt_printf ("\033G0\n");  /* no graphics */
+      tt_printf ("\033G0\012");        /* no graphics */
       return;
     }
   /* swallow other graphics sequences until terminating ':' */
@@ -3481,7 +4271,7 @@ rxvt_term::tt_printf (const char *fmt,...)
   va_start (arg_ptr, fmt);
   vsnprintf ((char *)buf, 256, fmt, arg_ptr);
   va_end (arg_ptr);
-  tt_write (buf, STRLEN (buf));
+  tt_write (buf, strlen (buf));
 }
 
 /* ---------------------------------------------------------------------- */
@@ -3491,13 +4281,13 @@ rxvt_term::tt_printf (const char *fmt,...)
 void
 rxvt_term::tt_write (const unsigned char *data, unsigned int len)
 {
-  enum { MAX_PTY_WRITE = 255 }; // minimum MAX_INPUT
+  const unsigned int MAX_PTY_WRITE = 255; // minimum MAX_INPUT
 
   if (len)
     {
       if (v_buflen == 0)
         {
-          ssize_t written = write (cmd_fd, data, min (MAX_PTY_WRITE, len));
+          ssize_t written = write (pty.pty, data, min (len, MAX_PTY_WRITE));
 
           if ((unsigned int)written == len)
             return;
@@ -3515,7 +4305,7 @@ rxvt_term::tt_write (const unsigned char *data, unsigned int len)
 
   for (;;)
     {
-      int written = write (cmd_fd, v_buffer, min (MAX_PTY_WRITE, v_buflen));
+      int written = write (pty.pty, v_buffer, min (v_buflen, MAX_PTY_WRITE));
 
       if (written > 0)
         {