*** empty log message ***
authorroot <root>
Wed, 25 Jan 2006 00:42:20 +0000 (00:42 +0000)
committerroot <root>
Wed, 25 Jan 2006 00:42:20 +0000 (00:42 +0000)
14 files changed:
Changes
MANIFEST
src/hookinc.h
src/main.C
src/perl/xim-onthespot [new file with mode: 0644]
src/rxvt.h
src/rxvtfont.C
src/rxvtperl.h
src/rxvtperl.xs
src/rxvttoolkit.C
src/rxvtutil.C
src/rxvtutil.h
src/screen.C
src/urxvt.pm

diff --git a/Changes b/Changes
index bfd5322ee469178f0ed94ed6dafde171a7737ea7..90279c6d485365377a6ad09d6b65edf7ed467363 100644 (file)
--- a/Changes
+++ b/Changes
@@ -15,12 +15,11 @@ WISH: OnTheSpot editing, or maybe switch to miiiiiiif. or maybe use perl and an
 WISH: just for fun, do shade and tint with XRender.
 DUMB: support tex fonts
 
-TODO: ctrl - mouse button2 in vim makes X freeze (unreproducable with cvs)
         - don't let iso14755 or mouse reporting get into the way of perl
           (could lead to global grabs never being cleared).
+        - experimental OnTheSpot editing support (-pe xim-onthespot).
         - moved Shift-Button2 paste combination to Meta-Button2.
         - removed (unused) arabic presentation form composing sequences.
-        - correctly ask XIM for events it needs to have enabled on the window.
         - changed version sos (ESC [ > c) response to be more compatible with
           xterm.
 
index eb7c751858cc5139f58a593d8bc3138b30828515..9b17e3e7839006d6eae81d40e997fbe98fd9e050 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -168,6 +168,7 @@ src/perl/searchable-scrollback
 src/perl/automove-background
 src/perl/mark-urls
 src/perl/tabbed
+src/perl/xim-onthespot
 src/perl/readline
 src/perl/example-refresh-hooks
 src/perl/block-graphics-to-ascii
index 203632f9ddff8aa9147b853f3a7b0dd05bdaeafe..e716ee7beee54935a005c40ce11139b67b4140c7 100644 (file)
   def (WM_PROTOCOLS)
   def (PROPERTY_NOTIFY)
 
+  def (XIM_PREEDIT_START)
+  def (XIM_PREEDIT_DONE)
+  def (XIM_PREEDIT_DRAW)
+  def (XIM_PREEDIT_CARET)
+
   def (CUSTOM_REND) // hovering over custom rendition, generate enter/leave maybe?
 
index 94571ef03056d1c39d55a78f56cd36098c09a0c4..d87b108d9fb7b811c218c2634b78202083ebf635 100644 (file)
@@ -307,8 +307,7 @@ rxvt_term::destroy ()
   if (destroy_ev.active)
     return;
 
-  if (HOOK_INVOKE ((this, HOOK_DESTROY, DT_END)))
-    return;
+  HOOK_INVOKE ((this, HOOK_DESTROY, DT_END));
 
 #if ENABLE_OVERLAY
   scr_overlay_off ();
@@ -1244,6 +1243,78 @@ rxvt_term::im_destroy ()
   Input_Context = 0;
 }
 
