Index: Makefile.in
===================================================================
--- Makefile.in	(revision 5ff830a145bf5f2e869a06f9dc2d43f97773d189)
+++ Makefile.in	(revision 5ff830a145bf5f2e869a06f9dc2d43f97773d189)
@@ -26,5 +26,5 @@
      keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
      aim.c buddy.c buddylist.c timer.c style.c stylefunc.c errqueue.c \
-     zbuddylist.c muxevents.c popexec.c obarray.c wcwidth.c glib_compat.c
+     zbuddylist.c muxevents.c popexec.c obarray.c
 OWL_SRC = owl.c
 TESTER_SRC = tester.c
Index: aim.c
===================================================================
--- aim.c	(revision 34509d514dfa9ee441febffc6d61e108962d1507)
+++ aim.c	(revision 9854278fd0ac47586e8157e1efa798dd2583d81e)
@@ -948,5 +948,5 @@
   
   if (modname) {
-    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(modname)+4+1))) {
+    if (!(filename = malloc(strlen(priv->aimbinarypath)+1+strlen(modname)+4+1))) {
       /* perror("memrequest: malloc"); */
       return -1;
@@ -954,5 +954,5 @@
     sprintf(filename, "%s/%s.ocm", priv->aimbinarypath, modname);
   } else {
-    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(defaultmod)+1))) {
+    if (!(filename = malloc(strlen(priv->aimbinarypath)+1+strlen(defaultmod)+1))) {
       /* perror("memrequest: malloc"); */
       return -1;
@@ -964,5 +964,5 @@
     if (!modname) {
       /* perror("memrequest: stat"); */
-      owl_free(filename);
+      free(filename);
       return -1;
     }
@@ -986,5 +986,5 @@
     int i;
     
-    owl_free(filename); /* not needed */
+    free(filename); /* not needed */
     owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
     i = 8;
@@ -993,5 +993,5 @@
     }
     
-    if (!(buf = owl_malloc(i))) {
+    if (!(buf = malloc(i))) {
       return -1;
     }
@@ -1017,6 +1017,6 @@
     *buflenret = i;
   } else {
-    if (!(buf = owl_malloc(len))) {
-      owl_free(filename);
+    if (!(buf = malloc(len))) {
+      free(filename);
       return -1;
     }
@@ -1024,15 +1024,15 @@
     if (!(f = fopen(filename, "r"))) {
       /* perror("memrequest: fopen"); */
-      owl_free(filename);
-      owl_free(buf);
+      free(filename);
+      free(buf);
       return -1;
     }
     
-    owl_free(filename);
+    free(filename);
     
     if (fseek(f, offset, SEEK_SET) == -1) {
       /* perror("memrequest: fseek"); */
       fclose(f);
-      owl_free(buf);
+      free(buf);
       return -1;
     }
@@ -1041,5 +1041,5 @@
       /* perror("memrequest: fread"); */
       fclose(f);
-      owl_free(buf);
+      free(buf);
       return -1;
     }
@@ -1076,5 +1076,5 @@
   if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {
     aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-    owl_free(buf);
+    free(buf);
   } else {
     owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
@@ -1342,10 +1342,10 @@
       int z;
       
-      newbuf = owl_malloc(i+1);
+      newbuf = malloc(i+1);
       for (z = 0; z < i; z++)
 	newbuf[z] = (z % 10)+0x30;
       newbuf[i] = '\0';
       /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_ACK | AIM_IMFLAGS_AWAY, newbuf); */
-      owl_free(newbuf);
+      free(newbuf);
     }
   } else if (strstr(tmpstr, "seticqstatus")) {
Index: cmd.c
===================================================================
--- cmd.c	(revision 34509d514dfa9ee441febffc6d61e108962d1507)
+++ cmd.c	(revision 6922eddf979a8bdbf46a21cad138b787a7719f46)
@@ -74,5 +74,5 @@
   owl_cmd *cmd;
 
-  tmpbuff=owl_strdup(cmdbuff);
+  tmpbuff=strdup(cmdbuff);
   argv=owl_parseline(tmpbuff, &argc);
   if (argc < 0) {
Index: config.h.in
===================================================================
--- config.h.in	(revision e23eb2b7a8b842ee6ac86fc356ffe7831757dd87)
+++ config.h.in	(revision 03cf6b91158dd0823c7329b8c4b0a28d3748b5e6)
@@ -22,4 +22,7 @@
 #undef HAVE_LIBCOM_ERR
 
+/* Define to 1 if you have the `curses' library (-lcurses). */
+#undef HAVE_LIBCURSES
+
 /* Define to 1 if you have the `des425' library (-ldes425). */
 #undef HAVE_LIBDES425
@@ -36,4 +39,7 @@
 /* Define to 1 if you have the `krb5' library (-lkrb5). */
 #undef HAVE_LIBKRB5
+
+/* Define to 1 if you have the `ncurses' library (-lncurses). */
+#undef HAVE_LIBNCURSES
 
 /* Define to 1 if you have the `ncursesw' library (-lncursesw). */
Index: configure.in
===================================================================
--- configure.in	(revision e23eb2b7a8b842ee6ac86fc356ffe7831757dd87)
+++ configure.in	(revision 18e28a410181648e32a57fac7edf9942a364a49d)
@@ -12,6 +12,4 @@
 fi
 
-m4_include(/usr/share/aclocal/pkg.m4)
-dnl m4_include(pkg.m4)
 
 dnl Check for Athena
@@ -46,5 +44,7 @@
 fi
 
-AC_CHECK_LIB(ncursesw, initscr,, AC_MSG_ERROR(No curses library found.))
+AC_CHECK_LIB(ncursesw, initscr,,
+  AC_CHECK_LIB(ncurses, initscr,,
+    AC_CHECK_LIB(curses, initscr,, AC_MSG_ERROR(No curses library found.))))
 AC_CHECK_LIB(com_err, com_err)
 AC_CHECK_LIB(nsl, gethostbyname)
@@ -109,13 +109,4 @@
 LDFLAGS=${LDFLAGS}\ ${FOO}
 
-dnl Add CFLAGS and LDFLAGS for glib-2.0
-PKG_CHECK_MODULES(GLIB,glib-2.0)
-
-echo Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}
-CFLAGS=${CFLAGS}\ ${GLIB_CFLAGS}
-echo Adding glib-2.0 LDFLAGS ${GLIB_LIBS}
-LDFLAGS=${LDFLAGS}\ ${GLIB_LIBS}
-
-
 dnl Checks for typedefs, structures, and compiler characteristics.
 
Index: editwin.c
===================================================================
--- editwin.c	(revision b2c1bd487feab1fdd38e282d70efa20f4de0635a)
+++ editwin.c	(revision cc6f009750d9fa16a07d5f504a57c299f6a1d646)
@@ -143,10 +143,9 @@
   e->buffy=0;
   owl_editwin_overwrite_string(e, text);
-  owl_editwin_overwrite_char(e, '\0');
   e->lock=strlen(text);
   /* if (text[e->lock-1]=='\n') e->lock--; */
-  /*  e->buffx=x; */
-  /*  e->buffy=y; */
-  _owl_editwin_set_xy_by_index(e, e->lock);
+  e->buffx=x;
+  e->buffy=y;
+  owl_editwin_adjust_for_locktext(e);
   owl_editwin_redisplay(e, 0);
 }
@@ -256,90 +255,55 @@
 
   /* start at topline */