+#ifdef ENABLE_XIM_ONTHESPOT
+
+static void
+xim_preedit_start (XIC ic, XPointer client_data, XPointer call_data)
+{
+  ((rxvt_term *)client_data)->make_current ();
+  HOOK_INVOKE (((rxvt_term *)client_data, HOOK_XIM_PREEDIT_START, DT_END));
+}
+
+static void
+xim_preedit_done (XIC ic, XPointer client_data, XPointer call_data)
+{
+  ((rxvt_term *)client_data)->make_current ();
+  HOOK_INVOKE (((rxvt_term *)client_data, HOOK_XIM_PREEDIT_DONE, DT_END));
+}
+
+static void
+xim_preedit_draw (XIC ic, XPointer client_data, XIMPreeditDrawCallbackStruct *call_data)
+{
+  rxvt_term *term = (rxvt_term *)client_data;
+  XIMText *text = call_data->text;
+
+  term->make_current ();
+
+  if (text)
+    {
+      void *str;
+
+      if (!text->encoding_is_wchar && text->string.multi_byte)
+        {
+          // of course, X makes it ugly again
+          if (term->rs[Rs_imLocale])
+            SET_LOCALE (term->rs[Rs_imLocale]);
+
+          str = rxvt_temp_buf ((text->length + 1) * sizeof (wchar_t));
+          mbstowcs ((wchar_t *)str, text->string.multi_byte, text->length + 1);
+
+          if (term->rs[Rs_imLocale])
+            SET_LOCALE (term->locale);
+        }
+      else
+        str = (void *)text->string.wide_char;
+      
+      HOOK_INVOKE ((term, HOOK_XIM_PREEDIT_DRAW,
+                    DT_INT, call_data->caret,
+                    DT_INT, call_data->chg_first,
+                    DT_INT, call_data->chg_length,
+                    DT_LCS_LEN, (void *)text->feedback, text->feedback ? (int)text->length : 0,
+                    DT_WCS_LEN, str, str ? (int)text->length : 0,
+                    DT_END));
+    }
+  else
+    HOOK_INVOKE ((term, HOOK_XIM_PREEDIT_DRAW,
+                  DT_INT, call_data->caret,
+                  DT_INT, call_data->chg_first,
+                  DT_INT, call_data->chg_length,
+                  DT_END));
+}
+
+static void
+xim_preedit_caret (XIC ic, XPointer client_data, XIMPreeditCaretCallbackStruct *call_data)
+{
+  ((rxvt_term *)client_data)->make_current ();
+  HOOK_INVOKE (((rxvt_term *)client_data, HOOK_XIM_PREEDIT_CARET,
+                DT_INT, call_data->position,
+                DT_INT, call_data->direction,
+                DT_INT, call_data->style,
+                DT_END));
+}
+
+#endif
+
 /*
  * Try to open a XIM with the current modifiers, then see if we can
  * open a suitable preedit type
@@ -1259,6 +1330,9 @@ rxvt_term::IM_get_IC (const char *modifiers)
   const char *p;
   char **s;
   XIMStyles *xim_styles;
+#ifdef ENABLE_XIM_ONTHESPOT
+  XIMCallback xcb[4];
+#endif
 
   set_environ (envv);
 
@@ -1294,13 +1368,19 @@ rxvt_term::IM_get_IC (const char *modifiers)
       for (i = found = 0; !found && s[i]; i++)
         {
           if (!strcmp (s[i], "OverTheSpot"))
-            input_style = (XIMPreeditPosition | XIMStatusNothing);
+            input_style = XIMPreeditPosition | XIMStatusNothing;
           else if (!strcmp (s[i], "OffTheSpot"))
-            input_style = (XIMPreeditArea | XIMStatusArea);
+            input_style = XIMPreeditArea | XIMStatusArea;
           else if (!strcmp (s[i], "Root"))
-            input_style = (XIMPreeditNothing | XIMStatusNothing);
+            input_style = XIMPreeditNothing | XIMStatusNothing;
           else if (!strcmp (s[i], "None"))
-            input_style = (XIMPreeditNone | XIMStatusNone);
+            input_style = XIMPreeditNone | XIMStatusNone;
+#ifdef ENABLE_XIM_ONTHESPOT
+          else if (SHOULD_INVOKE (HOOK_XIM_PREEDIT_START) && !strcmp (s[i], "OnTheSpot"))
+            input_style = XIMPreeditCallbacks | XIMStatusNothing;
+#endif
+          else
+            input_style = XIMPreeditNothing | XIMStatusNothing;
 
           for (j = 0; j < xim_styles->count_styles; j++)
             if (input_style == xim_styles->supported_styles[j])
@@ -1399,6 +1479,20 @@ foundpet:
                                          XNFontSet, fs,
                                          NULL);
     }
+  else if (input_style & XIMPreeditCallbacks)
+    {
+      xcb[0].client_data = (XPointer)this; xcb[0].callback = (XIMProc)xim_preedit_start;
+      xcb[1].client_data = (XPointer)this; xcb[1].callback = (XIMProc)xim_preedit_done;
+      xcb[2].client_data = (XPointer)this; xcb[2].callback = (XIMProc)xim_preedit_draw;
+      xcb[3].client_data = (XPointer)this; xcb[3].callback = (XIMProc)xim_preedit_caret;
+
+      preedit_attr = XVaCreateNestedList (0,
+                                          XNPreeditStartCallback, &xcb[0],
+                                          XNPreeditDoneCallback , &xcb[1],
+                                          XNPreeditDrawCallback , &xcb[2],
+                                          XNPreeditCaretCallback, &xcb[3],
+                                          NULL);
+    }
 
   Input_Context = XCreateIC (xim,
                              XNInputStyle, input_style,
@@ -1420,8 +1514,11 @@ foundpet:
       return false;
     }
 
+#if 0
+  // unfortunately, only the focus window is used by XIM, hard to fix
   if (!XGetICValues (Input_Context, XNFilterEvents, &vt_emask_xim, NULL))
     vt_select_input ();
+#endif
 
   if (input_style & XIMPreeditArea)
     IMSetStatusPosition ();
diff --git a/src/perl/xim-onthespot b/src/perl/xim-onthespot
new file mode 100644 (file)
index 0000000..08ffb43
--- /dev/null
@@ -0,0 +1,79 @@
+#! perl
+
+#
+# problems with this implementation include
+# 
+# - primary, secondary, teriary is NOT different to other hilighting
+# - if rend values are missing, they are not interpolated
+#
+
+my $SIZEOF_LONG = length pack "l!", 0;
+
+sub refresh {
+   my ($self) = @_;
+
+   delete $self->{overlay};
+
+   my $text = $self->{text};
+
+   return unless length $text;
+
+   my ($row, $col) = $self->screen_cur;
+
+   my $idx = 0;
+
+   my @rend = map {
+      my $rstyle = $self->{caret} == $idx ? urxvt::OVERLAY_RSTYLE : $self->rstyle;
+
+      $rstyle |= urxvt::RS_Uline   if $_ & (urxvt::XIMUnderline | urxvt::XIMPrimary);
+      $rstyle |= urxvt::RS_RVid    if $_ & (urxvt::XIMReverse   | urxvt::XIMSecondary);
+      $rstyle |= urxvt::RS_Blink   if $_ & (urxvt::XIMHighlight | urxvt::XIMTertiary);
+
+      ($rstyle) x ($self->strwidth (substr $text, $idx++, 1))
+   } unpack "l!*", $self->{rend};
+
+   if ($self->{caret} >= length $text) {
+      $text .= " ";
+      push @rend, urxvt::OVERLAY_RSTYLE;
+   }
+
+   $self->{overlay} = $self->overlay ($col, $row, $self->strwidth ($text), 1, $self->rstyle, 0);
+   $self->{overlay}->set (0, 0, $self->special_encode ($text), \@rend);
+}
+
+sub on_xim_preedit_start {
+   my ($self) = @_;
+
+   ()
+}
+
+sub on_xim_preedit_done {
+   my ($self) = @_;
+
+   delete $self->{overlay};
+   delete $self->{text};
+   delete $self->{rend};
+
+   ()
+}
+
+sub on_xim_preedit_caret {
+   my ($self, $pos, $dir, $style) = @_;
+   warn "preedit_caret(@_)\n";
+   ()
+}
+
+sub on_xim_preedit_draw {
+   my ($self, $caret, $pos, $len, $feedback, $chars) = @_;
+
+   $self->{caret} = $caret;
+
+   substr $self->{rend}, $pos * $SIZEOF_LONG, $len * $SIZEOF_LONG, $feedback;
+   substr $self->{text}, $pos               , $len               , $chars if defined $feedback || !defined $chars;
+
+   $self->refresh;
+
+   ()
+}
+
+
index fec8febfe1514c2eb8ec726ffffe7e2da821a003..2a171f5b46d26843ebcb3f07c2a0bbc759dde70f 100644 (file)
@@ -17,6 +17,7 @@
 #if ENABLE_FRILLS
 # define ENABLE_XEMBED 1
 # define ENABLE_EWMH   1
+# define ENABLE_XIM_ONTHESPOT 1
 # define CURSOR_BLINK  1
 #else
 # define ENABLE_MINIMAL 1
@@ -738,6 +739,11 @@ enum {
 #define dLocal(type,name)       type const name = this->name
 #define dDisp                  Display *disp = this->display->display
 
+// for speed reasons, we assume that all latin1 characters
+// are single-width (the first unicdoe combining character
+// is actually 0x300, but ascii is what matters most).
+#define WCWIDTH(c) ((c) < 0x100 ? 1 : wcwidth (c))
+
 /* convert pixel dimensions to row/column values.  Everything as int32_t */
 #define Pixel2Col(x)            Pixel2Width((int32_t)(x))
 #define Pixel2Row(y)            Pixel2Height((int32_t)(y))
index bd52e39806245d133b6ea4ccd8d153200ba45f32..65d71fe74c953c76446c019b6482658fc01a9e31 100644 (file)
@@ -175,26 +175,11 @@ rxvt_drawable::operator XftDraw *()
 
 /////////////////////////////////////////////////////////////////////////////
 
-static void *enc_buf;
-static uint32_t enc_len;
-
-static inline void *
-get_enc_buf (uint32_t len)
-{
-  if (len > enc_len)
-    {
-      free (enc_buf);
-      enc_buf = malloc (len);
-      enc_len = len;
-    }
-
-  return enc_buf;
-}
-
 static const char *
 enc_char (const text_t *text, uint32_t len, codeset cs, bool &zero)
 {
-  uint8_t *buf = (uint8_t *)get_enc_buf (len);
+  uint8_t *buf = rxvt_temp_buf<uint8_t> (len);
+  uint8_t *res = buf;
 
   while (len--)
     {
@@ -209,13 +194,14 @@ enc_char (const text_t *text, uint32_t len, codeset cs, bool &zero)
       *buf++ = c;
     }
 
-  return (const char *)enc_buf;
+  return (const char *)res;
 }
 
 static const XChar2b *
 enc_xchar2b (const text_t *text, uint32_t len, codeset cs, bool &zero)
 {
-  XChar2b *buf = (XChar2b *)get_enc_buf (len * sizeof (XChar2b));
+  XChar2b *buf = rxvt_temp_buf<XChar2b> (len);
+  XChar2b *res = buf;
 
   while (len--)
     {
@@ -232,7 +218,7 @@ enc_xchar2b (const text_t *text, uint32_t len, codeset cs, bool &zero)
       buf++;
     }
 
-  return (XChar2b *)enc_buf;
+  return res;
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -1282,7 +1268,7 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
   clear_rect (d, x, y, term->fwidth * len, term->fheight, bg);
 
   XGlyphInfo extents;
-  XftGlyphSpec *enc = (XftGlyphSpec *)get_enc_buf (len * sizeof (XftGlyphSpec));
+  XftGlyphSpec *enc = (XftGlyphSpec *)rxvt_temp_buf (len * sizeof (XftGlyphSpec));
   XftGlyphSpec *ep = enc;
 
   dTermDisplay;
index 147b8302d1efeda02a365b2bf5da5528035e209e..2449a06bf84ff58fa624a3a3458f7008da8a6f7b 100644 (file)
@@ -22,7 +22,8 @@ enum data_type {
   DT_LONG,
   DT_STR,     // 0-terminates string
   DT_STR_LEN, // string + length
-  DT_WCS_LEN, // wstring + length
+  DT_WCS_LEN, // wchar_t* + length
+  DT_LCS_LEN, // long* + length
   DT_XEVENT,
 };
 
index f7439ab7c4b967880d298bd8395b710d0bf32dba..9dc23a7f33cb4bdbae379ef93d38e067dada2044 100644 (file)
@@ -556,8 +556,9 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...)
               case DT_STR_LEN:
                 {
                   char *str = va_arg (ap, char *);
-                  int len = va_arg (ap, int);
+                  int len   = va_arg (ap, int);
 
+                  printf ("pushing str %p:%d\n", str,len);//D
                   XPUSHs (sv_2mortal (newSVpvn (str, len)));
                 }
                 break;