-  ptr1 = e->buff;
-  for (i = 0; i < e->topline; i++) {
-    ptr2 = strchr(ptr1, '\n');
+  ptr1=e->buff;
+  for (i=0; i<e->topline; i++) {
+    ptr2=strchr(ptr1, '\n');
     if (!ptr2) {
       /* we're already on the last line */
       break;
     }
-    ptr1 = ptr2 + 1;
+    ptr1=ptr2+1;
   }
   /* ptr1 now stores the starting point */
 
   /* find the ending point and store it in ptr3 */
-  ptr2 = ptr1;
-  ptr3 = ptr1;
-  for (i = 0; i < e->winlines; i++) {
-    ptr3 = strchr(ptr2, '\n');
+  ptr2=ptr1;
+  ptr3=ptr1;
+  for (i=0; i<e->winlines; i++) {
+    ptr3=strchr(ptr2, '\n');
     if (!ptr3) {
       /* we've hit the last line */
       /* print everything to the end */
-      ptr3 = e->buff + e->bufflen - 1;
+      ptr3=e->buff+e->bufflen-1;
       ptr3--;
       break;
     }
-    ptr2 = ptr3 + 1;
-  }
-  ptr3 += 2;
-
-  buff = owl_malloc(ptr3 - ptr1 + 50);
-  strncpy(buff, ptr1, ptr3 - ptr1);
-  buff[ptr3 - ptr1] = '\0';
-  if (e->echochar == '\0') {
+    ptr2=ptr3+1;
+  }
+  ptr3+=2;
+
+  buff=owl_malloc(ptr3-ptr1+50);
+  strncpy(buff, ptr1, ptr3-ptr1);
+  buff[ptr3-ptr1]='\0';
+  if (e->echochar=='\0') {
     waddstr(e->curswin, buff);
   } else {
     /* translate to echochar, *except* for the locktext */
     int len;
-    int dolocklen = e->lock - (ptr1 - e->buff);
-    char *locktext;
-    char tmp = e->buff[dolocklen];
-
-    e->buff[dolocklen] = '\0';
-    locktext = owl_strdup(e->buff);
-    e->buff[dolocklen] = tmp;
-
-    waddstr(e->curswin, locktext);
-    
-    len = strlen(buff);
-    for (i = 0; i < len-dolocklen; i++) {
+    int dolocklen=e->lock-(ptr1-e->buff);
+
+    for (i=0; i<dolocklen; i++) {
+      waddch(e->curswin, buff[i]);
+    }
+    len=strlen(buff);
+    for (i=0; i<len-dolocklen; i++) {
       waddch(e->curswin, e->echochar);
     }
   }
-  wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
+  wmove(e->curswin, e->buffy-e->topline, e->buffx);
   wnoutrefresh(e->curswin);
-  if (update == 1) {
+  if (update==1) {
     doupdate();
   }
   owl_free(buff);
-}
-
-/* Remove n bytes at cursor. */
-void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
-{
-  int i = _owl_editwin_get_index_from_xy(e) + n;
-  for (; i < e->bufflen; i++) {
-    e->buff[i-n] = e->buff[i];
-  }
-  
-  e->bufflen -= n;
-  e->buff[e->bufflen] = '\0';
-}
-
-/* Insert n bytes at cursor.*/
-void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
-{
-  int i, z;
-  
-  if ((e->bufflen + n) > (e->allocated - 5)) {
-    _owl_editwin_addspace(e);
-  }
-
-  e->bufflen += n;
-  e->buff[e->bufflen] = '\0';
-  
-  z = _owl_editwin_get_index_from_xy(e);
-  for (i = e->bufflen - 1; i > z; i--) {
-    e->buff[i] = e->buff[i - n];
-  }
 }
 
@@ -351,33 +315,24 @@
 int _owl_editwin_linewrap_word(owl_editwin *e)
 {
-  int x, y;
-  int i;
-  char *ptr1, *start;
-  gunichar c;
-
-  /* saving values */
-  x = e->buffx;
-  y = e->buffy;
-  start = e->buff + e->lock;
-
-  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  ptr1 = g_utf8_find_prev_char(start, ptr1);
-
-  while (ptr1) {
-    c = g_utf8_get_char(ptr1);
-    if (owl_util_can_break_after(c)) {
-      if (c != ' ') {
-        i = ptr1 - e->buff;
-        _owl_editwin_set_xy_by_index(e, i);
-        _owl_editwin_insert_bytes(e, 1);
-        /* _owl_editwin_insert_bytes may move e->buff. */
-        ptr1 = e->buff + i;
-      }
-      *ptr1 = '\n';
-      return 0;
-    }
-    ptr1 = g_utf8_find_prev_char(start, ptr1);
-  }
-  return -1;
+  int i, z;
+
+  z=_owl_editwin_get_index_from_xy(e);
+  /* move back and line wrap the previous word */
+  for (i=z-1; ; i--) {
+    /* move back until you find a space or hit the beginning of the line */
+    if (e->buff[i]==' ') {
+      /* replace the space with a newline */
+      e->buff[i]='\n';
+      e->buffy++;
+      e->buffx=z-i-1;
+      /* were we on the last line */
+      return(0);
+    } else if (e->buff[i]=='\n' || i<=e->lock) {
+      /* we hit the begginning of the line or the buffer, we cannot
+       * wrap.
+       */
+      return(-1);
+    }
+  }
 }
 
@@ -385,16 +340,15 @@
  * characters over)
  */
-void owl_editwin_insert_char(owl_editwin *e, gunichar c)
-{
-  int z, i, ret, len;
-  char tmp[6];
-  memset(tmp, '\0', 6);
+void owl_editwin_insert_char(owl_editwin *e, char c)
+{
+  
+  int z, i, ret;
 
   /* \r is \n */
-  if (c == '\r') {
-    c = '\n';
-  }
-
-  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
+  if (c=='\r') {
+    c='\n';
+  }
+
+  if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     /* perhaps later this will change some state that allows the string
        to be read */
@@ -402,19 +356,16 @@
   }
 
-  g_unichar_to_utf8(c, tmp);
-  len = strlen(tmp);
-
   /* make sure there is enough memory for the new text */
-  if ((e->bufflen + len) > (e->allocated - 5)) {
+  if ((e->bufflen+1) > (e->allocated-5)) {
     _owl_editwin_addspace(e);
   }
 
   /* get the insertion point */
-  z = _owl_editwin_get_index_from_xy(e);
+  z=_owl_editwin_get_index_from_xy(e);
 
   /* If we're going to insert at the last column do word wrapping, unless it's a \n */
-  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
-    ret = _owl_editwin_linewrap_word(e);
-    if (ret == -1) {
+  if ((e->buffx+1==e->wrapcol) && (c!='\n')) {
+    ret=_owl_editwin_linewrap_word(e);
+    if (ret==-1) {
       /* we couldn't wrap, insert a hard newline instead */
       owl_editwin_insert_char(e, '\n');
@@ -422,36 +373,37 @@
   }
 
+  z=_owl_editwin_get_index_from_xy(e);
   /* shift all the other characters right */
-  if (z != e->bufflen) {
-    _owl_editwin_insert_bytes(e, len);
-  }
-
-  /* insert the new character */
-  for(i = 0; i < len; i++) {
-    e->buff[z + i] = tmp[i];
-  }
+  for (i=e->bufflen; i>z; i--) {
+    e->buff[i]=e->buff[i-1];
+  }
+
+  /* insert the new one */
+  e->buff[z]=c;
 
   /* housekeeping */
-  e->bufflen += len;
-  e->buff[e->bufflen] = '\0';
+  e->bufflen++;
+  e->buff[e->bufflen]='\0';
+
+  /* advance the cursor */
+  if (c=='\n') {
+    e->buffx=0;
+    e->buffy++;
+  } else {
+    e->buffx++;
+  }
+}
+
+/* overwrite the character at the current point with 'c' */
+void owl_editwin_overwrite_char(owl_editwin *e, char c)
+{
+  int z;
   
-  /* advance the cursor */
-  z += len;
-  _owl_editwin_set_xy_by_index(e, z);
-}
-
-/* overwrite the character at the current point with 'c' */
-void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
-{
-  int z, oldlen, newlen, i;
-  char tmp[6];
-  memset(tmp, '\0', 6);
-
   /* \r is \n */
-  if (c == '\r') {
-    c = '\n';
-  }
-  
-  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
+  if (c=='\r') {
+    c='\n';
+  }
+
+  if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     /* perhaps later this will change some state that allows the string
        to be read */
@@ -459,40 +411,29 @@
   }
 
-  g_unichar_to_utf8(c, tmp);
-  newlen = strlen(tmp);
-
-  z = _owl_editwin_get_index_from_xy(e);
-  {
-    char *t = g_utf8_find_next_char(e->buff + z, NULL);
-    oldlen = (t ? (t - (e->buff + z)) : 0);
-  }
-
-  /* only if we are at the end of the buffer do we create new space here */
-  if (z == e->bufflen) {
-    if ((e->bufflen+newlen) > (e->allocated-5)) {
+  z=_owl_editwin_get_index_from_xy(e);
+
+  /* only if we are at the end of the buffer do we create new space */
+  if (z==e->bufflen) {
+    if ((e->bufflen+1) > (e->allocated-5)) {
       _owl_editwin_addspace(e);
     }
   }
-  /* if not at the end of the buffer, adjust based in char size difference. */ 
-  else if (oldlen > newlen) {
-    _owl_editwin_remove_bytes(e, oldlen-newlen);
-  }
-  else /* oldlen < newlen */ {
-    _owl_editwin_insert_bytes(e, newlen-oldlen);
-  }
-  /* Overwrite the old char*/
-  for (i = 0; i < newlen; i++) {
-    e->buff[z+i] = tmp[i];
-  }
-       
-  /* housekeeping */
-  if (z == e->bufflen) {
-    e->bufflen += newlen;
-    e->buff[e->bufflen] = '\0';
-  }
   
+  e->buff[z]=c;
+
+  /* housekeeping if we are at the end of the buffer */
+  if (z==e->bufflen) {
+    e->bufflen++;
+    e->buff[e->bufflen]='\0';
+  }
+
   /* advance the cursor */
-  z += newlen;
-  _owl_editwin_set_xy_by_index(e, z);
+  if (c=='\n') {
+    e->buffx=0;
+    e->buffy++;
+  } else {
+    e->buffx++;
+  }
+
 }
 
@@ -502,23 +443,18 @@
 void owl_editwin_delete_char(owl_editwin *e)
 {
-  int z;
-  char *p1, *p2;
-  gunichar c;
-
-  if (e->bufflen == 0) return;
+  int z, i;
+
+  if (e->bufflen==0) return;
   
   /* get the deletion point */
-  z = _owl_editwin_get_index_from_xy(e);
-
-  if (z == e->bufflen) return;
-
-  p1 = e->buff + z;
-  p2 = g_utf8_next_char(p1);
-  c = g_utf8_get_char(p2);
-  while (g_unichar_ismark(c)) {
-    p2 = g_utf8_next_char(p2);
-    c = g_utf8_get_char(p2);
-  }
-  _owl_editwin_remove_bytes(e, p2-p1);
+  z=_owl_editwin_get_index_from_xy(e);
+
+  if (z==e->bufflen) return;
+
+  for (i=z; i<e->bufflen; i++) {
+    e->buff[i]=e->buff[i+1];
+  }
+  e->bufflen--;
+  e->buff[e->bufflen]='\0';
 }
 
@@ -531,43 +467,25 @@
 {
   int z;
-  char *p1, *p2, *p3, *tmp;
-
-  if (e->bufflen == 0) return;
+  char tmp;
+
+  if (e->bufflen==0) return;
   
   /* get the cursor point */
-  z = _owl_editwin_get_index_from_xy(e);
-
-  if (z == e->bufflen) {
+  z=_owl_editwin_get_index_from_xy(e);
+
+  if (z==e->bufflen) {
     /* point is after last character */
     z--;
   }  
 
-  if (z - 1 < e->lock) {
+  if (z-1 < e->lock) {
     /* point is at beginning of buffer, do nothing */
     return;
   }
 
-  /* Transpose two utf-8 unicode glyphs. */
-  p1 = e->buff + z;
-
-  p2 = g_utf8_find_next_char(p1, NULL);
-  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
-    p2 = g_utf8_find_next_char(p2, NULL);
-  }
-  if (p2 == NULL) return;
-
-  p3 = g_utf8_find_prev_char(e->buff, p1);
-  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
-    p3 = g_utf8_find_prev_char(p3, NULL);
-  }
-  if (p3 == NULL) return;
-
-  tmp = owl_malloc(p2 - p3 + 5);
-  *tmp = '\0';
-  strncat(tmp, p1, p2 - p1);
-  strncat(tmp, p3, p1 - p3);
-  strncpy(p3, tmp, p2 - p3);
-  owl_free(tmp);
-  _owl_editwin_set_xy_by_index(e, p3 - e->buff);
+  tmp=e->buff[z];
+  e->buff[z]=e->buff[z-1];
+  e->buff[z-1]=tmp;
+  owl_editwin_key_right(e);
 }
 
@@ -577,16 +495,9 @@
 void owl_editwin_insert_string(owl_editwin *e, char *string)
 {
-  char *p;
-  gunichar c;
-  if (!g_utf8_validate(string, -1, NULL)) {
-    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
-    return;
-  }
-  p = string;
-  c = g_utf8_get_char(p);
-  while (c) {
-    _owl_editwin_process_char(e, c);
-    p = g_utf8_next_char(p);
-    c = g_utf8_get_char(p);
+  int i, j;
+
+  j=strlen(string);
+  for (i=0; i<j; i++) {
+    owl_editwin_insert_char(e, string[i]);
   }
 }
@@ -598,17 +509,9 @@
 void owl_editwin_overwrite_string(owl_editwin *e, char *string)
 {
-  char *p;
-  gunichar c;
-
-  if (!g_utf8_validate(string, -1, NULL)) {
-    owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
-    return;
-  }
-  p = string;
-  c = g_utf8_get_char(p);
-  while (c) {
-    owl_editwin_overwrite_char(e, c);
-    p = g_utf8_next_char(p);
-    c = g_utf8_get_char(p);
+  int i, j;
+
+  j=strlen(string);
+  for (i=0; i<j; i++) {
+    owl_editwin_overwrite_char(e, string[i]);
   }
 }
@@ -621,106 +524,48 @@
   int i;
   char *ptr1, *ptr2;
-  gunichar c;
-
-  if (e->bufflen == 0) return(0);
+
+  if (e->bufflen==0) return(0);
   
   /* first go to the yth line */
-  ptr1 = e->buff;
-  for (i = 0; i < e->buffy; i++) {
-    ptr2= strchr(ptr1, '\n');
+  ptr1=e->buff;
+  for (i=0; i<e->buffy; i++) {
+    ptr2=strchr(ptr1, '\n');
     if (!ptr2) {
       /* we're already on the last line */
       break;
     }
-    ptr1 = ptr2 + 1;
-  }
-
-  /* now go to the xth cell */
-  ptr2 = ptr1;
-  i = 0;
-  while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
-    c = g_utf8_get_char(ptr2);
-    i += (c == '\n' ? 1 : mk_wcwidth(c));
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  if (ptr2 == NULL) return e->bufflen;
-  return(ptr2 - e->buff);
-}
-
-/* We assume x,y are not set to point to a mid-char */
-gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
-{
-  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
-}
-
+    ptr1=ptr2+1;
+  }
+
+  /* now go to the xth character */
+  ptr2=strchr(ptr1, '\n');
+  if (!ptr2) {
+    ptr2=e->buff+e->bufflen;
+  }
+
+  if ((ptr2-ptr1) < e->buffx) {
+    ptr1=ptr2-1;
+  } else {
+    ptr1+=e->buffx;
+  }
+
+  /* printf("DEBUG: index is %i\r\n", ptr1-e->buff); */
+  return(ptr1-e->buff);
+}
 
 void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
 {
-  char *ptr1, *ptr2, *target;
-  gunichar c;
-
-  e->buffx = 0;
-  e->buffy = 0;
-
-  ptr1 = e->buff;
-  target = ptr1 + index;
-  /* target sanitizing */
-  if ((target[0] & 0x80) && (~target[0] & 0x40)) {
-    /* middle of a utf-8 character, back up to previous character. */
-    target = g_utf8_find_prev_char(e->buff, target);
-  }
-  c = g_utf8_get_char(target);
-  while (g_unichar_ismark(c) && target > e->buff) {
-    /* Adjust the target off of combining characters and the like. */
-    target = g_utf8_find_prev_char(e->buff, target);
-    c = g_utf8_get_char(target);
-  }
-  /* If we start with a mark, something is wrong.*/
-  if (g_unichar_ismark(c)) return;
-
-  /* Now our target should be acceptable. */
-  ptr2 = strchr(ptr1, '\n');
-  while (ptr2 != NULL && ptr2 < target) {
-    e->buffy++;
-    ptr1 = ptr2 + 1;
-    ptr2 = strchr(ptr1, '\n');
-  }
-  ptr2 = ptr1;
-  while (ptr2 != NULL && ptr2 < target) {
-    c = g_utf8_get_char(ptr2);
-    e->buffx += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-}
-
-int _owl_editwin_cursor_adjustment(owl_editwin *e)
-{
-  char *ptr1, *ptr2;
-  gunichar c;
-  int x, i;
-
-  /* Find line */
-  ptr1 = e->buff;
-  ptr2 = strchr(ptr1, '\n');
-  for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
-    ptr1 = ptr2 + 1;
-    ptr2 = strchr(ptr1, '\n');
-  }
-  ptr2 = ptr1;
-
-  /* Find char */
-  x = 0;
-  while (ptr2 != NULL && x < e->buffx) {
-    if (*ptr2 == '\n') return 0;
-    c = g_utf8_get_char(ptr2);
-    x += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  
-  /* calculate x offset */
-  return x - e->buffx;
+  int z, i;
+
+  z=_owl_editwin_get_index_from_xy(e);
+  if (index>z) {
+    for (i=0; i<index-z; i++) {
+      owl_editwin_key_right(e);
+    }
+  } else if (index<z) {
+    for (i=0; i<z-index; i++) {
+      owl_editwin_key_left(e);
+    }
+  }
 }
 
@@ -729,5 +574,5 @@
   /* if we happen to have the cursor over locked text
    * move it to be out of the locktext region */
-  if (_owl_editwin_get_index_from_xy(e) < e->lock) {
+  if (_owl_editwin_get_index_from_xy(e)<e->lock) {
     _owl_editwin_set_xy_by_index(e, e->lock);
   }
@@ -749,6 +594,6 @@
 {
   if (e->buffy > 0) e->buffy--;
-  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
-    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
+  if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
+    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
   }
 
@@ -767,6 +612,6 @@
 
   /* if we're past the last character move back */
-  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
-    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
+  if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
+    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
   }
 
@@ -782,17 +627,15 @@
 void owl_editwin_key_left(owl_editwin *e)
 {
-  int i;
-  char * p;
-  i = _owl_editwin_get_index_from_xy(e);
-  p = e->buff + i;
-  p = g_utf8_find_prev_char(e->buff, p);
-  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
-    p = g_utf8_find_prev_char(e->buff, p);
-  }
-  if (p == NULL) p = e->buff;
-  _owl_editwin_set_xy_by_index(e, p - e->buff);
-
-  if (e->buffy - e->topline < 0) {
-    e->topline -= e->winlines / 2;
+  /* move left if we can, and maybe up a line */
+  if (e->buffx>0) {
+    e->buffx--;
+  } else if (e->buffy>0) {
+    e->buffy--;
+    e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
+  }
+
+  /* do we need to scroll up? */
+  if (e->buffy-e->topline < 0) {
+    e->topline-=e->winlines/2;
   }
 
@@ -804,21 +647,20 @@
 {
   int i;
-  char * p;
-  i = _owl_editwin_get_index_from_xy(e);
-  p = e->buff + i;
-  p = g_utf8_find_next_char(p, NULL);
-  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
-    p = g_utf8_find_next_char(p, NULL);
-  }
-  if (p == NULL) {
-    _owl_editwin_set_xy_by_index(e, e->bufflen);
-  }
-  else {
-    _owl_editwin_set_xy_by_index(e, p - e->buff);
+
+  /* move right if we can, and skip down a line if needed */
+  i=owl_editwin_get_numchars_on_line(e, e->buffy);
+  if (e->buffx < i) {
+    e->buffx++;
+    /*  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) { */
+  } else if (_owl_editwin_get_index_from_xy(e) < e->bufflen) {
+    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
+      e->buffx=0;
+      e->buffy++;
+    }
   }
 
   /* do we need to scroll down? */
-  if (e->buffy - e->topline >= e->winlines) {
-    e->topline += e->winlines / 2;
+  if (e->buffy-e->topline >= e->winlines) {
+    e->topline+=e->winlines/2;
   }
 }
@@ -827,5 +669,4 @@
 {
   int i, x;
-  gunichar c = '\0';
 
   /* if we're starting on a space, find the first non-space */
@@ -840,14 +681,12 @@
   }
 
-  /* find the next space, newline or end of line and go
-     there, if already at the end of the line, continue on to the next */
-  i=owl_editwin_get_numcells_on_line(e, e->buffy);
-  c = _owl_editwin_get_char_at_xy(e);
+  /* find the next space, newline or end of line and go there, if
+     already at the end of the line, continue on to the next */
+  i=owl_editwin_get_numchars_on_line(e, e->buffy);
   if (e->buffx < i) {
     /* move right till end of line */
     while (e->buffx < i) {
-      owl_editwin_key_right(e);
-      c = _owl_editwin_get_char_at_xy(e);
-      if (c == ' ') return;
+      e->buffx++;
+      if (e->buff[_owl_editwin_get_index_from_xy(e)]==' ') return;
       if (e->buffx == i) return;
     }
@@ -855,5 +694,5 @@
     /* try to move down */
     if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
-      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
+      if (e->buffy+1 <  owl_editwin_get_numlines(e)) {
 	e->buffx=0;
 	e->buffy++;
@@ -868,42 +707,34 @@
 void owl_editwin_move_to_previousword(owl_editwin *e)
 {
-  int i;
-  gunichar c;
-  char *ptr1, *ptr2;
+  int i, x;
 
   /* are we already at the beginning of the word? */
-  c = _owl_editwin_get_char_at_xy(e);
-  i = _owl_editwin_get_index_from_xy(e);
-  ptr1 = e->buff + i;
-  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
-    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
-    c = g_utf8_get_char(ptr1);
-    if (c == ' ' || c == '\n') {
-      owl_editwin_key_left(e);      
-    }
-  }
-
+  i=_owl_editwin_get_index_from_xy(e);
+  if ( (e->buff[i]!=' ' && e->buff[i]!='\n' && e->buff[i]!='\0') &&
+       (e->buff[i-1]==' ' || e->buff[i-1]=='\n') ) {
+    owl_editwin_key_left(e);
+  }
+    
   /* are we starting on a space character? */
-  i = _owl_editwin_get_index_from_xy(e);
-  while (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0') {
+  i=_owl_editwin_get_index_from_xy(e);
+  if (e->buff[i]==' ' || e->buff[i]=='\n' || e->buff[i]=='\0') {
     /* find the first non-space */
-    owl_editwin_key_left(e);      
-    i = _owl_editwin_get_index_from_xy(e);
+    for (x=i; x>=e->lock; x--) {
+      if (e->buff[x]!=' ' && e->buff[x]!='\n' && e->buff[x]!='\0') {
+	_owl_editwin_set_xy_by_index(e, x);
+	break;
+      }
+    }
   }
 
   /* find the last non-space */
-  owl_editwin_key_left(e);
-  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  while (ptr1 >= e->buff + e->lock) {
-    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
-    if (!ptr2) break;
-    
-    c = g_utf8_get_char(ptr2);
-    if (c == ' ' || c == '\n'){
+  i=_owl_editwin_get_index_from_xy(e);
+  for (x=i; x>=e->lock; x--) {
+    if (e->buff[x-1]==' ' || e->buff[x-1]=='\n') {
+      _owl_editwin_set_xy_by_index(e, x);
       break;
     }
-    owl_editwin_key_left(e);
-    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  }
+  }
+  _owl_editwin_set_xy_by_index(e, x);
 }
 
@@ -911,36 +742,30 @@
 void owl_editwin_delete_nextword(owl_editwin *e)
 {
-  char *ptr1, *start;
-  gunichar c;
+  int z;
 
   if (e->bufflen==0) return;
 
-  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  /* if we start out on a space character then jump past all the
-     spaces up first */
-  while (*ptr1 == ' ' || *ptr1 == '\n') {
-    ++ptr1;
-  }
-
-  /* then jump past the next word */
-  
-  while (ptr1 && ptr1 - e->buff < e->bufflen) {
-    c = g_utf8_get_char(ptr1);
-    if (c == ' ' || c == '\n' || c == '\0') break;
-    ptr1 = g_utf8_find_next_char(ptr1, NULL);
-  }
-
-  if (ptr1) { /* We broke on a space, */
-    ptr1 = g_utf8_find_next_char(ptr1, NULL);
-    if (ptr1) { /* and there's a character after it, */
-      /* nuke everything back to our starting point. */
-      _owl_editwin_remove_bytes(e, ptr1 - start);
-      return;
-    }
-  }
-  
-  /* If we get here, we ran out of string, drop what's left. */
-  *start = '\0';
-  e->bufflen = start - e->buff;
+  /* if we start out on a space character then gobble all the spaces
+     up first */
+  while (1) {
+    z=_owl_editwin_get_index_from_xy(e);
+    if (e->buff[z]==' ' || e->buff[z]=='\n') {
+      owl_editwin_delete_char(e);
+    } else {
+      break;
+    }
+  }
+
+  /* then nuke the next word */
+  while (1) {
+    z=_owl_editwin_get_index_from_xy(e);
+    /* z == e->bufflen check added to prevent a hang I (nelhage) have
+       seen repeatedly while using owl. I'm not sure precisely what
+       conditions lead to it. */
+    if (z == e->bufflen
+        || e->buff[z+1]==' ' || e->buff[z+1]=='\n' || e->buff[z+1]=='\0') break;
+    owl_editwin_delete_char(e);
+  }
+  owl_editwin_delete_char(e);
 }
 
@@ -948,10 +773,12 @@
 {
   /* go backwards to the last non-space character, then delete chars */
-  int startpos, endpos;
+  int i, startpos, endpos;
 
   startpos = _owl_editwin_get_index_from_xy(e);
   owl_editwin_move_to_previousword(e);
   endpos = _owl_editwin_get_index_from_xy(e);
-  _owl_editwin_remove_bytes(e, startpos-endpos);
+  for (i=0; i<startpos-endpos; i++) {
+    owl_editwin_delete_char(e);
+  }
 }
 
@@ -960,5 +787,5 @@
   int i;
 
-  if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
+  if (owl_editwin_get_numchars_on_line(e, e->buffy)>e->buffx) {
     /* normal line */
     i=_owl_editwin_get_index_from_xy(e);
@@ -981,5 +808,5 @@
 void owl_editwin_move_to_line_end(owl_editwin *e)
 {
-  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
+  e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
 }
 
@@ -994,5 +821,5 @@
   /* go to last char */
   e->buffy=owl_editwin_get_numlines(e)-1;
-  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
+  e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
   owl_editwin_key_right(e);
 
@@ -1034,45 +861,38 @@
   /* main loop */
   while (1) {
-    i = _owl_editwin_get_index_from_xy(e);
+    i=_owl_editwin_get_index_from_xy(e);
 
     /* bail if we hit the end of the buffer */
-    if (i >= e->bufflen || e->buff[i] == '\0') break;
+    if (i>=e->bufflen) break;
 
     /* bail if we hit the end of the paragraph */
-    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
+    if (e->buff[i]=='\n' && e->buff[i+1]=='\n') break;
 
     /* if we've travelled too far, linewrap */
     if ((e->buffx) >= e->fillcol) {
-      int len = e->bufflen;
       _owl_editwin_linewrap_word(e);
-      /* we may have added a character. */
-      if (i < save) save += e->bufflen - len;
     }
 
     /* did we hit the end of a line too soon? */
-    /* asedeno: Here we replace a newline with a space. We may want to
-       consider removing the space if the characters to either side
-       are CJK ideograms.*/
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
+    i=_owl_editwin_get_index_from_xy(e);
+    if (e->buff[i]=='\n' && e->buffx<e->fillcol-1) {
       /* ********* we need to make sure we don't pull in a word that's too long ***********/
       e->buff[i]=' ';
     }
-
+    
     /* fix spacing */
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
-      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
+    i=_owl_editwin_get_index_from_xy(e);
+    if (e->buff[i]==' ' && e->buff[i+1]==' ') {
+      if (e->buff[i-1]=='.' || e->buff[i-1]=='!' || e->buff[i-1]=='?') {
 	owl_editwin_key_right(e);
       } else {
 	owl_editwin_delete_char(e);
-	/* if we did this ahead of the save point, adjust it. Changing
-           by one is fine here because we're only removing an ASCII
-           space. */
-	if (i < save) save--;
+	/* if we did this ahead of the save point, adjust it */
+	if (i<save) save--;
       }
     } else {
       owl_editwin_key_right(e);
     }
+
   }
 
@@ -1095,31 +915,23 @@
 int owl_editwin_check_dotsend(owl_editwin *e)
 {
-  char *p, *p_n, *p_p;
-  gunichar c;
+  int i;
 
   if (!e->dotsend) return(0);
-
-  p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
-  p_n = g_utf8_find_next_char(p, NULL);
-  p_p = g_utf8_find_prev_char(e->buff, p);
-  c = g_utf8_get_char(p);
-  while (p != NULL) {
-    if (*p == '.'
-	&& p_p != NULL && (*p_p == '\n' || *p_p == '\r')
-	&& p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
-      e->bufflen = p - e->buff;
-      e->buff[e->bufflen] = '\0';
+  for (i=e->bufflen-1; i>0; i--) {
+    if (e->buff[i] == '.' 
+	&& (e->buff[i-1] == '\n' || e->buff[i-1] == '\r')
+	&& (e->buff[i+1] == '\n' || e->buff[i+1] == '\r')) {
+      e->bufflen = i;
+      e->buff[i] = '\0';
       return(1);
     }
-    if (c != '\0' && !g_unichar_isspace(c)) return(0);
-    p_n = p;
-    p = p_p;
-    c = g_utf8_get_char(p);
-    p_p = g_utf8_find_prev_char(e->buff, p);
+    if (!isspace((int) e->buff[i])) {
+      return(0);
+    }
   }
   return(0);
 }
 
-void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
+void owl_editwin_post_process_char(owl_editwin *e, int j)
 {
   /* check if we need to scroll down */
@@ -1127,5 +939,5 @@
     e->topline+=e->winlines/2;
   }
-  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
+  if ((j==13 || j==10) && owl_editwin_check_dotsend(e)) {
     owl_command_editmulti_done(e);
     return;
@@ -1134,18 +946,11 @@
 }
 
-void _owl_editwin_process_char(owl_editwin *e, gunichar j)
-{
-  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
+void owl_editwin_process_char(owl_editwin *e, int j)
+{
+  if (j == ERR) return;
+  if (j>127 || ((j<32) && (j!=10) && (j!=13))) {
+    return;
+  } else {
     owl_editwin_insert_char(e, j);
-  }
-}
-
-
-void owl_editwin_process_char(owl_editwin *e, owl_input j)
-{
-  if (j.ch == ERR) return;
-  /* Ignore ncurses control characters. */
-  if (j.ch < 0x100) { 
-    _owl_editwin_process_char(e, j.uch);
   }
 }
@@ -1174,44 +979,10 @@
   }
 
-  /* now count characters */
-  i = 0;
-  ptr2 = ptr1;
-  while (ptr2 - e->buff < e->bufflen
-	 && *ptr2 != '\n') {
-    ++i;
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  return i;
-}
-
-int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
-{
-  int i;
-  char *ptr1, *ptr2;
-  gunichar c;
-
-  if (e->bufflen==0) return(0);
-  
-  /* first go to the yth line */
-  ptr1=e->buff;
-  for (i=0; i<line; i++) {
-    ptr2=strchr(ptr1, '\n');
-    if (!ptr2) {
-      /* we're already on the last line */
-      return(0);
-    }
-    ptr1=ptr2+1;
-  }
-
-  /* now count cells */
-  i = 0;
-  ptr2 = ptr1;
-  while (ptr2 - e->buff < e->bufflen
-	 && *ptr2 != '\n') {
-    c = g_utf8_get_char(ptr2);
-    i += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  return i;
+  /* now go to the xth character */
+  ptr2=strchr(ptr1, '\n');
+  if (!ptr2) {
+    return(e->buff + e->bufflen - ptr1);
+  }
+  return(ptr2-ptr1); /* don't count the newline for now */
 }
 
Index: fmtext.c
===================================================================
--- fmtext.c	(revision c55ad845105974d495240c5d81e7d0c536780951)
+++ fmtext.c	(revision fa3290d0243ae8fb36df1f09bbe9bc943d1efc06)
@@ -8,11 +8,14 @@
 void owl_fmtext_init_null(owl_fmtext *f)
 {
-  f->textlen = 0;
-  f->bufflen = 5;
-  f->textbuff = owl_malloc(5);
-  f->textbuff[0] = 0;
-  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
-  f->default_fgcolor = OWL_COLOR_DEFAULT;
-  f->default_bgcolor = OWL_COLOR_DEFAULT;
+  f->textlen=0;
+  f->bufflen=5;
+  f->textbuff=owl_malloc(5);
+  f->fmbuff=owl_malloc(5);
+  f->fgcolorbuff=owl_malloc(5 * sizeof(short));
+  f->bgcolorbuff=owl_malloc(5 * sizeof(short));
+  f->textbuff[0]=0;
+  f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
+  f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
+  f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
 }
 
@@ -21,9 +24,50 @@
 void owl_fmtext_clear(owl_fmtext *f)
 {
-  f->textlen = 0;
-  f->textbuff[0] = 0;
-  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
-  f->default_fgcolor = OWL_COLOR_DEFAULT;
-  f->default_bgcolor = OWL_COLOR_DEFAULT;
+    f->textlen = 0;
+    f->textbuff[0] = 0;
+    f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
+    f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
+    f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
+}
+
+/* Internal function.  Set the attribute 'attr' from index 'first' to
+ * index 'last'
+ */
+void _owl_fmtext_set_attr(owl_fmtext *f, int attr, int first, int last)
+{
+  int i;
+  for (i=first; i<=last; i++) {
+    f->fmbuff[i]=(unsigned char) attr;
+  }
+}
+
+/* Internal function.  Add the attribute 'attr' to the existing
+ * attributes from index 'first' to index 'last'
+ */
+void _owl_fmtext_add_attr(owl_fmtext *f, int attr, int first, int last)
+{
+  int i;
+  for (i=first; i<=last; i++) {
+    f->fmbuff[i]|=(unsigned char) attr;
+  }
+}
+
+/* Internal function.  Set the color to be 'color' from index 'first'
+ * to index 'last
+ */
+void _owl_fmtext_set_fgcolor(owl_fmtext *f, int color, int first, int last)
+{
+  int i;
+  for (i=first; i<=last; i++) {
+    f->fgcolorbuff[i]=(short)color;
+  }
+}
+
+void _owl_fmtext_set_bgcolor(owl_fmtext *f, int color, int first, int last)
+{
+  int i;
+  for (i=first; i<=last; i++) {
+    f->bgcolorbuff[i]=(short)color;
+  }
 }
 
@@ -31,54 +75,25 @@
 {
     if(newlen + 1 > f->bufflen) {
-      f->textbuff = owl_realloc(f->textbuff, newlen + 1);
+      f->textbuff=owl_realloc(f->textbuff, newlen+1);
+      f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
+      f->fgcolorbuff=owl_realloc(f->fgcolorbuff, (newlen+1) * sizeof(short));
+      f->bgcolorbuff=owl_realloc(f->bgcolorbuff, (newlen+1) * sizeof(short));
       f->bufflen = newlen+1;
   }
 }
 
-int owl_fmtext_is_format_char(gunichar c)
-{
-  if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
-  if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
-  return 0;
-}
 /* append text to the end of 'f' with attribute 'attr' and color
  * 'color'
  */
-void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
-{
-  char attrbuff[6];
-  int newlen, a = 0, fg = 0, bg = 0;
-  
-  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
-  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
-  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
-
-  /* Plane-16 characters in UTF-8 are 4 bytes long. */
-  newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
+void owl_fmtext_append_attr(owl_fmtext *f, char *text, int attr, int fgcolor, int bgcolor)
+{
+  int newlen;
+  newlen=strlen(f->textbuff)+strlen(text);
   _owl_fmtext_realloc(f, newlen);
-
-  /* Set attributes */
-  if (a) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (fg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (bg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
   
   strcat(f->textbuff, text);
-
-  /* Reset attributes */
-  if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
-  if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
-  if (a)  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
+  _owl_fmtext_set_attr(f, attr, f->textlen, newlen);
+  _owl_fmtext_set_fgcolor(f, fgcolor, f->textlen, newlen);
+  _owl_fmtext_set_bgcolor(f, bgcolor, f->textlen, newlen);
   f->textlen=newlen;
 }
@@ -114,101 +129,58 @@
 }
 
-/* Add the attribute 'attr' to the default atts for the text in 'f' */
-void owl_fmtext_addattr(owl_fmtext *f, char attr)
+/* Add the attribute 'attr' to all text in 'f' */
+void owl_fmtext_addattr(owl_fmtext *f, int attr)
 {
   /* add the attribute to all text */
-  f->default_attrs |= attr;
-}
-
-/* Set the default foreground color for this fmtext to 'color'.
- * Only affects text that is colored default.
+  int i, j;
+
+  j=f->textlen;
+  for (i=0; i<j; i++) {
+    f->fmbuff[i] |= attr;
+  }
+}
+
+/* Anywhere the color is NOT ALREDY SET, set the color to 'color'.
+ * Other colors are left unchanged
  */
 void owl_fmtext_colorize(owl_fmtext *f, int color)
 {
-  f->default_fgcolor = color;
-}
-
-/* Set the default foreground color for this fmtext to 'color'.
- * Only affects text that is colored default.
- */
+  /* everywhere the fgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
+  int i, j;
+
+  j=f->textlen;
+  for(i=0; i<j; i++) {
+    if (f->fgcolorbuff[i]==OWL_COLOR_DEFAULT) f->fgcolorbuff[i] = (short)color;
+  }
+}
+
 void owl_fmtext_colorizebg(owl_fmtext *f, int color)
 {
-  f->default_bgcolor = color;
-}
-
-/* Internal function. Parse attrbute character. */
-void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
-{
-  if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
-    *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
-  }
-  else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
-    *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
-		? OWL_COLOR_DEFAULT
-		: c & OWL_FMTEXT_UC_COLOR_MASK);
-  }
-  else if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
-    *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
-		? OWL_COLOR_DEFAULT
-		: c & OWL_FMTEXT_UC_COLOR_MASK);
-  }
-}
-
-/* Internal function. Scan for attribute characters. */
-void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
-{
-  char *p;
-  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  while (p && p < f->textbuff + start) {
-    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
-    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  }
-}  
+  /* everywhere the bgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
+  int i, j;
+
+  j=f->textlen;
+  for(i=0; i<j; i++) {
+    if (f->bgcolorbuff[i]==OWL_COLOR_DEFAULT) f->bgcolorbuff[i] = (short)color;
+  }
+}
 
 /* Internal function.  Append text from 'in' between index 'start' and
  * 'stop' to the end of 'f'
  */
-void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
-{
-  char attrbuff[6];
-  int newlen, a = 0, fg = 0, bg = 0;
-  char attr = 0;
-  short fgcolor = OWL_COLOR_DEFAULT;
-  short bgcolor = OWL_COLOR_DEFAULT;
-
-  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
-  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
-  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
-  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
-
-  /* We will reset to defaults after appending the text. We may need
-     to set initial attributes. */
-  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
+void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
+{
+  int newlen, i;
+
+  newlen=strlen(f->textbuff)+(stop-start+1);
   _owl_fmtext_realloc(f, newlen);
 
-  if (a) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (fg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (bg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-
   strncat(f->textbuff, in->textbuff+start, stop-start+1);
-
-  /* Reset attributes */
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
-
   f->textbuff[newlen]='\0';
+  for (i=start; i<=stop; i++) {
+    f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
+    f->fgcolorbuff[f->textlen+(i-start)]=in->fgcolorbuff[i];
+    f->bgcolorbuff[f->textlen+(i-start)]=in->bgcolorbuff[i];
+  }
   f->textlen=newlen;
 }
@@ -235,27 +207,5 @@
 char *owl_fmtext_print_plain(owl_fmtext *f)
 {
-  return owl_strip_format_chars(f->textbuff);
-}
-
-void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
-{
-  wattrset(w, A_NORMAL);
-  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
-  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
-  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
-}
-
-void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
-{
-  if (owl_global_get_hascolors(&g)) {
-    *pair = owl_fmtext_get_colorpair(fg, bg);
-  }
-}
-
-void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
-{
-  if (owl_global_get_hascolors(&g)) {
-      wcolor_set(w,pair,NULL);
-  }
+  return(owl_strdup(f->textbuff));
 }
 
@@ -263,13 +213,9 @@
  * must already be initiatlized with curses
  */
-void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
-{
-  /* char *tmpbuff; */
-  /* int position, trans1, trans2, trans3, len, lastsame; */
-  char *s, *p;
-  char attr;
-  short fg, bg, pair;
-  int search_results, search_len;
-  
+void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
+{
+  char *tmpbuff;
+  int position, trans1, trans2, trans3, len, lastsame;
+
   if (w==NULL) {
     owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
@@ -277,96 +223,53 @@
   }
 
-  search_results = (do_search
-		    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
-		    : 0);
-  search_len = (search_results
-		? strlen(owl_global_get_search_string(&g))
-		: 0);
-  s = f->textbuff;
-  /* Set default attributes. */
-  attr = f->default_attrs;
-  fg = f->default_fgcolor;
-  bg = f->default_bgcolor;
-  _owl_fmtext_wattrset(w, attr);
-  _owl_fmtext_update_colorpair(fg, bg, &pair);
-  _owl_fmtext_wcolor_set(w, pair);
-
-  /* Find next possible format character. */
-  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  while(p) {
-    if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-      /* Deal with all text from last insert to here. */
-      char tmp;
-   
-      tmp = p[0];
-      p[0] = '\0';
-      if (search_results) {
-	/* Search is active, so highlight search results. */
-	char tmp2, *ss;
-	ss = stristr(s, owl_global_get_search_string(&g));
-	while (ss) {
-	  /* Found search string, highlight it. */
-
-	  tmp2 = ss[0];
-	  ss[0] = '\0';
-	  waddstr(w, s);
-	  ss[0] = tmp2;
-
-	  _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
-	  _owl_fmtext_wcolor_set(w, pair);
-	  
-	  tmp2 = ss[search_len];
-	  ss[search_len] = '\0';
-	  waddstr(w, ss);
-	  ss[search_len] = tmp2;
-
-	  _owl_fmtext_wattrset(w, attr);
-	  _owl_fmtext_wcolor_set(w, pair);
-
-	  s = ss + search_len;
-	  ss = stristr(s, owl_global_get_search_string(&g));
-	}
-      }
-      /* Deal with remaining part of string. */
-      waddstr(w, s);
-      p[0] = tmp;
-
-      /* Deal with new attributes. Initialize to defaults, then
-	 process all consecutive formatting characters. */
-      attr = f->default_attrs;
-      fg = f->default_fgcolor;
-      bg = f->default_bgcolor;
-      while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	_owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
-	p = g_utf8_next_char(p);
-      }
-      _owl_fmtext_wattrset(w, attr | f->default_attrs);
-      if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
-      if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
-      _owl_fmtext_update_colorpair(fg, bg, &pair);
-      _owl_fmtext_wcolor_set(w, pair);
-
-      /* Advance to next non-formatting character. */
-      s = p;
-      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    }
-    else {
-      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    }
-  }
-  if (s) {
-    waddstr(w, s);
-  }
-}
-
-void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
-{
-  _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
-}
-
-void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
-{
-  _owl_fmtext_curs_waddstr(f, w, 0);
-}
+  tmpbuff=owl_malloc(f->textlen+10);
+
+  position=0;
+  len=f->textlen;
+  while (position<=len) {
+    /* find the last char with the current format and color */
+    trans1=owl_util_find_trans(f->fmbuff+position, len-position);
+    trans2=owl_util_find_trans_short(f->fgcolorbuff+position, len-position);
+    trans3=owl_util_find_trans_short(f->bgcolorbuff+position, len-position);
+
+    lastsame = (trans1 < trans2) ? trans1 : trans2;
+    lastsame = (lastsame < trans3) ? lastsame : trans3;
+    lastsame += position;
+
+    /* set the format */
+    wattrset(w, A_NORMAL);
+    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
+      wattron(w, A_BOLD);
+    }
+    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
+      wattron(w, A_REVERSE);
+    }
+    if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
+      wattron(w, A_UNDERLINE);
+    }
+
+    /* set the color */
+    /* warning, this is sort of a hack */
+    if (owl_global_get_hascolors(&g)) {
+      short fg, bg, pair;
+      fg = f->fgcolorbuff[position];
+      bg = f->bgcolorbuff[position];
+
+      pair = owl_fmtext_get_colorpair(fg, bg);
+      if (pair != -1) {
+        wcolor_set(w,pair,NULL);
+      }
+    }
+
+    /* add the text */
+    strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
+    tmpbuff[lastsame-position+1]='\0';
+    waddstr(w, tmpbuff);
+
+    position=lastsame+1;
+  }
+  owl_free(tmpbuff);
+}
+
 
 /* start with line 'aline' (where the first line is 0) and print
@@ -379,30 +282,26 @@
   
   /* find the starting line */
-  ptr1 = in->textbuff;
-  for (i = 0; i < aline; i++) {
-    ptr1 = strchr(ptr1, '\n');
-    if (!ptr1) return(-1);
-    ptr1++;
-  }
-  
+  ptr1=in->textbuff;
+  if (aline!=0) {
+    for (i=0; i<aline; i++) {
+      ptr1=strchr(ptr1, '\n');
+      if (!ptr1) return(-1);
+      ptr1++;
+    }
+  }
   /* ptr1 now holds the starting point */
 
-  /* copy the default attributes */
-  out->default_attrs = in->default_attrs;
-  out->default_fgcolor = in->default_fgcolor;
-  out->default_bgcolor = in->default_bgcolor;
-    
   /* copy in the next 'lines' lines */
-  if (lines < 1) return(-1);
-
-  for (i = 0; i < lines; i++) {
-    offset = ptr1 - in->textbuff;
-    ptr2 = strchr(ptr1, '\n');
+  if (lines<1) return(-1);
+
+  for (i=0; i<lines; i++) {
+    offset=ptr1-in->textbuff;
+    ptr2=strchr(ptr1, '\n');
     if (!ptr2) {
-      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
+      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
       return(-1);
     }
-    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
-    ptr1 = ptr2 + 1;
+    _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
+    ptr1=ptr2+1;
   }
   return(0);
@@ -412,80 +311,47 @@
  * ends at 'bcol' or sooner.  The first column is number 0.  The new
  * message is placed in 'out'.  The message is * expected to end in a
- * new line for now. NOTE: This needs to be modified to deal with
- * backing up if we find a SPACING COMBINING MARK at the end of a
- * line. If that happens, we should back up to the last non-mark
- * character and stop there.
+ * new line for now
  */
 void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
 {
-  char *ptr_s, *ptr_e, *ptr_c, *last;
-  int col, st, padding, chwidth;
-
-  /* copy the default attributes */
-  out->default_attrs = in->default_attrs;
-  out->default_fgcolor = in->default_fgcolor;
-  out->default_bgcolor = in->default_bgcolor;
+  char *ptr1, *ptr2, *last;
+  int len, offset;
 
   last=in->textbuff+in->textlen-1;
-  ptr_s=in->textbuff;
-  while (ptr_s <= last) {
-    ptr_e=strchr(ptr_s, '\n');
-    if (!ptr_e) {
+  ptr1=in->textbuff;
+  while (ptr1<=last) {
+    ptr2=strchr(ptr1, '\n');
+    if (!ptr2) {
       /* but this shouldn't happen if we end in a \n */
       break;
     }
     
-    if (ptr_e == ptr_s) {
+    if (ptr2==ptr1) {
       owl_fmtext_append_normal(out, "\n");
-      ++ptr_s;
+      ptr1++;
       continue;
     }
 
-    col = 0;
-    st = 0;
-    padding = 0;
-    chwidth = 0;
-    ptr_c = ptr_s;
-    while(ptr_c < ptr_e) {
-      gunichar c = g_utf8_get_char(ptr_c);
-      if (!owl_fmtext_is_format_char(c)) {
-	chwidth = mk_wcwidth(c);
-	if (col + chwidth > bcol) break;
-	
-	if (col >= acol) {
-	  if (st == 0) {
-	    ptr_s = ptr_c;
-	    padding = col - acol;
-	    ++st;
-	  }
-	}
-	col += chwidth;
-	chwidth = 0;
-      }
-      ptr_c = g_utf8_next_char(ptr_c);
-    }
-    if (st) {
-      /* lead padding */
-      owl_fmtext_append_spaces(out, padding);
-      if (ptr_c == ptr_e) {
-	/* We made it to the newline. */
-	_owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
-      }
-      else {
-	if (chwidth > 1) {
-	  /* Last char is wide, truncate. */
-	  _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
-	  owl_fmtext_append_normal(out, "\n");
-	}
-	else {
-	  /* Last char fits perfectly, leave alone.*/
-	  _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
-	}
-      }
-    }
-    else {
+    /* we need to check that we won't run over here */
+    len=bcol-acol;
+    if (len > (ptr2-(ptr1+acol))) {
+      /* the whole line fits with room to spare, don't take a full 'len' */
+      len=ptr2-(ptr1+acol);
+    }
+    if (len>last-ptr1) {
+      /* the whole rest of the text fits with room to spare, adjust for it */
+      len-=(last-ptr1);
+    }
+    if (len<=0) {
+      /* saftey check */
       owl_fmtext_append_normal(out, "\n");
-    }
-    ptr_s = g_utf8_next_char(ptr_e);
+      ptr1=ptr2+1;
+      continue;
+    }
+
+    offset=ptr1-in->textbuff;
+    _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
+
+    ptr1=ptr2+1;
   }
 }
@@ -515,11 +381,8 @@
 
 /* set the charater at 'index' to be 'char'.  If index is out of
- * bounds don't do anything. If c or char at index is not ASCII, don't
- * do anything because it's not UTF-8 safe. */
-void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
+ * bounds don't do anything */
+void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
 {
   if ((index < 0) || (index > f->textlen-1)) return;
-  /* NOT ASCII*/
-  if (f->textbuff[index] & 0x80 || ch & 0x80) return; 
   f->textbuff[index]=ch;
 }
@@ -537,8 +400,37 @@
   dst->textlen=src->textlen;
   dst->textbuff=owl_malloc(mallocsize);
+  dst->fmbuff=owl_malloc(mallocsize);
+  dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
+  dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
   memcpy(dst->textbuff, src->textbuff, src->textlen+1);
-  dst->default_attrs = src->default_attrs;
-  dst->default_fgcolor = src->default_fgcolor;
-  dst->default_bgcolor = src->default_bgcolor;
+  memcpy(dst->fmbuff, src->fmbuff, src->textlen);
+  memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
+  memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
+}
+
+/* highlight all instances of "string".  Return the number of
+ * instances found.  This is a case insensitive search.
+ */
+int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
+{
+
+  int found, len;
+  char *ptr1, *ptr2;
+
+  len=strlen(string);
+  found=0;
+  ptr1=f->textbuff;
+  while (ptr1-f->textbuff <= f->textlen) {
+    ptr2=stristr(ptr1, string);
+    if (!ptr2) return(found);
+
+    found++;
+    _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
+                         ptr2 - f->textbuff,
+                         ptr2 - f->textbuff + len - 1);
+
+    ptr1=ptr2+len;
+  }
+  return(found);
 }
 
@@ -548,4 +440,5 @@
 int owl_fmtext_search(owl_fmtext *f, char *string)
 {
+
   if (stristr(f->textbuff, string)) return(1);
   return(0);
@@ -788,4 +681,7 @@
 {
   if (f->textbuff) owl_free(f->textbuff);
+  if (f->fmbuff) owl_free(f->fmbuff);
+  if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
+  if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
 }
 
Index: functions.c
===================================================================
--- functions.c	(revision f9eea4c2b610d8a43d97d158b483c245238165c7)
+++ functions.c	(revision 36172860060e404e761fc6fd5503c09ef88bd83d)
@@ -1606,5 +1606,5 @@
 	  sprintf(buff, "  Field %i   : ", i+1);
 	  
-	  ptr=owl_zephyr_get_field_as_utf8(n, i+1);
+	  ptr=owl_zephyr_get_field(n, i+1);
 	  len=strlen(ptr);
 	  if (len<30) {
@@ -2187,4 +2187,5 @@
 void owl_function_start_command(char *line)
 {
+  int i, j;
   owl_editwin *tw;
 
@@ -2197,5 +2198,8 @@
   owl_global_set_needrefresh(&g);
 
-  owl_editwin_insert_string(tw, line);
+  j=strlen(line);
+  for (i=0; i<j; i++) {
+    owl_editwin_process_char(tw, line[i]);
+  }
   owl_editwin_redisplay(tw, 0);
 
@@ -2595,11 +2599,5 @@
   }
   /* downcase it */
-  {
-    char *temp = g_utf8_strdown(filtname, -1);
-    if (temp) {
-      owl_free(filtname);
-      filtname = temp;
-    }
-  }
+  downstr(filtname);
   /* turn spaces, single quotes, and double quotes into dots */
   owl_text_tr(filtname, ' ', '.');
@@ -3026,5 +3024,5 @@
   char *quoted;
 
-  buff=owl_malloc(strlen(class)+strlen(inst)+strlen(recip)+100);
+  buff=malloc(strlen(class)+strlen(inst)+strlen(recip)+100);
   strcpy(buff, "class");
   if (!strcmp(class, "*")) {
@@ -3330,5 +3328,5 @@
           if (ret==0) {
             for (x=0; x<numlocs; x++) {
-              line=owl_malloc(strlen(location[x].host)+strlen(location[x].time)+strlen(location[x].tty)+100);
+              line=malloc(strlen(location[x].host)+strlen(location[x].time)+strlen(location[x].tty)+100);
               tmp=short_zuser(user);
               sprintf(line, "  %-10.10s %-24.24s %-12.12s  %20.20s\n",
@@ -3373,5 +3371,4 @@
   owl_view *v;
   FILE *file;
-  char *plaintext;
 
   v=owl_global_get_current_view(&g);
@@ -3396,9 +3393,5 @@
   for (i=0; i<j; i++) {
     m=owl_view_get_element(v, i);
-    plaintext = owl_strip_format_chars(owl_message_get_text(m));
-    if (plaintext) {
-      fputs(plaintext, file);
-      owl_free(plaintext);
-    }
+    fputs(owl_message_get_text(m), file);
   }
   fclose(file);
@@ -3441,5 +3434,5 @@
 	  _exit(127);
 	}
-	parsed=owl_realloc(parsed, sizeof(*parsed) * (myargc+1));
+	parsed=realloc(parsed, sizeof(*parsed) * (myargc+1));
 	parsed[myargc] = NULL;
 	
Index: ib_compat.c
===================================================================
--- glib_compat.c	(revision c60ade251647a4ea5fe6675372c30ea5a7772244)
+++ 	(revision )
@@ -1,18 +1,0 @@
-#include <owl.h>
-
-#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14)
-/* Our own implementation of g_unichar_is_mark for glib versions that
-   are too old to have one. */
-int g_unichar_ismark(gunichar ucs)
-{
-  GUnicodeType t = g_unichar_type(ucs);
-  switch (t) {
-  case G_UNICODE_NON_SPACING_MARK:
-  case G_UNICODE_COMBINING_MARK:
-  case G_UNICODE_ENCLOSING_MARK:
-       return 1;
-  default:
-       return 0;
-  }
-}
-#endif
Index: global.c
===================================================================
--- global.c	(revision eebef194307e93a0e2956946794840c21dd8c4ba)
+++ global.c	(revision eebef194307e93a0e2956946794840c21dd8c4ba)
@@ -549,5 +549,5 @@
     len+=strlen(argv[i])+5;
   }
-  g->startupargs=owl_malloc(len+5);
+  g->startupargs=malloc(len+5);
 
   strcpy(g->startupargs, "");
Index: keymap.c
===================================================================
--- keymap.c	(revision 428834dd2aedac4b5fc2874635c22897ffa16c22)
+++ keymap.c	(revision cf83b7a15ef998b48ca0aa69dae69a963b365dc1)
@@ -5,5 +5,5 @@
 
 /* returns 0 on success */
-int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
+int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(int), void (*prealways_fn)(int), void (*postalways_fn)(int))
 {
   if (!name || !desc) return(-1);
@@ -151,5 +151,5 @@
 }
 
-owl_keymap *owl_keyhandler_create_and_add_keymap(owl_keyhandler *kh, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
+owl_keymap *owl_keyhandler_create_and_add_keymap(owl_keyhandler *kh, char *name, char *desc, void (*default_fn)(int), void (*prealways_fn)(int), void (*postalways_fn)(int))
 {
   owl_keymap *km;
@@ -202,5 +202,5 @@
 /* processes a keypress.  returns 0 if the keypress was handled,
  * 1 if not handled, -1 on error, and -2 if j==ERR. */
-int owl_keyhandler_process(owl_keyhandler *kh, owl_input j)
+int owl_keyhandler_process(owl_keyhandler *kh, int j)
 {
   owl_keymap     *km;
@@ -214,5 +214,5 @@
 
   /* temporarily disallow C-`/C-SPACE until we fix associated bugs */
-  if (j.ch == ERR || j.ch == 0) {
+  if (j==ERR || j==0) {
 	return(-1);
   }
@@ -224,14 +224,14 @@
 
   /* deal with ESC prefixing */
-  if (!kh->in_esc && j.ch == 27) {
+  if (!kh->in_esc && j==27) {
     kh->in_esc = 1;
     return(0);
   }
   if (kh->in_esc) {
-    j.ch = OWL_META(j.ch);
+    j = OWL_META(j);
     kh->in_esc = 0;
   }
   
-  kh->kpstack[++(kh->kpstackpos)] = j.ch;
+  kh->kpstack[++(kh->kpstackpos)] = j;
   if (kh->kpstackpos >= OWL_KEYMAP_MAXSTACK) {
     owl_keyhandler_reset(kh);
@@ -260,5 +260,5 @@
       } else if (match == 2) {	/* exact match */
 	/* owl_function_debugmsg("processkey: found exact match in %s", km->name); */
-	owl_keybinding_execute(kb, j.ch);
+	owl_keybinding_execute(kb, j);
 	owl_keyhandler_reset(kh);
 	if (km->postalways_fn) {
Index: keypress.c
===================================================================
--- keypress.c	(revision 428834dd2aedac4b5fc2874635c22897ffa16c22)
+++ keypress.c	(revision 948b94240edb7210e2db1029e279718ea7fe3aac)
@@ -148,5 +148,5 @@
   }
   if (!*kb) {
-    if (j & OWL_META(0)) {
+    if (j&OWL_META(0)) {
       strcat(kb, "M-");
       j &= ~OWL_META(0);
@@ -163,5 +163,4 @@
       strcat(kb, kb2);    
     }
-    
   }  
   if (!*kb) {
Index: keys.c
===================================================================
--- keys.c	(revision fac5463dbde789ec17cf1e7b828366dd7911806f)
+++ keys.c	(revision 8938188651289a80e4f3129f765c9ac991d254a3)
@@ -294,25 +294,25 @@
 /****************************************************************/
 
-void owl_keys_recwin_prealways(owl_input j) {
+void owl_keys_recwin_prealways(int j) {
   /* Clear the message line on subsequent key presses */
   owl_function_makemsg("");
 }
 
-void owl_keys_editwin_default(owl_input j) {
+void owl_keys_editwin_default(int j) {
   owl_editwin *e;
   if (NULL != (e=owl_global_get_typwin(&g))) {
-       owl_editwin_process_char(e, j);
+    owl_editwin_process_char(e, j);
   }
 }
 
-void owl_keys_editwin_postalways(owl_input j) {
+void owl_keys_editwin_postalways(int j) {
   owl_editwin *e;
   if (NULL != (e=owl_global_get_typwin(&g))) {
     owl_editwin_post_process_char(e, j);
-  }
+  }  
   owl_global_set_needrefresh(&g);
 }
 
-void owl_keys_popless_postalways(owl_input j) {
+void owl_keys_popless_postalways(int j) {
   owl_viewwin *v = owl_global_get_viewwin(&g);
   owl_popwin *pw = owl_global_get_popwin(&g);
@@ -323,7 +323,7 @@
 }
 
-void owl_keys_default_invalid(owl_input j) {
-  if (j.ch==ERR) return;
-  if (j.ch==410) return;
+void owl_keys_default_invalid(int j) {
+  if (j==ERR) return;
+  if (j==410) return;
   owl_keyhandler_invalidkey(owl_global_get_keyhandler(&g));
 }
Index: logging.c
===================================================================
--- logging.c	(revision 28ee32b3f0b785ed3f83357207feda49cfdb61b4)
+++ logging.c	(revision d0961fe0bc68cec33bc23afbae4928bbd861d718)
@@ -155,9 +155,7 @@
     to = owl_sprintf("jabber:%s", owl_message_get_recipient(m));
   } else if (owl_message_is_type_aim(m)) {
-    char *temp2;
     temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
-    temp2 = g_utf8_strdown(temp,-1);
-    to = owl_sprintf("aim:%s", temp2);
-    owl_free(temp2);
+    downstr(temp);
+    to = owl_sprintf("aim:%s", temp);
     owl_free(temp);
   } else {
@@ -269,10 +267,9 @@
   } else if (owl_message_is_type_aim(m)) {
     /* we do not yet handle chat rooms */
-    char *normalto, *temp;
-    temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
-    normalto = g_utf8_strdown(temp, -1);
+    char *normalto;
+    normalto=owl_aim_normalize_screenname(owl_message_get_sender(m));
+    downstr(normalto);
     from=frombuff=owl_sprintf("aim:%s", normalto);
     owl_free(normalto);
-    owl_free(temp);
   } else if (owl_message_is_type_loopback(m)) {
     from=frombuff=owl_strdup("loopback");
@@ -293,5 +290,5 @@
 
   ch=frombuff[0];
-  if (!g_ascii_isalnum(ch)) from="weird";
+  if (!isalnum(ch)) from="weird";
 
   for (i=0; i<len; i++) {
@@ -302,11 +299,5 @@
 
   if (!personal) {
-    if (strcmp(from, "weird")) {
-      char* temp = g_utf8_strdown(frombuff, -1);
-      if (temp) {
-	owl_free(frombuff);
-	from = frombuff = temp;
-      }
-    }
+    if (strcmp(from, "weird")) downstr(from);
   }
 
Index: message.c
===================================================================
--- message.c	(revision 635881c74d5db520489dd93640fdefa1f71d4988)
+++ message.c	(revision 635881c74d5db520489dd93640fdefa1f71d4988)
@@ -79,5 +79,5 @@
     owl_list_append_element(&(m->attributes), pair);
   }
-  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
+  owl_pair_set_value(pair, owl_strdup(attrvalue));
 }
 
@@ -493,5 +493,5 @@
 {
   if(m->zwriteline) owl_free(m->zwriteline);
-  m->zwriteline=owl_strdup(line);
+  m->zwriteline=strdup(line);
 }
 
@@ -535,9 +535,17 @@
   owl_fmtext_init_null(&b);
   
-  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline, &a);
+  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline+1, &a);
   owl_fmtext_truncate_cols(&a, acol, bcol, &b);
-  owl_fmtext_colorize(&b, fgcolor);
-  owl_fmtext_colorizebg(&b, bgcolor);
-
+  if (fgcolor!=OWL_COLOR_DEFAULT) {
+    owl_fmtext_colorize(&b, fgcolor);
+  }
+  if (bgcolor!=OWL_COLOR_DEFAULT) {
+    owl_fmtext_colorizebg(&b, bgcolor);
+  }
+
+  if (owl_global_is_search_active(&g)) {
+    owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
+  }
+      
   owl_fmtext_curs_waddstr(&b, win);
 
@@ -882,5 +890,5 @@
   }
 
-  m->zwriteline=owl_strdup("");
+  m->zwriteline=strdup("");
 
   /* save the hostname */
@@ -964,5 +972,5 @@
   }
 
-  m->zwriteline=owl_strdup("");
+  m->zwriteline=strdup("");
 
   owl_message_set_body(m, "<uninitialized>");
Index: owl.c
===================================================================
--- owl.c	(revision 6fe806ae890b6a1616bd442639d297349a7d8d20)
+++ owl.c	(revision eebef194307e93a0e2956946794840c21dd8c4ba)
@@ -48,5 +48,4 @@
 #include <termios.h>
 #include <sys/stat.h>
-#include <locale.h>
 #include "owl.h"
 
@@ -70,6 +69,5 @@
   owl_editwin *tw;
   owl_popwin *pw;
-  int ret, initialsubs, debug, argcsave, followlast;
-  owl_input j;
+  int j, ret, initialsubs, debug, argcsave, followlast;
   int newmsgs, nexttimediff;
   struct sigaction sigact;
@@ -86,7 +84,4 @@
   int newstderr;
 #endif
-  
-  if (!GLIB_CHECK_VERSION (2, 12, 0))
-    g_error ("GLib version 2.12.0 or above is needed.");
 
   argcsave=argc;
@@ -97,7 +92,4 @@
   debug=0;
   initialsubs=1;
-
-  setlocale(LC_ALL, "");
-  
   if (argc>0) {
     argv++;
@@ -538,53 +530,8 @@
      * little bit, but otherwise do not.  This lets input be grabbed
      * as quickly as possbile */
-    j.ch = wgetch(typwin);
-    if (j.ch == ERR) {
+    j=wgetch(typwin);
+    if (j==ERR) {
       usleep(10000);
     } else {
-      j.uch = '\0';
-      if (j.ch >= KEY_MIN && j.ch <= KEY_MAX) {
-	/* This is a curses control character. */
-      }
-      else if (j.ch > 0x7f && j.ch < 0xfe) {
-	/* Pull in a full utf-8 character. */
-	int bytes, i;
-	char utf8buf[7];
-	memset(utf8buf, '\0', 7);
-
-	utf8buf[0] = j.ch;
-
-	if ((j.ch & 0xc0) && (~j.ch & 0x20)) bytes = 2;
-	else if ((j.ch & 0xe0) && (~j.ch & 0x10)) bytes = 3;
-	else if ((j.ch & 0xf0) && (~j.ch & 0x08)) bytes = 4;
-	else if ((j.ch & 0xf8) && (~j.ch & 0x04)) bytes = 5;
-	else if ((j.ch & 0xfc) && (~j.ch & 0x02)) bytes = 6;
-	else bytes = 1;
-	
-	for (i = 1; i < bytes; i++) {
-          int tmp =  wgetch(typwin);
-          /* If what we got was not a byte, or not a continuation byte */
-          if (tmp > 0xff || !(tmp & 0x80 && ~tmp & 0x40)) {
-            /* ill-formed UTF-8 code unit subsequence, put back the
-               char we just got. */
-            ungetch(tmp);
-            j.ch = ERR;
-            break;
-          }
-	  utf8buf[i] = tmp;
-        }
-        
-	if (j.ch != ERR) {
-          if (g_utf8_validate(utf8buf, -1, NULL)) {
-            j.uch = g_utf8_get_char(utf8buf);
-          }
-          else {
-            j.ch = ERR;
-          }
-        }
-      }
-      else if (j.ch <= 0x7f) {
-	j.uch = j.ch;
-      }
-      
       owl_global_set_lastinputtime(&g, now);
       /* find and activate the current keymap.
Index: owl.h
===================================================================
--- owl.h	(revision 88dc766f92b555243e8aa1fdd3dde181bd80a04a)
+++ owl.h	(revision 88dc766f92b555243e8aa1fdd3dde181bd80a04a)
@@ -52,7 +52,5 @@
 #include <termios.h>
 #include <libfaim/aim.h>
-#include <wchar.h>
 #include "config.h"
-#include "glib.h"
 #ifdef HAVE_LIBZEPHYR
 #include <zephyr/zephyr.h>
@@ -102,24 +100,4 @@
 #define OWL_FMTEXT_ATTR_REVERSE   2
 #define OWL_FMTEXT_ATTR_UNDERLINE 4
-
-#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
-#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
-#define OWL_FMTEXT_UC_ATTR_MASK 0x7
-#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
-#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
-#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
-#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
-#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
-#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
-#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
-#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
-#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
-
-#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
-#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
-#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x96\x80"
-
-
-
 
 #define OWL_COLOR_BLACK     0
@@ -234,5 +212,5 @@
 #endif
 
-#define OWL_META(key) ((key)|010000)
+#define OWL_META(key) ((key)|0200)
 /* OWL_CTRL is definied in kepress.c */
 
@@ -274,16 +252,11 @@
 } owl_variable;
 
-typedef struct _owl_input {
-  int ch;
-  gunichar uch;
-} owl_input;
-
 typedef struct _owl_fmtext {
   int textlen;
   int bufflen;
   char *textbuff;
-  char default_attrs;
-  short default_fgcolor;
-  short default_bgcolor;
+  char *fmbuff;
+  short *fgcolorbuff;
+  short *bgcolorbuff;
 } owl_fmtext;
 
@@ -518,7 +491,7 @@
   owl_list  bindings;		/* key bindings */
   struct _owl_keymap *submap;	/* submap */
-  void (*default_fn)(owl_input j);	/* default action (takes a keypress) */
-  void (*prealways_fn)(owl_input  j);	/* always called before a keypress is received */
-  void (*postalways_fn)(owl_input  j);	/* always called after keypress is processed */
+  void (*default_fn)(int j);	/* default action (takes a keypress) */
+  void (*prealways_fn)(int j);	/* always called before a keypress is received */
+  void (*postalways_fn)(int j);	/* always called after keypress is processed */
 } owl_keymap;
 
Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm	(revision 81312e4de65076e92c386f849f45afc1d6ab77a4)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm	(revision 05f0061e58c81a1d32a1a1385b05b75d0b73360e)
@@ -25,6 +25,4 @@
 use Net::DNS;
 use Getopt::Long;
-
-use utf8;
 
 our $VERSION = 0.1;
@@ -375,5 +373,5 @@
                     $vars{jlogin_havepass} = 1;
                     $conn->removeConnection($jidStr);
-                    BarnOwl::start_password("Password for $jidStr: ", \&do_login );
+                    BarnOwl::start_password( "Password for $jidStr: ", \&do_login );
                     return "";
                 }
@@ -479,5 +477,5 @@
     }
     else {
-      $to = shift @ARGV;
+        $to = shift @ARGV;
     }
 
@@ -523,6 +521,5 @@
     $cmd .= " -t $jwrite_thread" if $jwrite_thread;
     $cmd .= " -s $jwrite_subject" if $jwrite_subject;
-
-    BarnOwl::start_edit_win($cmd, \&process_owl_jwrite );
+    BarnOwl::start_edit_win( $cmd, \&process_owl_jwrite );
 }
 
Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision e0ffe777358f35ecd718919a91164131c03db217)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision 892568bf6e3ceea8724cef719078e5f6c2455b16)
@@ -1,5 +1,4 @@
 use warnings;
 use strict;
-use utf8;
 
 =head1 NAME
Index: perl/modules/Jabber/lib/Net/XMPP/Debug.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Debug.pm	(revision b7b2a76676535044fc771b1bb087e020102d7af2)
+++ perl/modules/Jabber/lib/Net/XMPP/Debug.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
@@ -189,5 +189,4 @@
                         {
                             $self->{HANDLE}->autoflush(1);
-                            binmode $self->{HANDLE}, ":utf8";
                             $Net::XMPP::Debug::HANDLES{$args{file}} = $self->{HANDLE};
                         }
Index: perl/modules/Jabber/lib/Net/XMPP/Message.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Message.pm	(revision 8574801f6dba0d88fd1fb74c123861816eb077f8)
+++ perl/modules/Jabber/lib/Net/XMPP/Message.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
@@ -135,5 +135,5 @@
                             $Mess->SetMessage(TO=>"bob\@jabber.org",
                                               Subject=>"Lunch",
-                                              Body=>"Let's do lunch!");
+                                              BoDy=>"Let's do lunch!");
                             $Mess->SetMessage(to=>"bob\@jabber.org",
                                               from=>"jabber.org",
Index: perl/modules/Jabber/lib/XML/Stream.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream.pm	(revision a8d5a39837d6c308c7f46d0f78f528e6b9e6d54f)
+++ perl/modules/Jabber/lib/XML/Stream.pm	(revision 5073972cb617a0a04e54650031f94c47059c66fb)
@@ -1659,5 +1659,5 @@
     {
         $self->debug(3,"Send: can_write");
-
+        
         $self->{SENDSTRING} = Encode::encode_utf8(join("",@_));
 
Index: perlconfig.c
===================================================================
--- perlconfig.c	(revision 367fbf32a41d30c32785e01d25d05b04f221728e)
+++ perlconfig.c	(revision ff13a6f4c60b5298ed361b690905db36a382fe26)
@@ -55,5 +55,5 @@
     j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
     for (i=0; i<j; i++) {
-      ptr=owl_zephyr_get_field_as_utf8(owl_message_get_notice(m), i+1);
+      ptr=owl_zephyr_get_field(owl_message_get_notice(m), i+1);
       av_push(av_zfields, newSVpvn(ptr, strlen(ptr)));
       owl_free(ptr);
@@ -454,7 +454,5 @@
   PUSHMARK(SP);
   for(i=0;i<argc;i++) {
-    SV *tmp = newSVpv(argv[i], 0);
-    SvUTF8_on(tmp);
-    XPUSHs(sv_2mortal(tmp));
+    XPUSHs(sv_2mortal(newSVpv(argv[i], 0)));
   }
   PUTBACK;
@@ -490,5 +488,4 @@
 {
   SV *cb = (SV*)(e->cbdata);
-  SV *text;
   unsigned int n_a;
   dSP;
@@ -497,6 +494,4 @@
     owl_function_error("Perl callback is NULL!");
   }
-  text = newSVpv(owl_editwin_get_text(e), 0);
-  SvUTF8_on(text);
 
   ENTER;
@@ -504,5 +499,5 @@
 
   PUSHMARK(SP);
-  XPUSHs(sv_2mortal(text));
+  XPUSHs(sv_2mortal(newSVpv(owl_editwin_get_text(e), 0)));
   PUTBACK;
   
Index: text.c
===================================================================
--- text.c	(revision 47519e1bcab60a6026c4192bf5b20290f37f4737)
+++ text.c	(revision 72db971652f37640c13d75944eeb6eaf0fff645a)
@@ -50,66 +50,39 @@
 void owl_text_truncate_cols(char *out, char *in, int acol, int bcol)
 {
-  char *ptr_s, *ptr_e, *ptr_c, *tmpbuff, *last;
-  int col, cnt, padding;
-  
+  char *ptr1, *ptr2, *tmpbuff, *last;
+  int len;
+
   tmpbuff=owl_malloc(strlen(in)+20);
 
   strcpy(tmpbuff, "");
   last=in+strlen(in)-1;
-  ptr_s=in;
-  while (ptr_s<last) {
-    ptr_e=strchr(ptr_s, '\n');
-    if (!ptr_e) {
+  ptr1=in;
+  while (ptr1<last) {
+    ptr2=strchr(ptr1, '\n');
+    if (!ptr2) {
       /* but this shouldn't happen if we end in a \n */
       break;
     }
     
-    if (ptr_e==ptr_s) {
+    if (ptr2==ptr1) {
       strcat(tmpbuff, "\n");
-      ptr_s++;
-      continue;
-    }
-
-    col = 0;
-    cnt = 0;
-    padding = 0;
-    ptr_c = ptr_s;
-    while(col < bcol && ptr_c < ptr_e) {
-      gunichar c = g_utf8_get_char(ptr_c);
-      if (col + mk_wcwidth(c) > bcol) break;
-      col += mk_wcwidth(c);
-      ptr_c = g_utf8_next_char(ptr_c);
-      if (col >= acol) {
-	if (cnt == 0) {
-	  ptr_s = ptr_c;
-	  padding = col - acol;
-	}
-	++cnt;
-      }
-    }
-    if (cnt) {
-      while(padding-- > 0) {
-	strcat(tmpbuff, " ");
-      }
-      strncat(tmpbuff, ptr_s, ptr_c - ptr_s - 1);
-    }
-    strcat(tmpbuff, "\n");
-    ptr_s = ptr_e + 1;
-#if 0
+      ptr1++;
+      continue;
+    }
+
     /* we need to check that we won't run over here */
-    if ( (ptr_e-ptr_s) < (bcol-acol) ) {
-      len=ptr_e-(ptr_s+acol);
+    if ( (ptr2-ptr1) < (bcol-acol) ) {
+      len=ptr2-(ptr1+acol);
     } else {
       len=bcol-acol;
     }
-    if ((ptr_s+len)>=last) {
-      len-=last-(ptr_s+len);
-    }
-
-    strncat(tmpbuff, ptr_s+acol, len);
+    if ((ptr1+len)>=last) {
+      len-=last-(ptr1+len);
+    }
+
+    strncat(tmpbuff, ptr1+acol, len);
     strcat(tmpbuff, "\n");
 
-    ptr_s=ptr_e+1;
-#endif
+    ptr1=ptr2+1;
   }
   strcpy(out, tmpbuff);
@@ -302,16 +275,19 @@
 char *stristr(char *a, char *b)
 {
-  char *x, *y;
-  char *ret = NULL;
-  if ((x = g_utf8_casefold(a, -1)) != NULL) {
-    if ((y = g_utf8_casefold(b, -1)) != NULL) {
-      ret = strstr(x, y);
-      if (ret != NULL) {
-	ret = ret - x + a;
-      }
-      g_free(y);
-    }
-    g_free(x);
-  }
+  char *x, *y, *ret;
+
+  if ((x=owl_strdup(a))==NULL) return(NULL);
+  if ((y=owl_strdup(b))==NULL) return(NULL);
+  downstr(x);
+  downstr(y);
+  ret=strstr(x, y);
+  if (ret==NULL) {
+    owl_free(x);
+    owl_free(y);
+    return(NULL);
+  }
+  ret=ret-x+a;
+  owl_free(x);
+  owl_free(y);
   return(ret);
 }
@@ -320,15 +296,7 @@
 int only_whitespace(char *s)
 {
-  if (g_utf8_validate(s,-1,NULL)) {
-    char *p;
-    for(p = s; p[0]; p=g_utf8_next_char(p)) {
-      if (!g_unichar_isspace(g_utf8_get_char(p))) return 0;
-    }
-  }
-  else {
-    int i;
-    for (i=0; s[i]; i++) {
-      if (!isspace((int) s[i])) return(0);
-    }
+  int i;
+  for (i=0; s[i]; i++) {
+    if (!isspace((int) s[i])) return(0);
   }
   return(1);
@@ -359,5 +327,5 @@
   tolen  = strlen(to);
   fromlen  = strlen(from);
-  out = owl_malloc(outlen);
+  out = malloc(outlen);
 
   while (in[inpos]) {
Index: util.c
===================================================================
--- util.c	(revision 840270156f5630a4aeef58aaa9bb9cb1e4131f5b)
+++ util.c	(revision 89f5338caeb1828d0000cccaf478f1808203a6b1)
@@ -399,4 +399,13 @@
 }
 
+/* downcase the string 'foo' */
+void downstr(char *foo)
+{
+  int i;
+  for (i=0; foo[i]!='\0'; i++) {
+    foo[i]=tolower(foo[i]);
+  }
+}
+
 /* Caller must free response. 
  * Takes in strings which are space-separated lists of tokens
@@ -437,35 +446,49 @@
 void *owl_malloc(size_t size)
 {
-  return(g_malloc(size));
+  return(malloc(size));
 }
 
 void owl_free(void *ptr)
 {
-  g_free(ptr);
+  free(ptr);
 }
 
 char *owl_strdup(const char *s1)
 {
-  return(g_strdup(s1));
+  return(strdup(s1));
 }
 
 void *owl_realloc(void *ptr, size_t size)
 {
-  return(g_realloc(ptr, size));
+  return(realloc(ptr, size));
 }
 
 /* allocates memory and returns the string or null.
  * caller must free the string. 
+ * from Linux sprintf man page. 
  */
 char *owl_sprintf(const char *fmt, ...)
 {
+  int n, size = 100;
+  char *p;
   va_list ap;
-  char *ret = NULL;
-  va_start(ap, fmt);
-  ret = g_strdup_vprintf(fmt, ap);
-  va_end(ap);
-  return ret;
-}
-
+  if ((p = owl_malloc (size)) == NULL) return (NULL);
+  while (1) {
+    /* Try to print in the allocated space. */
+    va_start(ap, fmt);
+    n = vsnprintf (p, size, fmt, ap);
+    va_end(ap);
+    /* If that worked, return the string. */
+    if (n > -1 && n < size)
+      return p;
+    /* Else try again with more space. */
+    if (n > -1)    /* glibc 2.1 */
+      size = n+1; /* precisely what is needed */
+    else           /* glibc 2.0 */
+      size *= 2;  /* twice the old size */
+    if ((p = owl_realloc (p, size)) == NULL)
+      return NULL;
+  }
+}
 
 /* Return the owl color associated with the named color.  Return -1
@@ -753,102 +776,9 @@
 }
 
-char * owl_get_datadir()
-{
-  char * datadir = getenv("BARNOWL_DATA_DIR");
-  if(datadir != NULL)
-    return strchr(datadir, '=') + 1;
-  return DATADIR;
-}
-
-/* Strips format characters from a valid utf-8 string. Returns the
-   empty string if 'in' does not validate. */
-char * owl_strip_format_chars(char *in)
-{
-  char *r;
-  if (g_utf8_validate(in, -1, NULL)) {
-    char *s, *p;
-    r = owl_malloc(strlen(in)+1);
-    r[0] = '\0';
-    s = in;
-    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    while(p) {
-      /* If it's a format character, copy up to it, and skip all
-	 immediately following format characters. */
-      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	strncat(r, s, p-s);
-	p = g_utf8_next_char(p);
-	while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	  p = g_utf8_next_char(p);
-	}
-	s = p;
-	p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-      }
-      else {
-	p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-      }
-    }
-    if (s) strcat(r,s);
-  }
-  else {
-    r = owl_strdup("");
-  }
-  return r;
-}
-
-/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
- * the caller to specify an alternative in the future. We also strip
- * out characters in Unicode Plane 16, as we use that plane internally
- * for formatting.
- */
-char * owl_validate_or_convert(char *in)
-{
-  if (g_utf8_validate(in, -1, NULL)) {
-    return owl_strip_format_chars(in);
-  }
-  else {
-    return g_convert(in, -1,
-		     "UTF-8", "ISO-8859-1",
-		     NULL, NULL, NULL);
-  }
-}
-/* Attempts to convert 'in' to ISO-8859-1. Returns that if possible,
-   else returns UTF-8.
- */
-char * owl_get_iso_8859_1_if_possible(char *in)
-{
-  char *out;
-  if (g_utf8_validate(in, -1, NULL)) {
-    out = g_convert(in, -1,
-		    "ISO-8859-1", "UTF-8",
-		    NULL, NULL, NULL);
-    if (!out) {
-      out = owl_strdup(in);
-    }
-  }
-  else {
-    out = owl_strdup("");
-  }
-  return out;
-}
-
-/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
-int owl_util_can_break_after(gunichar c)
-{
-  
-  if (c == ' ') return 1;
-  if (c >= 0x3000 && c <= 0x312f) {
-    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
-    if (c == 0x300a || c == 0x300c || c == 0x300e ||
-        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
-        c == 0x3018 || c == 0x301a)
-      return 0;
-    return 1;
-  }
-  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
-  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
-  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
-  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
-  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
-  return 0;
+char * owl_get_datadir() {
+    char * datadir = getenv("BARNOWL_DATA_DIR");
+    if(datadir != NULL)
+        return strchr(datadir, '=') + 1;
+    return DATADIR;
 }
 
Index: viewwin.c
===================================================================
--- viewwin.c	(revision 47519e1bcab60a6026c4192bf5b20290f37f4737)
+++ viewwin.c	(revision 8721756cdb2a0ef8c380c35ec3bf73d2c0e1508a)
@@ -73,5 +73,5 @@
   owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
 
-  owl_fmtext_curs_waddstr_without_search(&fm2, v->curswin);
+  owl_fmtext_curs_waddstr(&fm2, v->curswin);
 
   /* print the message at the bottom */
Index: width.c
===================================================================
--- wcwidth.c	(revision 47519e1bcab60a6026c4192bf5b20290f37f4737)
+++ 	(revision )
@@ -1,309 +1,0 @@
-/*
- * This is an implementation of wcwidth() and wcswidth() (defined in
- * IEEE Std 1002.1-2001) for Unicode.
- *
- * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
- * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
- *
- * In fixed-width output devices, Latin characters all occupy a single
- * "cell" position of equal width, whereas ideographic CJK characters
- * occupy two such cells. Interoperability between terminal-line
- * applications and (teletype-style) character terminals using the
- * UTF-8 encoding requires agreement on which character should advance
- * the cursor by how many cell positions. No established formal
- * standards exist at present on which Unicode character shall occupy
- * how many cell positions on character terminals. These routines are
- * a first attempt of defining such behavior based on simple rules
- * applied to data provided by the Unicode Consortium.
- *
- * For some graphical characters, the Unicode standard explicitly
- * defines a character-cell width via the definition of the East Asian
- * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
- * In all these cases, there is no ambiguity about which width a
- * terminal shall use. For characters in the East Asian Ambiguous (A)
- * class, the width choice depends purely on a preference of backward
- * compatibility with either historic CJK or Western practice.
- * Choosing single-width for these characters is easy to justify as
- * the appropriate long-term solution, as the CJK practice of
- * displaying these characters as double-width comes from historic
- * implementation simplicity (8-bit encoded characters were displayed
- * single-width and 16-bit ones double-width, even for Greek,
- * Cyrillic, etc.) and not any typographic considerations.
- *
- * Much less clear is the choice of width for the Not East Asian
- * (Neutral) class. Existing practice does not dictate a width for any
- * of these characters. It would nevertheless make sense
- * typographically to allocate two character cells to characters such
- * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
- * represented adequately with a single-width glyph. The following
- * routines at present merely assign a single-cell width to all
- * neutral characters, in the interest of simplicity. This is not
- * entirely satisfactory and should be reconsidered before
- * establishing a formal standard in this area. At the moment, the
- * decision which Not East Asian (Neutral) characters should be
- * represented by double-width glyphs cannot yet be answered by
- * applying a simple rule from the Unicode database content. Setting
- * up a proper standard for the behavior of UTF-8 character terminals
- * will require a careful analysis not only of each Unicode character,
- * but also of each presentation form, something the author of these
- * routines has avoided to do so far.
- *
- * http://www.unicode.org/unicode/reports/tr11/
- *
- * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
- *
- * Permission to use, copy, modify, and distribute this software
- * for any purpose and without fee is hereby granted. The author
- * disclaims all warranties with regard to this software.
- *
- * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
- */
-
-#include <wchar.h>
-
-static struct interval {
-  int first;
-  int last;
-};
-
-/* auxiliary function for binary search in interval table */
-static int bisearch(wchar_t ucs, const struct interval *table, int max) {
-  int min = 0;
-  int mid;
-
-  if (ucs < table[0].first || ucs > table[max].last)
-    return 0;
-  while (max >= min) {
-    mid = (min + max) / 2;
-    if (ucs > table[mid].last)
-      min = mid + 1;
-    else if (ucs < table[mid].first)
-      max = mid - 1;
-    else
-      return 1;
-  }
-
-  return 0;
-}
-
-
-/* The following two functions define the column width of an ISO 10646
- * character as follows:
- *
- *    - The null character (U+0000) has a column width of 0.
- *
- *    - Other C0/C1 control characters and DEL will lead to a return
- *      value of -1.
- *
- *    - Non-spacing and enclosing combining characters (general
- *      category code Mn or Me in the Unicode database) have a
- *      column width of 0.
- *
- *    - SOFT HYPHEN (U+00AD) has a column width of 1.
- *
- *    - Other format characters (general category code Cf in the Unicode
- *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
- *
- *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
- *      have a column width of 0.
- *
- *    - Spacing characters in the East Asian Wide (W) or East Asian
- *      Full-width (F) category as defined in Unicode Technical
- *      Report #11 have a column width of 2.
- *
- *    - All remaining characters (including all printable
- *      ISO 8859-1 and WGL4 characters, Unicode control characters,
- *      etc.) have a column width of 1.
- *
- * This implementation assumes that wchar_t characters are encoded
- * in ISO 10646.
- */
-
-int mk_wcwidth(wchar_t ucs)
-{
-  /* sorted list of non-overlapping intervals of non-spacing characters */
-  /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
-  static const struct interval combining[] = {
-    { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
-    { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
-    { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
-    { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
-    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
-    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
-    { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
-    { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
-    { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
-    { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
-    { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
-    { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
-    { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
-    { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
-    { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
-    { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
-    { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
-    { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
-    { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
-    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
-    { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
-    { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
-    { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
-    { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
-    { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
-    { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
-    { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
-    { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
-    { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
-    { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
-    { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
-    { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
-    { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
-    { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
-    { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
-    { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
-    { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
-    { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
-    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
-    { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
-    { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
-    { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
-    { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
-    { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
-    { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
-    { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
-    { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
-    { 0xE0100, 0xE01EF }
-  };
-
-  /* test for 8-bit control characters */
-  if (ucs == 0)
-    return 0;
-  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
-    return -1;
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, combining,
-	       sizeof(combining) / sizeof(struct interval) - 1))
-    return 0;
-
-  /* if we arrive here, ucs is not a combining or C0/C1 control character */
-
-  return 1 + 
-    (ucs >= 0x1100 &&
-     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
-      ucs == 0x2329 || ucs == 0x232a ||
-      (ucs >= 0x2e80 && ucs <= 0xa4cf &&
-       ucs != 0x303f) ||                  /* CJK ... Yi */
-      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
-      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
-      (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
-      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
-      (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
-      (ucs >= 0xffe0 && ucs <= 0xffe6) ||
-      (ucs >= 0x20000 && ucs <= 0x2fffd) ||
-      (ucs >= 0x30000 && ucs <= 0x3fffd)));
-}
-
-
-int mk_wcswidth(const wchar_t *pwcs, size_t n)
-{
-  int w, width = 0;
-
-  for (;*pwcs && n-- > 0; pwcs++)
-    if ((w = mk_wcwidth(*pwcs)) < 0)
-      return -1;
-    else
-      width += w;
-
-  return width;
-}
-
-
-/*
- * The following functions are the same as mk_wcwidth() and
- * mk_wcswidth(), except that spacing characters in the East Asian
- * Ambiguous (A) category as defined in Unicode Technical Report #11
- * have a column width of 2. This variant might be useful for users of
- * CJK legacy encodings who want to migrate to UCS without changing
- * the traditional terminal character-width behaviour. It is not
- * otherwise recommended for general use.
- */
-int mk_wcwidth_cjk(wchar_t ucs)
-{
-  /* sorted list of non-overlapping intervals of East Asian Ambiguous
-   * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
-  static const struct interval ambiguous[] = {
-    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
-    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
-    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
-    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
-    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
-    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
-    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
-    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
-    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
-    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
-    { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
-    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
-    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
-    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
-    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
-    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
-    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
-    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
-    { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
-    { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
-    { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
-    { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
-    { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
-    { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
-    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
-    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
-    { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
-    { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
-    { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
-    { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
-    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
-    { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
-    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
-    { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
-    { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
-    { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
-    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
-    { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
-    { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
-    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
-    { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
-    { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
-    { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
-    { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
-    { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
-    { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
-    { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
-    { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
-    { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
-    { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
-    { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
-    { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
-  };
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, ambiguous,
-	       sizeof(ambiguous) / sizeof(struct interval) - 1))
-    return 2;
-
-  return mk_wcwidth(ucs);
-}
-
-
-int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
-{
-  int w, width = 0;
-
-  for (;*pwcs && n-- > 0; pwcs++)
-    if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
-      return -1;
-    else
-      width += w;
-
-  return width;
-}
Index: zcrypt.c
===================================================================
--- zcrypt.c	(revision 34509d514dfa9ee441febffc6d61e108962d1507)
+++ zcrypt.c	(revision 9ceee9d93177e80e7794f45d5ba9e611169e4d55)
@@ -385,5 +385,5 @@
 
 /* Build a space-separated string from argv from elements between start  *
- * and end - 1.  owl_malloc()'s the returned string. */
+ * and end - 1.  malloc()'s the returned string. */
 char *BuildArgString(char **argv, int start, int end) {
   int len = 1;
@@ -397,5 +397,5 @@
 
   /* Allocate memory */
-  result = (char *)owl_malloc(len);
+  result = (char *)malloc(len);
   if (result) {
     /* Build the string */
@@ -482,5 +482,5 @@
       /* Prepare result to be returned */
       char *temp = keyfile;
-      keyfile = (char *)owl_malloc(strlen(temp) + 1);
+      keyfile = (char *)malloc(strlen(temp) + 1);
       if (keyfile) {
 	strcpy(keyfile, temp);
@@ -611,5 +611,5 @@
       }
       use_buffer = TRUE;
-      if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) {
+      if ((inptr = inbuff = (char *)malloc(MAX_RESULT)) == NULL) {
 	printf("Memory allocation error\n");
 	return FALSE;
@@ -639,5 +639,5 @@
       printf("Could not run zwrite\n");
       if (freein && inbuff) {
-	owl_free(inbuff);
+	free(inbuff);
       }
       return(FALSE);
@@ -685,5 +685,5 @@
 
   /* Free the input buffer, if necessary */
-  if (freein && inbuff) owl_free(inbuff);
+  if (freein && inbuff) free(inbuff);
 
   return(!error);
Index: zephyr.c
===================================================================
--- zephyr.c	(revision 10e396337dd6bf954d7f0d8ef97faf81999c7db3)
+++ zephyr.c	(revision 10e396337dd6bf954d7f0d8ef97faf81999c7db3)
@@ -354,46 +354,8 @@
   return(owl_strdup(""));
 }
-
-char *owl_zephyr_get_field_as_utf8(ZNotice_t *n, int j)
-{
-  int i, count, save;
-
-  /* If there's no message here, just run along now */
-  if (n->z_message_len == 0)
-    return(owl_strdup(""));
-
-  count=save=0;
-  for (i = 0; i < n->z_message_len; i++) {
-    if (n->z_message[i]=='\0') {
-      count++;
-      if (count == j) {
-	/* just found the end of the field we're looking for */
-	return(owl_validate_or_convert(n->z_message + save));
-      } else {
-	save = i + 1;
-      }
-    }
-  }
-  /* catch the last field, which might not be null terminated */
-  if (count == j - 1) {
-    char *tmp, *out;
-    tmp = owl_malloc(n->z_message_len-save+5);
-    memcpy(tmp, n->z_message+save, n->z_message_len-save);
-    tmp[n->z_message_len-save]='\0';
-    out = owl_validate_or_convert(tmp);
-    owl_free(tmp);
-    return out;
-  }
-
+#else
+char *owl_zephyr_get_field(void *n, int j)
+{
   return(owl_strdup(""));
-}
-#else
-char *owl_zephyr_get_field(void *n, int j)
-{
-  return(owl_strdup(""));
-}
-char *owl_zephyr_get_field_as_utf8(ZNotice_t *n, int j)
-{
-  return owl_zephyr_get_field(n, j);
 }
 #endif
Index: zwrite.c
===================================================================
--- zwrite.c	(revision 7b1d048f7f97c017e859a6805cd148da213a3bc3)
+++ zwrite.c	(revision 1fe100c61c2374e461ad9d7c12938dbf52b015b6)
@@ -44,5 +44,5 @@
 	break;
       }
-      z->class=owl_get_iso_8859_1_if_possible(myargv[1]);
+      z->class=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -52,5 +52,5 @@
 	break;
       }
-      z->inst=owl_get_iso_8859_1_if_possible(myargv[1]);
+      z->inst=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -60,5 +60,5 @@
 	break;
       }
-      z->realm=owl_get_iso_8859_1_if_possible(myargv[1]);
+      z->realm=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -68,5 +68,5 @@
 	break;
       }
-      z->zsig=owl_get_iso_8859_1_if_possible(myargv[1]);
+      z->zsig=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -76,5 +76,5 @@
 	break;
       }
-      z->opcode=owl_get_iso_8859_1_if_possible(myargv[1]);
+      z->opcode=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -93,7 +93,7 @@
       myargv++;
       myargc--;
-      z->message=owl_get_iso_8859_1_if_possible("");
+      z->message=owl_strdup("");
       while (myargc) {
-	z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
+	z->message=realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
 	strcat(z->message, myargv[0]);
 	strcat(z->message, " ");
@@ -113,5 +113,5 @@
     } else {
       /* anything unattached is a recipient */
-      owl_list_append_element(&(z->recips), owl_get_iso_8859_1_if_possible(myargv[0]));
+      owl_list_append_element(&(z->recips), strdup(myargv[0]));
       myargv++;
       myargc--;
@@ -146,5 +146,5 @@
 
     if (zsigowlvar && *zsigowlvar) {
-      z->zsig=owl_get_iso_8859_1_if_possible(zsigowlvar);
+      z->zsig=owl_strdup(zsigowlvar);
     } else if (zsigproc && *zsigproc) {
       FILE *file;
@@ -161,5 +161,5 @@
       if (!file) {
 	if (zsigzvar && *zsigzvar) {
-	  z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
+	  z->zsig=owl_strdup(zsigzvar);
 	}
       } else {
@@ -175,7 +175,7 @@
       }
     } else if (zsigzvar) {
-      z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
+      z->zsig=owl_strdup(zsigzvar);
     } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
-      z->zsig=owl_get_iso_8859_1_if_possible(pw->pw_gecos);
+      z->zsig=strdup(pw->pw_gecos);
       ptr=strchr(z->zsig, ',');
       if (ptr) {
@@ -218,5 +218,4 @@
   int i, j;
   char toline[LINE];
-  char *tmp = NULL;
 
   if (z->message) owl_free(z->message);
@@ -232,10 +231,8 @@
       }
     }
-    tmp = owl_get_iso_8859_1_if_possible(msg);
-    z->message=owl_sprintf("%s\n%s", toline, tmp);
+    z->message=owl_sprintf("%s\n%s", toline, msg);
   } else {
-    z->message=owl_get_iso_8859_1_if_possible(msg);
-  }
-  if (tmp) owl_free(tmp);
+    z->message=owl_strdup(msg);
+  }
 }
 
@@ -308,5 +305,5 @@
 {
   if (z->opcode) owl_free(z->opcode);
-  z->opcode=owl_get_iso_8859_1_if_possible(opcode);
+  z->opcode=owl_strdup(opcode);
 }
 