@@ -565,21 +566,30 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...)
               case DT_WCS_LEN:
                 {
                   wchar_t *wstr = va_arg (ap, wchar_t *);
-                  int wlen = va_arg (ap, int);
+                  int wlen      = va_arg (ap, int);
 
                   XPUSHs (sv_2mortal (wcs2sv (wstr, wlen)));
                 }
                break;
 
+              case DT_LCS_LEN:
+                {
+                  long *lstr = va_arg (ap, long *);
+                  int llen   = va_arg (ap, int);
+
+                  XPUSHs (sv_2mortal (newSVpvn ((char *)lstr, llen * sizeof (long))));
+                }
+               break;
+
               case DT_XEVENT:
                 {
                   XEvent *xe = va_arg (ap, XEvent *);
                   HV *hv = newHV ();
 
-#           define set(name, sv) hv_store (hv, # name,  sizeof (# name) - 1, sv, 0)
-#           define setiv(name, val) hv_store (hv, # name,  sizeof (# name) - 1, newSViv (val), 0)
-#           define setuv(name, val) hv_store (hv, # name,  sizeof (# name) - 1, newSVuv (val), 0)
-#           undef set
+#                 define set(name, sv) hv_store (hv, # name,  sizeof (# name) - 1, sv, 0)
+#                 define setiv(name, val) hv_store (hv, # name,  sizeof (# name) - 1, newSViv (val), 0)
+#                 define setuv(name, val) hv_store (hv, # name,  sizeof (# name) - 1, newSVuv (val), 0)
+#                 undef set
 
                   setiv (type,       xe->type);
                   setiv (send_event, xe->xany.send_event);
@@ -718,6 +728,9 @@ rxvt_perl_interp::invoke (rxvt_term *term, hook_type htype, ...)
     {
       clearSVptr ((SV *)term->perl.self);
       SvREFCNT_dec ((SV *)term->perl.self);
+      
+      // don't allow further calls
+      term->perl.self = 0;
     }
 
   swap (perl_environ, environ);
@@ -844,6 +857,30 @@ BOOT:
     const_iv (ColormapNotify),
     const_iv (ClientMessage),
     const_iv (MappingNotify),
+#   if ENABLE_XIM_ONTHESPOT
+    const_iv (XIMReverse),
+    const_iv (XIMUnderline),
+    const_iv (XIMHighlight),
+    const_iv (XIMPrimary),
+    const_iv (XIMSecondary),
+    const_iv (XIMTertiary),
+    const_iv (XIMVisibleToForward),
+    const_iv (XIMVisibleToBackword),
+    const_iv (XIMVisibleToCenter),
+
+    const_iv (XIMForwardChar),
+    const_iv (XIMBackwardChar),
+    const_iv (XIMForwardWord),
+    const_iv (XIMBackwardWord),
+    const_iv (XIMCaretUp),
+    const_iv (XIMCaretDown),
+    const_iv (XIMNextLine),
+    const_iv (XIMPreviousLine),
+    const_iv (XIMLineStart),
+    const_iv (XIMLineEnd),
+    const_iv (XIMAbsolutePosition),
+    const_iv (XIMDontChange),
+#   endif
   };
 
   for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]);
@@ -1246,14 +1283,12 @@ rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start
 
         if (GIMME_V != G_VOID)
           {
-            wchar_t *wstr = new wchar_t [THIS->ncol];
+            wchar_t *wstr = rxvt_temp_buf<wchar_t> (THIS->ncol);
 
             for (int col = 0; col < THIS->ncol; col++)
               wstr [col] = l.t [col];
 
             XPUSHs (sv_2mortal (wcs2sv (wstr, THIS->ncol)));
-
-            delete [] wstr;
           }
 
         if (new_text)
@@ -1356,35 +1391,41 @@ rxvt_term::special_encode (SV *string)
 {
         wchar_t *wstr = sv2wcs (string);
         int wlen = wcslen (wstr);
-        wchar_t *rstr = new wchar_t [wlen]; // cannot become longer
+        wchar_t *rstr = rxvt_temp_buf<wchar_t> (wlen * 2); // cannot become longer
 
        rxvt_push_locale (THIS->locale);
 
         wchar_t *r = rstr;
         for (wchar_t *s = wstr; *s; s++)
-          if (wcwidth (*s) == 0)
-            {
-              if (r == rstr)
-                croak ("leading combining character unencodable");
+          {
+            int w = WCWIDTH (*s);
+
+            if (w == 0)
+              {
+                if (r == rstr)
+                  croak ("leading combining character unencodable");
 
-              unicode_t n = rxvt_compose (r[-1], *s);
-              if (n == NOCHAR)
-                n = rxvt_composite.compose (r[-1], *s);
+                unicode_t n = rxvt_compose (r[-1], *s);
+                if (n == NOCHAR)
+                  n = rxvt_composite.compose (r[-1], *s);
 
-              r[-1] = n;
-            }
+                r[-1] = n;
+              }
 #if !UNICODE_3
-          else if (*s >= 0x10000)
-            *r++ = rxvt_composite.compose (*s);
+            else if (*s >= 0x10000)
+              *r++ = rxvt_composite.compose (*s);
 #endif
-          else
-            *r++ = *s;
+            else
+              *r++ = *s;
+
+            // the *2 above only allows wcwidth <= 2
+            if (w > 1)
+              *r++ = NOCHAR;
+          }
 
        rxvt_pop_locale ();
 
         RETVAL = wcs2sv (rstr, r - rstr);
-
-        delete [] rstr;
 }
        OUTPUT:
         RETVAL
@@ -1406,7 +1447,7 @@ rxvt_term::special_decode (SV *text)
           else
             dlen++;
 
-        wchar_t *rstr = new wchar_t [dlen];
+        wchar_t *rstr = rxvt_temp_buf<wchar_t> (dlen);
 
         // decode
         wchar_t *r = rstr;
@@ -1419,8 +1460,6 @@ rxvt_term::special_decode (SV *text)
             *r++ = *s;
 
         RETVAL = wcs2sv (rstr, r - rstr);
-
-        delete [] rstr;
 }
        OUTPUT:
         RETVAL
index 3e79ad42b4e907254b3413fc7c90e1b638f451c2..078c422d004a4fef3d66d43f840359de4fc555e5 100644 (file)
@@ -95,6 +95,7 @@ void refcache<T>::clear ()
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef USE_XIM
+
 static void
 #if XIMCB_PROTO_BROKEN
 im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3)
@@ -135,6 +136,7 @@ rxvt_xim::~rxvt_xim ()
   if (xim)
     XCloseIM (xim);
 }
+
 #endif
 
 /////////////////////////////////////////////////////////////////////////////
index 8bb4a3fad2273d4f7b0861e14ec80f10fdc1e5d5..bf1baa418b8b76d354cbf6830130db360a3074b1 100644 (file)
@@ -38,5 +38,20 @@ zero_initialized::operator delete (void *p, size_t s)
   free (p);
 }
 
+static void *temp_buf;
+static uint32_t temp_len;
+
+void *
+rxvt_temp_buf (int len)
+{
+  if (len > temp_len)
+    { 
+      free (temp_buf);
+      temp_buf = malloc (len);
+      temp_len = len;
+    }
+  
+  return temp_buf;
+}
 
 
index 2e62cc36020bfded7b63610100041367cb4c9841..2a3ef5bc37bff53b65f6ad6b616d8fb7acc8d163 100644 (file)
@@ -398,5 +398,15 @@ struct stringvec : simplevec<char *>
   }
 };
 
+// return a very temporary (and never deallocated) buffer. keep small.
+void *rxvt_temp_buf (int len);
+
+template<typename T>
+inline T *
+rxvt_temp_buf (int len)
+{
+  return (T *)rxvt_temp_buf (len * sizeof (T));
+}
+
 #endif
 
index 0e11e3891d91f2bd8427072e9206f4d77c55a578..198544668369dfea5e998f798cd46cb1f12fd647 100644 (file)
@@ -844,11 +844,11 @@ rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) NOTHROW
       if (IN_RANGE_INC (c, 0xd800, 0xdfff))
         c = 0xfffd;
 
-      // rely on wcwidth to tell us the character width, at least for non-latin1
-      // do wcwidth before further replacements, as wcwidth might return -1
-      // for the line drawing characters below as they might be invalid in the current
+      // rely on wcwidth to tell us the character width, do wcwidth before
+      // further replacements, as wcwidth might return -1 for the line
+      // drawing characters below as they might be invalid in the current
       // locale.
-      int width = c < 0x100 ? 1 : wcwidth (c);
+      int width = WCWIDTH (c);
 
       if (charsets [screen.charset] == '0') // DEC SPECIAL
         {
index 9793c908ff1d5c0bd39259a9a10e7305f0d74871..f2f314bd15daa4942c4d71c2e717443762dc0554 100644 (file)
@@ -372,9 +372,8 @@ trying to map (display) the toplevel and returning to the mainloop.
 
 =item on_destroy $term
 
-Called whenever something tries to destroy terminal, before doing anything
-yet. If this hook returns true, then destruction is skipped, but this is
-rarely a good idea.
+Called whenever something tries to destroy terminal, when the terminal is
+still fully functional (not for long, though).
 
 =item on_reset $term