Changeset 8c93479


Ignore:
Timestamp:
May 11, 2008, 10:57:44 PM (16 years ago)
Author:
Nelson Elhage <nelhage@mit.edu>
Branches:
master, barnowl_perlaim, debian, release-1.10, release-1.4, release-1.5, release-1.6, release-1.7, release-1.8, release-1.9
Children:
426735d
Parents:
0eaa488 (diff), feabce2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge the unicode branch to trunk

........
  r776 | asedeno | 2007-12-23 19:48:01 -0500 (Sun, 23 Dec 2007) | 10 lines
  
  GLib/Unicode branch - adding glib dependency.
  
  Linking BarnOwl to GLib. 
  
  Cleaning up some malloc/realloc/strdup/free code, moving to owl_*
  functions for each.
  
  Changing to GLib memory allocation functions.
........
  r780 | asedeno | 2007-12-24 02:53:11 -0500 (Mon, 24 Dec 2007) | 21 lines
  
  UTF-8 - first pass
  
  unicode changes:
  * remove downstr() from text.c, replace on site with calls to g_utf8_strdown.
    In place downcasing is not a good idea, so the downstr() contract is unfulfillable.
  
  * make owl_text_truncate_cols() and owl_fmtext_truncate_cols() understand character width.
    This may need more work. Some code duplication - see if we can refactor.
  
  * stristr() rewritten to yse g_utf_casefold() instead of downstr(), and restructured to have a single return.
  
  * only_whitespace() rewritten for unicode.
  
  glib changes:
  * rewrite owl_sprintf() in terms of g_strdup_vprintf()
  
  WARNING: THIS IS NOT SAFE YET. Network data is not yet sanitized. Non
  UTF-8 inputs may do horrible things to you. This phase is just
  working on rendering.
........
  r781 | asedeno | 2007-12-24 03:10:38 -0500 (Mon, 24 Dec 2007) | 1 line
  
  full path to pkg.m4 in autoconf.in
........
  r782 | asedeno | 2007-12-24 10:14:09 -0500 (Mon, 24 Dec 2007) | 9 lines
  
  Unicode / Glib branch:
  
  * include wchar.h
  * replace hand-rolled width detection with wcswidth.
  * pad with space if we end up halfway into a character at the start of a line.
  
  WARNING: Still not safe.
........
  r784 | asedeno | 2007-12-27 11:01:03 -0500 (Thu, 27 Dec 2007) | 20 lines
  
  Unicode / glib branch
  
  Reworked the fmtext format to use in-line formatting.  Characters used
  for formatting are part of Unicode Supplemental Private Area-B, or
  Plane 16.
  
  fmtext no longer need 5x the text space to store formatting
  information, though they are harder to change at arbitrary
  points. This was something we hardly ever did anyhow, and we can still
  do everything we need to do.
  
  fmtext keeps a pair of colors and a char for default attributes to be
  applied when necessary.
  
  Searching is now done inline at owl_fmtext_waddstr() rather than
  specifying a section of the string to be reversed.
  
  This probably still needs some cleanup and more comments, but it
  works.
........
  r786 | asedeno | 2007-12-28 17:04:34 -0500 (Fri, 28 Dec 2007) | 6 lines
  
  unicode/glib branch.
  First pass at incoming zephyr -> UTF-8 sanitizing.
  This only operates on incoming data so far.
  We still need to clean outgoing data -- the plan is to attempt conversion
  to ISO-8859-1, and use that if it works.
........
  r787 | asedeno | 2007-12-28 17:21:57 -0500 (Fri, 28 Dec 2007) | 3 lines
  
  unicode/glib branch
  Fixing bug encountered when last field was not null-terminated.
........
  r788 | asedeno | 2007-12-29 02:55:43 -0500 (Sat, 29 Dec 2007) | 7 lines
  
  unicode/glib branch
  first pass at outbound zephyr -> iso-8859-1 sanitizing.
  Not that we can input anything other than ascii yet...
  
  The plan is that for a given field, we'll try to convert to iso-8859-1.
  If that doesn't work, use utf-8.
........
  r792 | asedeno | 2008-01-02 02:42:05 -0500 (Wed, 02 Jan 2008) | 21 lines
  
  unicode / glib branch
  
  text entry:
  * first pass at utf-8 text entry. This is not yet complete, and it certainly has bugs.
    The following is an incomplete list of functions that will probably misbehave if you use them.
    - owl_editwin_move_to_nextword()
    - owl_editwin_move_to_previousword()
    - owl_editwin_delete_nextword()
    - owl_editwin_delete_previousword()
    - owl_editwin_delete_to_endofline()
    - owl_editwin_fill_paragraph()
  
  format text:
  * owl_fmtext_curs_waddstr() contract restored to match trunk.
  * owl_fmtext_curs_waddstr_without_search() added.
  
  misc:
  * Importing Markus Kuhn's wcwidth.c from
    http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
  * Change wcwidth() calls to mk_wcwidth()
........
  r793 | asedeno | 2008-01-02 13:56:33 -0500 (Wed, 02 Jan 2008) | 8 lines
  
  unicode / glib branch
  * set min glib version to 2.12.0
   - first to support Unicode 5.0
  
  * added glib_compat.c with our own implementation of
    g_unicode_ismark() for glib < 2.14
........
  r794 | asedeno | 2008-01-02 16:53:19 -0500 (Wed, 02 Jan 2008) | 4 lines
  
  Remove options for libcurses and libncurses. This really only works
  with libncursesw.
........
  r795 | asedeno | 2008-01-02 21:35:44 -0500 (Wed, 02 Jan 2008) | 3 lines
  
  unicode/glib branch
  * Fix search code so higlighting actually works.
........
  r796 | asedeno | 2008-01-02 22:51:28 -0500 (Wed, 02 Jan 2008) | 3 lines
  
  unicode/glib branch
  fixing bugs in editwin bufflen calculations.
........
  r797 | asedeno | 2008-01-04 14:31:55 -0500 (Fri, 04 Jan 2008) | 5 lines
  
  unicode/glib branch
  * Rework some logic in fmtext's column truncating code.
  * fix what appears to be an off-by-one error, though I can't explain why
    it never manifested in trunk.
........
  r798 | asedeno | 2008-01-04 14:32:59 -0500 (Fri, 04 Jan 2008) | 2 lines
  
  unicode/glib branch
  * removing some debugging code I left in accidentally.
........
  r800 | asedeno | 2008-01-07 23:11:57 -0500 (Mon, 07 Jan 2008) | 2 lines
  
  unicode/glib branch
  Strip formmating characters when dumping to file.
........
  r802 | asedeno | 2008-01-08 00:11:55 -0500 (Tue, 08 Jan 2008) | 4 lines
  
  unicode/glib branch
  * more strict utf-8 byte fetching.
  This probably still needs more work.
........
  r804 | asedeno | 2008-01-08 00:31:31 -0500 (Tue, 08 Jan 2008) | 4 lines
  
  unicode/glib branch
  * ignore KEY_RESIZE if we know what that is. We don't need an
  unhandled keypress every time we resize the terminal.
........
  r808 | nelhage | 2008-01-09 00:26:15 -0500 (Wed, 09 Jan 2008) | 3 lines
  
   r27173@lunatique:  nelhage | 2008-01-09 00:25:13 -0500
   Implement smartnarrow on channels
........
  r811 | asedeno | 2008-01-09 14:17:57 -0500 (Wed, 09 Jan 2008) | 1 line
  
  take two for input processing
........
  r813 | asedeno | 2008-01-09 14:32:01 -0500 (Wed, 09 Jan 2008) | 1 line
  
  Preserve colors when highlighting search terms.
........
  r832 | asedeno | 2008-01-11 14:46:52 -0500 (Fri, 11 Jan 2008) | 1 line
  
  fixing post-processing in the editwin.
........
  r833 | asedeno | 2008-01-11 15:32:14 -0500 (Fri, 11 Jan 2008) | 5 lines
  
  
  * drop unused struct member
  * char * != char
  
  This fixes unicode input, which was broken as of r811.
........
  r844 | asedeno | 2008-01-11 23:59:42 -0500 (Fri, 11 Jan 2008) | 3 lines
  
  unicode/glib
  * Do not use bit 0x80 to indicate meta. We have other uses for that bit.
  * shift it above ncurses's KEY_MAX instead.
........
  r846 | asedeno | 2008-01-12 01:18:20 -0500 (Sat, 12 Jan 2008) | 2 lines
  
  unicode/glib branch
  Eliminating a warning by un-internalizing a new fmtext function.
........
  r849 | asedeno | 2008-01-12 02:26:49 -0500 (Sat, 12 Jan 2008) | 4 lines
  
  unicode/glib branch
  * fix a typo that was causing background problems
  * pass defaults attributes through in the truncate functions
........
  r883 | asedeno | 2008-01-16 14:34:55 -0500 (Wed, 16 Jan 2008) | 3 lines
  
  Unicode/glib branch
  Patches to jabber libraries for better UTF-8 handling.
........
  r884 | asedeno | 2008-01-16 14:39:12 -0500 (Wed, 16 Jan 2008) | 2 lines
  
  Unicode/glib branch
  Shuffling a line of code to where it actually should be.
........
  r885 | asedeno | 2008-01-16 14:40:36 -0500 (Wed, 16 Jan 2008) | 2 lines
  
  Unicode/glib branch
  Pet peeve - tabs. That should be the end of it for now.
........
  r886 | asedeno | 2008-01-16 20:18:25 -0500 (Wed, 16 Jan 2008) | 8 lines
  
  unicode/glib branch
  
  editwin.c: make locktext deal with UTF-8
  
  Jabber - 
  More utf-8 sanitizing.
  New helper function to validate strings from C and set the utf8 flag if needed.
........
  r887 | asedeno | 2008-01-16 21:54:55 -0500 (Wed, 16 Jan 2008) | 5 lines
  
  unicode/glib branch
  Remove a debug message I accidentally left in.
  Remove the hours old check_utf8 hackery in favor of actually
  marking strings as UTF-8 from the C side.
........
  r888 | asedeno | 2008-01-16 21:58:09 -0500 (Wed, 16 Jan 2008) | 2 lines
  
  unicode/glib branch
  Remove more bad hacks.
........
  r892 | asedeno | 2008-01-17 01:23:53 -0500 (Thu, 17 Jan 2008) | 4 lines
  
  unicode/glib branch
  editwin.c - lots of utf-8 cleanup that I had been putting off.
  util.c - a can we break here'' function based on perl's Text::WrapI18N
........
  r893 | asedeno | 2008-01-17 02:03:11 -0500 (Thu, 17 Jan 2008) | 3 lines
  
  unicode/glib branch
  editwin.c - fix a wrapping bug I introduced in the last revision.
  It could leave us with a buffer that was not valid UTF-8
........
  r895 | asedeno | 2008-01-17 09:51:48 -0500 (Thu, 17 Jan 2008) | 2 lines
  
  unicode/glib branch
  removing more hackery I left behind after doing things the right way.
........
  r896 | asedeno | 2008-01-17 14:55:22 -0500 (Thu, 17 Jan 2008) | 3 lines
  
  unicode/glib branch
  better compliance with UTF-8 processing. Stop trying to pull in a UTF-8
  character as soon as we know something has gone wrong.
........
  r929 | asedeno | 2008-02-04 20:17:18 -0500 (Mon, 04 Feb 2008) | 4 lines
  
  unicode/glib branch
  * fix a typo in OWL_FMTEXT_UTF8_BGDEFAULT
  * fix a parsing issue for attributes
........
  r930 | asedeno | 2008-02-04 20:33:04 -0500 (Mon, 04 Feb 2008) | 3 lines
  
  unicode/glib branch
  * Fix nelhage's key_left bug. Don't spin at the locktext boundary.
........
  r931 | asedeno | 2008-02-04 21:23:16 -0500 (Mon, 04 Feb 2008) | 2 lines
  
  unicode/glib branch
  I think I like this better.
........
  r932 | asedeno | 2008-02-07 14:01:23 -0500 (Thu, 07 Feb 2008) | 6 lines
  
  unicode/glib branch
  
  Fix a bug in owl_editwin_move_to_previousword() which would skip over
  single letter words.
........
  r938 | nelhage | 2008-02-13 23:39:41 -0500 (Wed, 13 Feb 2008) | 2 lines
  
  Rename configure.in to configure.ac so Debian autoconf DTRT.
........
  r961 | asedeno | 2008-02-19 21:52:10 -0500 (Tue, 19 Feb 2008) | 1 line
  
  Fixing an obscure wrapping bug that nelhage and I tracked down.
........
  r979 | asedeno | 2008-03-02 18:30:35 -0500 (Sun, 02 Mar 2008) | 1 line
  
  Fix a unicode branch wordwrap problem.
........
  r1021 | asedeno | 2008-04-15 12:09:13 -0400 (Tue, 15 Apr 2008) | 1 line
  
  Unicode branch: Fix building without zephyr.
........
  r1032 | nelhage | 2008-05-02 16:17:10 -0400 (Fri, 02 May 2008) | 3 lines
  
  Put glib's CFLAGS and LDFLAGS at the beginning of the corresponding
  variables.
........
Files:
2 added
27 edited
1 moved

Legend:

Unmodified
Added
Removed
  • Makefile.in

    r864ed35 rdb0ac7e  
    2626     keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
    2727     aim.c buddy.c buddylist.c timer.c style.c errqueue.c \
    28      zbuddylist.c muxevents.c popexec.c obarray.c select.c
     28     zbuddylist.c muxevents.c popexec.c obarray.c select.c wcwidth.c \
     29     glib_compat.c
    2930OWL_SRC = owl.c
    3031TESTER_SRC = tester.c
  • aim.c

    re3e6cff rdb0ac7e  
    948948 
    949949  if (modname) {
    950     if (!(filename = malloc(strlen(priv->aimbinarypath)+1+strlen(modname)+4+1))) {
     950    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(modname)+4+1))) {
    951951      /* perror("memrequest: malloc"); */
    952952      return -1;
     
    954954    sprintf(filename, "%s/%s.ocm", priv->aimbinarypath, modname);
    955955  } else {
    956     if (!(filename = malloc(strlen(priv->aimbinarypath)+1+strlen(defaultmod)+1))) {
     956    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(defaultmod)+1))) {
    957957      /* perror("memrequest: malloc"); */
    958958      return -1;
     
    964964    if (!modname) {
    965965      /* perror("memrequest: stat"); */
    966       free(filename);
     966      owl_free(filename);
    967967      return -1;
    968968    }
     
    986986    int i;
    987987   
    988     free(filename); /* not needed */
     988    owl_free(filename); /* not needed */
    989989    owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
    990990    i = 8;
     
    993993    }
    994994   
    995     if (!(buf = malloc(i))) {
     995    if (!(buf = owl_malloc(i))) {
    996996      return -1;
    997997    }
     
    10171017    *buflenret = i;
    10181018  } else {
    1019     if (!(buf = malloc(len))) {
    1020       free(filename);
     1019    if (!(buf = owl_malloc(len))) {
     1020      owl_free(filename);
    10211021      return -1;
    10221022    }
     
    10241024    if (!(f = fopen(filename, "r"))) {
    10251025      /* perror("memrequest: fopen"); */
    1026       free(filename);
    1027       free(buf);
     1026      owl_free(filename);
     1027      owl_free(buf);
    10281028      return -1;
    10291029    }
    10301030   
    1031     free(filename);
     1031    owl_free(filename);
    10321032   
    10331033    if (fseek(f, offset, SEEK_SET) == -1) {
    10341034      /* perror("memrequest: fseek"); */
    10351035      fclose(f);
    1036       free(buf);
     1036      owl_free(buf);
    10371037      return -1;
    10381038    }
     
    10411041      /* perror("memrequest: fread"); */
    10421042      fclose(f);
    1043       free(buf);
     1043      owl_free(buf);
    10441044      return -1;
    10451045    }
     
    10761076  if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {
    10771077    aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
    1078     free(buf);
     1078    owl_free(buf);
    10791079  } else {
    10801080    owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
     
    13421342      int z;
    13431343     
    1344       newbuf = malloc(i+1);
     1344      newbuf = owl_malloc(i+1);
    13451345      for (z = 0; z < i; z++)
    13461346        newbuf[z] = (z % 10)+0x30;
    13471347      newbuf[i] = '\0';
    13481348      /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_ACK | AIM_IMFLAGS_AWAY, newbuf); */
    1349       free(newbuf);
     1349      owl_free(newbuf);
    13501350    }
    13511351  } else if (strstr(tmpstr, "seticqstatus")) {
  • cmd.c

    r6922edd r34509d5  
    7474  owl_cmd *cmd;
    7575
    76   tmpbuff=strdup(cmdbuff);
     76  tmpbuff=owl_strdup(cmdbuff);
    7777  argv=owl_parseline(tmpbuff, &argc);
    7878  if (argc < 0) {
  • config.h.in

    r03cf6b9 re23eb2b  
    2222#undef HAVE_LIBCOM_ERR
    2323
    24 /* Define to 1 if you have the `curses' library (-lcurses). */
    25 #undef HAVE_LIBCURSES
    26 
    2724/* Define to 1 if you have the `des425' library (-ldes425). */
    2825#undef HAVE_LIBDES425
     
    3936/* Define to 1 if you have the `krb5' library (-lkrb5). */
    4037#undef HAVE_LIBKRB5
    41 
    42 /* Define to 1 if you have the `ncurses' library (-lncurses). */
    43 #undef HAVE_LIBNCURSES
    4438
    4539/* Define to 1 if you have the `ncursesw' library (-lncursesw). */
  • configure.ac

    r18e28a4 rd9337637  
    1212fi
    1313
     14m4_include(/usr/share/aclocal/pkg.m4)
     15dnl m4_include(pkg.m4)
    1416
    1517dnl Check for Athena
     
    4446fi
    4547
    46 AC_CHECK_LIB(ncursesw, initscr,,
    47   AC_CHECK_LIB(ncurses, initscr,,
    48     AC_CHECK_LIB(curses, initscr,, AC_MSG_ERROR(No curses library found.))))
     48AC_CHECK_LIB(ncursesw, initscr,, AC_MSG_ERROR(No curses library found.))
    4949AC_CHECK_LIB(com_err, com_err)
    5050AC_CHECK_LIB(nsl, gethostbyname)
     
    109109LDFLAGS=${LDFLAGS}\ ${FOO}
    110110
     111dnl Add CFLAGS and LDFLAGS for glib-2.0
     112PKG_CHECK_MODULES(GLIB,glib-2.0)
     113
     114echo Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}
     115CFLAGS="${GLIB_CFLAGS} ${CFLAGS}"
     116echo Adding glib-2.0 LDFLAGS ${GLIB_LIBS}
     117LDFLAGS="${GLIB_LIBS} ${LDFLAGS}"
     118
     119
    111120dnl Checks for typedefs, structures, and compiler characteristics.
    112121
  • editwin.c

    raf1920fd r2d4ff14  
    143143  e->buffy=0;
    144144  owl_editwin_overwrite_string(e, text);
     145  owl_editwin_overwrite_char(e, '\0');
    145146  e->lock=strlen(text);
    146147  /* if (text[e->lock-1]=='\n') e->lock--; */
    147   e->buffx=x;
    148   e->buffy=y;
    149   owl_editwin_adjust_for_locktext(e);
     148  /*  e->buffx=x; */
     149  /*  e->buffy=y; */
     150  _owl_editwin_set_xy_by_index(e, e->lock);
    150151  owl_editwin_redisplay(e, 0);
    151152}
     
    255256
    256257  /* start at topline */
    257   ptr1=e->buff;
    258   for (i=0; i<e->topline; i++) {
    259     ptr2=strchr(ptr1, '\n');
     258  ptr1 = e->buff;
     259  for (i = 0; i < e->topline; i++) {
     260    ptr2 = strchr(ptr1, '\n');
    260261    if (!ptr2) {
    261262      /* we're already on the last line */
    262263      break;
    263264    }
    264     ptr1=ptr2+1;
     265    ptr1 = ptr2 + 1;
    265266  }
    266267  /* ptr1 now stores the starting point */
    267268
    268269  /* find the ending point and store it in ptr3 */
    269   ptr2=ptr1;
    270   ptr3=ptr1;
    271   for (i=0; i<e->winlines; i++) {
    272     ptr3=strchr(ptr2, '\n');
     270  ptr2 = ptr1;
     271  ptr3 = ptr1;
     272  for (i = 0; i < e->winlines; i++) {
     273    ptr3 = strchr(ptr2, '\n');
    273274    if (!ptr3) {
    274275      /* we've hit the last line */
    275276      /* print everything to the end */
    276       ptr3=e->buff+e->bufflen-1;
     277      ptr3 = e->buff + e->bufflen - 1;
    277278      ptr3--;
    278279      break;
    279280    }
    280     ptr2=ptr3+1;
    281   }
    282   ptr3+=2;
    283 
    284   buff=owl_malloc(ptr3-ptr1+50);
    285   strncpy(buff, ptr1, ptr3-ptr1);
    286   buff[ptr3-ptr1]='\0';
    287   if (e->echochar=='\0') {
     281    ptr2 = ptr3 + 1;
     282  }
     283  ptr3 += 2;
     284
     285  buff = owl_malloc(ptr3 - ptr1 + 50);
     286  strncpy(buff, ptr1, ptr3 - ptr1);
     287  buff[ptr3 - ptr1] = '\0';
     288  if (e->echochar == '\0') {
    288289    waddstr(e->curswin, buff);
    289290  } else {
    290291    /* translate to echochar, *except* for the locktext */
    291292    int len;
    292     int dolocklen=e->lock-(ptr1-e->buff);
    293 
    294     for (i=0; i<dolocklen; i++) {
    295       waddch(e->curswin, buff[i]);
    296     }
    297     len=strlen(buff);
    298     for (i=0; i<len-dolocklen; i++) {
     293    int dolocklen = e->lock - (ptr1 - e->buff);
     294    char *locktext;
     295    char tmp = e->buff[dolocklen];
     296
     297    e->buff[dolocklen] = '\0';
     298    locktext = owl_strdup(e->buff);
     299    e->buff[dolocklen] = tmp;
     300
     301    waddstr(e->curswin, locktext);
     302   
     303    len = strlen(buff);
     304    for (i = 0; i < len-dolocklen; i++) {
    299305      waddch(e->curswin, e->echochar);
    300306    }
    301307  }
    302   wmove(e->curswin, e->buffy-e->topline, e->buffx);
     308  wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
    303309  wnoutrefresh(e->curswin);
    304   if (update==1) {
     310  if (update == 1) {
    305311    doupdate();
    306312  }
    307313  owl_free(buff);
     314}
     315
     316/* Remove n bytes at cursor. */
     317void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
     318{
     319  int i = _owl_editwin_get_index_from_xy(e) + n;
     320  for (; i < e->bufflen; i++) {
     321    e->buff[i-n] = e->buff[i];
     322  }
     323 
     324  e->bufflen -= n;
     325  e->buff[e->bufflen] = '\0';
     326}
     327
     328/* Insert n bytes at cursor.*/
     329void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
     330{
     331  int i, z;
     332 
     333  if ((e->bufflen + n) > (e->allocated - 5)) {
     334    _owl_editwin_addspace(e);
     335  }
     336
     337  e->bufflen += n;
     338  e->buff[e->bufflen] = '\0';
     339 
     340  z = _owl_editwin_get_index_from_xy(e);
     341  for (i = e->bufflen - 1; i > z; i--) {
     342    e->buff[i] = e->buff[i - n];
     343  }
    308344}
    309345
     
    315351int _owl_editwin_linewrap_word(owl_editwin *e)
    316352{
    317   int i, z;
    318 
    319   z=_owl_editwin_get_index_from_xy(e);
    320   /* move back and line wrap the previous word */
    321   for (i=z-1; ; i--) {
    322     /* move back until you find a space or hit the beginning of the line */
    323     if (e->buff[i]==' ') {
    324       /* replace the space with a newline */
    325       e->buff[i]='\n';
    326       e->buffy++;
    327       e->buffx=z-i-1;
    328       /* were we on the last line */
    329       return(0);
    330     } else if (e->buff[i]=='\n' || i<=e->lock) {
    331       /* we hit the begginning of the line or the buffer, we cannot
    332        * wrap.
    333        */
    334       return(-1);
    335     }
    336   }
     353  int x, y;
     354  int i;
     355  char *ptr1, *start;
     356  gunichar c;
     357
     358  /* saving values */
     359  x = e->buffx;
     360  y = e->buffy;
     361  start = e->buff + e->lock;
     362
     363  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     364  ptr1 = g_utf8_find_prev_char(start, ptr1);
     365
     366  while (ptr1) {
     367    c = g_utf8_get_char(ptr1);
     368    if (owl_util_can_break_after(c)) {
     369      if (c != ' ') {
     370        i = ptr1 - e->buff;
     371        _owl_editwin_set_xy_by_index(e, i);
     372        _owl_editwin_insert_bytes(e, 1);
     373        /* _owl_editwin_insert_bytes may move e->buff. */
     374        ptr1 = e->buff + i;
     375      }
     376      *ptr1 = '\n';
     377      return 0;
     378    }
     379    else if (c == '\n') {
     380      return 0;
     381    }
     382    ptr1 = g_utf8_find_prev_char(start, ptr1);
     383  }
     384  return -1;
    337385}
    338386
     
    340388 * characters over)
    341389 */
    342 void owl_editwin_insert_char(owl_editwin *e, char c)
    343 {
    344  
    345   int z, i, ret;
     390void owl_editwin_insert_char(owl_editwin *e, gunichar c)
     391{
     392  int z, i, ret, len;
     393  char tmp[6];
     394  memset(tmp, '\0', 6);
    346395
    347396  /* \r is \n */
    348   if (c=='\r') {
    349     c='\n';
    350   }
    351 
    352   if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     397  if (c == '\r') {
     398    c = '\n';
     399  }
     400
     401  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    353402    /* perhaps later this will change some state that allows the string
    354403       to be read */
     
    356405  }
    357406
     407  g_unichar_to_utf8(c, tmp);
     408  len = strlen(tmp);
     409
    358410  /* make sure there is enough memory for the new text */
    359   if ((e->bufflen+1) > (e->allocated-5)) {
     411  if ((e->bufflen + len) > (e->allocated - 5)) {
    360412    _owl_editwin_addspace(e);
    361413  }
    362414
    363415  /* get the insertion point */
    364   z=_owl_editwin_get_index_from_xy(e);
     416  z = _owl_editwin_get_index_from_xy(e);
    365417
    366418  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
    367   if ((e->buffx+1==e->wrapcol) && (c!='\n')) {
    368     ret=_owl_editwin_linewrap_word(e);
    369     if (ret==-1) {
     419  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
     420    ret = _owl_editwin_linewrap_word(e);
     421    if (ret == -1) {
    370422      /* we couldn't wrap, insert a hard newline instead */
    371423      owl_editwin_insert_char(e, '\n');
     
    373425  }
    374426
    375   z=_owl_editwin_get_index_from_xy(e);
    376427  /* shift all the other characters right */
    377   for (i=e->bufflen; i>z; i--) {
    378     e->buff[i]=e->buff[i-1];
    379   }
    380 
    381   /* insert the new one */
    382   e->buff[z]=c;
     428  if (z != e->bufflen) {
     429    _owl_editwin_insert_bytes(e, len);
     430  }
     431
     432  /* insert the new character */
     433  for(i = 0; i < len; i++) {
     434    e->buff[z + i] = tmp[i];
     435  }
    383436
    384437  /* housekeeping */
    385   e->bufflen++;
    386   e->buff[e->bufflen]='\0';
    387 
     438  e->bufflen += len;
     439  e->buff[e->bufflen] = '\0';
     440 
    388441  /* advance the cursor */
    389   if (c=='\n') {
    390     e->buffx=0;
    391     e->buffy++;
    392   } else {
    393     e->buffx++;
    394   }
     442  z += len;
     443  _owl_editwin_set_xy_by_index(e, z);
    395444}
    396445
    397446/* overwrite the character at the current point with 'c' */
    398 void owl_editwin_overwrite_char(owl_editwin *e, char c)
    399 {
    400   int z;
    401  
     447void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
     448{
     449  int z, oldlen, newlen, i;
     450  char tmp[6];
     451  memset(tmp, '\0', 6);
     452
    402453  /* \r is \n */
    403   if (c=='\r') {
    404     c='\n';
    405   }
    406 
    407   if (c=='\n' && e->style==OWL_EDITWIN_STYLE_ONELINE) {
     454  if (c == '\r') {
     455    c = '\n';
     456  }
     457 
     458  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    408459    /* perhaps later this will change some state that allows the string
    409460       to be read */
     
    411462  }
    412463
    413   z=_owl_editwin_get_index_from_xy(e);
    414 
    415   /* only if we are at the end of the buffer do we create new space */
    416   if (z==e->bufflen) {
    417     if ((e->bufflen+1) > (e->allocated-5)) {
     464  g_unichar_to_utf8(c, tmp);
     465  newlen = strlen(tmp);
     466
     467  z = _owl_editwin_get_index_from_xy(e);
     468  {
     469    char *t = g_utf8_find_next_char(e->buff + z, NULL);
     470    oldlen = (t ? (t - (e->buff + z)) : 0);
     471  }
     472
     473  /* only if we are at the end of the buffer do we create new space here */
     474  if (z == e->bufflen) {
     475    if ((e->bufflen+newlen) > (e->allocated-5)) {
    418476      _owl_editwin_addspace(e);
    419477    }
    420478  }
    421  
    422   e->buff[z]=c;
    423 
    424   /* housekeeping if we are at the end of the buffer */
    425   if (z==e->bufflen) {
    426     e->bufflen++;
    427     e->buff[e->bufflen]='\0';
    428   }
    429 
     479  /* if not at the end of the buffer, adjust based in char size difference. */
     480  else if (oldlen > newlen) {
     481    _owl_editwin_remove_bytes(e, oldlen-newlen);
     482  }
     483  else /* oldlen < newlen */ {
     484    _owl_editwin_insert_bytes(e, newlen-oldlen);
     485  }
     486  /* Overwrite the old char*/
     487  for (i = 0; i < newlen; i++) {
     488    e->buff[z+i] = tmp[i];
     489  }
     490       
     491  /* housekeeping */
     492  if (z == e->bufflen) {
     493    e->bufflen += newlen;
     494    e->buff[e->bufflen] = '\0';
     495  }
     496 
    430497  /* advance the cursor */
    431   if (c=='\n') {
    432     e->buffx=0;
    433     e->buffy++;
    434   } else {
    435     e->buffx++;
    436   }
    437 
     498  z += newlen;
     499  _owl_editwin_set_xy_by_index(e, z);
    438500}
    439501
     
    443505void owl_editwin_delete_char(owl_editwin *e)
    444506{
    445   int z, i;
    446 
    447   if (e->bufflen==0) return;
     507  int z;
     508  char *p1, *p2;
     509  gunichar c;
     510
     511  if (e->bufflen == 0) return;
    448512 
    449513  /* get the deletion point */
    450   z=_owl_editwin_get_index_from_xy(e);
    451 
    452   if (z==e->bufflen) return;
    453 
    454   for (i=z; i<e->bufflen; i++) {
    455     e->buff[i]=e->buff[i+1];
    456   }
    457   e->bufflen--;
    458   e->buff[e->bufflen]='\0';
     514  z = _owl_editwin_get_index_from_xy(e);
     515
     516  if (z == e->bufflen) return;
     517
     518  p1 = e->buff + z;
     519  p2 = g_utf8_next_char(p1);
     520  c = g_utf8_get_char(p2);
     521  while (g_unichar_ismark(c)) {
     522    p2 = g_utf8_next_char(p2);
     523    c = g_utf8_get_char(p2);
     524  }
     525  _owl_editwin_remove_bytes(e, p2-p1);
    459526}
    460527
     
    467534{
    468535  int z;
    469   char tmp;
    470 
    471   if (e->bufflen==0) return;
     536  char *p1, *p2, *p3, *tmp;
     537
     538  if (e->bufflen == 0) return;
    472539 
    473540  /* get the cursor point */
    474   z=_owl_editwin_get_index_from_xy(e);
    475 
    476   if (z==e->bufflen) {
     541  z = _owl_editwin_get_index_from_xy(e);
     542
     543  if (z == e->bufflen) {
    477544    /* point is after last character */
    478545    z--;
    479546  } 
    480547
    481   if (z-1 < e->lock) {
     548  if (z - 1 < e->lock) {
    482549    /* point is at beginning of buffer, do nothing */
    483550    return;
    484551  }
    485552
    486   tmp=e->buff[z];
    487   e->buff[z]=e->buff[z-1];
    488   e->buff[z-1]=tmp;
    489   owl_editwin_key_right(e);
     553  /* Transpose two utf-8 unicode glyphs. */
     554  p1 = e->buff + z;
     555
     556  p2 = g_utf8_find_next_char(p1, NULL);
     557  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
     558    p2 = g_utf8_find_next_char(p2, NULL);
     559  }
     560  if (p2 == NULL) return;
     561
     562  p3 = g_utf8_find_prev_char(e->buff, p1);
     563  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
     564    p3 = g_utf8_find_prev_char(p3, NULL);
     565  }
     566  if (p3 == NULL) return;
     567
     568  tmp = owl_malloc(p2 - p3 + 5);
     569  *tmp = '\0';
     570  strncat(tmp, p1, p2 - p1);
     571  strncat(tmp, p3, p1 - p3);
     572  strncpy(p3, tmp, p2 - p3);
     573  owl_free(tmp);
     574  _owl_editwin_set_xy_by_index(e, p3 - e->buff);
    490575}
    491576
     
    495580void owl_editwin_insert_string(owl_editwin *e, char *string)
    496581{
    497   int i, j;
    498 
    499   j=strlen(string);
    500   for (i=0; i<j; i++) {
    501     owl_editwin_insert_char(e, string[i]);
     582  char *p;
     583  gunichar c;
     584  if (!g_utf8_validate(string, -1, NULL)) {
     585    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
     586    return;
     587  }
     588  p = string;
     589  c = g_utf8_get_char(p);
     590  while (c) {
     591    _owl_editwin_process_char(e, c);
     592    p = g_utf8_next_char(p);
     593    c = g_utf8_get_char(p);
    502594  }
    503595}
     
    509601void owl_editwin_overwrite_string(owl_editwin *e, char *string)
    510602{
    511   int i, j;
    512 
    513   j=strlen(string);
    514   for (i=0; i<j; i++) {
    515     owl_editwin_overwrite_char(e, string[i]);
     603  char *p;
     604  gunichar c;
     605
     606  if (!g_utf8_validate(string, -1, NULL)) {
     607    owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
     608    return;
     609  }
     610  p = string;
     611  c = g_utf8_get_char(p);
     612  while (c) {
     613    owl_editwin_overwrite_char(e, c);
     614    p = g_utf8_next_char(p);
     615    c = g_utf8_get_char(p);
    516616  }
    517617}
     
    524624  int i;
    525625  char *ptr1, *ptr2;
    526 
    527   if (e->bufflen==0) return(0);
     626  gunichar c;
     627
     628  if (e->bufflen == 0) return(0);
    528629 
    529630  /* first go to the yth line */
    530   ptr1=e->buff;
    531   for (i=0; i<e->buffy; i++) {
    532     ptr2=strchr(ptr1, '\n');
     631  ptr1 = e->buff;
     632  for (i = 0; i < e->buffy; i++) {
     633    ptr2= strchr(ptr1, '\n');
    533634    if (!ptr2) {
    534635      /* we're already on the last line */
    535636      break;
    536637    }
    537     ptr1=ptr2+1;
    538   }
    539 
    540   /* now go to the xth character */
    541   ptr2=strchr(ptr1, '\n');
    542   if (!ptr2) {
    543     ptr2=e->buff+e->bufflen;
    544   }
    545 
    546   if ((ptr2-ptr1) < e->buffx) {
    547     ptr1=ptr2-1;
    548   } else {
    549     ptr1+=e->buffx;
    550   }
    551 
    552   /* printf("DEBUG: index is %i\r\n", ptr1-e->buff); */
    553   return(ptr1-e->buff);
    554 }
     638    ptr1 = ptr2 + 1;
     639  }
     640
     641  /* now go to the xth cell */
     642  ptr2 = ptr1;
     643  i = 0;
     644  while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
     645    c = g_utf8_get_char(ptr2);
     646    i += (c == '\n' ? 1 : mk_wcwidth(c));
     647    ptr2 = g_utf8_next_char(ptr2);
     648  }
     649  while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
     650    ptr2 = g_utf8_next_char(ptr2);
     651  }
     652  if (ptr2 == NULL) return e->bufflen;
     653  return(ptr2 - e->buff);
     654}
     655
     656/* We assume x,y are not set to point to a mid-char */
     657gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
     658{
     659  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
     660}
     661
    555662
    556663void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
    557664{
    558   int z, i;
    559 
    560   z=_owl_editwin_get_index_from_xy(e);
    561   if (index>z) {
    562     for (i=0; i<index-z; i++) {
    563       owl_editwin_key_right(e);
    564     }
    565   } else if (index<z) {
    566     for (i=0; i<z-index; i++) {
    567       owl_editwin_key_left(e);
    568     }
    569   }
     665  char *ptr1, *ptr2, *target;
     666  gunichar c;
     667
     668  e->buffx = 0;
     669  e->buffy = 0;
     670
     671  ptr1 = e->buff;
     672  target = ptr1 + index;
     673  /* target sanitizing */
     674  if ((target[0] & 0x80) && (~target[0] & 0x40)) {
     675    /* middle of a utf-8 character, back up to previous character. */
     676    target = g_utf8_find_prev_char(e->buff, target);
     677  }
     678  c = g_utf8_get_char(target);
     679  while (g_unichar_ismark(c) && target > e->buff) {
     680    /* Adjust the target off of combining characters and the like. */
     681    target = g_utf8_find_prev_char(e->buff, target);
     682    c = g_utf8_get_char(target);
     683  }
     684  /* If we start with a mark, something is wrong.*/
     685  if (g_unichar_ismark(c)) return;
     686
     687  /* Now our target should be acceptable. */
     688  ptr2 = strchr(ptr1, '\n');
     689  while (ptr2 != NULL && ptr2 < target) {
     690    e->buffy++;
     691    ptr1 = ptr2 + 1;
     692    ptr2 = strchr(ptr1, '\n');
     693  }
     694  ptr2 = ptr1;
     695  while (ptr2 != NULL && ptr2 < target) {
     696    c = g_utf8_get_char(ptr2);
     697    e->buffx += mk_wcwidth(c);
     698    ptr2 = g_utf8_next_char(ptr2);
     699  }
     700}
     701
     702int _owl_editwin_cursor_adjustment(owl_editwin *e)
     703{
     704  char *ptr1, *ptr2;
     705  gunichar c;
     706  int x, i;
     707
     708  /* Find line */
     709  ptr1 = e->buff;
     710  ptr2 = strchr(ptr1, '\n');
     711  for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
     712    ptr1 = ptr2 + 1;
     713    ptr2 = strchr(ptr1, '\n');
     714  }
     715  ptr2 = ptr1;
     716
     717  /* Find char */
     718  x = 0;
     719  while (ptr2 != NULL && x < e->buffx) {
     720    if (*ptr2 == '\n') return 0;
     721    c = g_utf8_get_char(ptr2);
     722    x += mk_wcwidth(c);
     723    ptr2 = g_utf8_next_char(ptr2);
     724  }
     725 
     726  /* calculate x offset */
     727  return x - e->buffx;
    570728}
    571729
     
    574732  /* if we happen to have the cursor over locked text
    575733   * move it to be out of the locktext region */
    576   if (_owl_editwin_get_index_from_xy(e)<e->lock) {
     734  if (_owl_editwin_get_index_from_xy(e) < e->lock) {
    577735    _owl_editwin_set_xy_by_index(e, e->lock);
    578736  }
     
    594752{
    595753  if (e->buffy > 0) e->buffy--;
    596   if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
    597     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     754  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     755    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    598756  }
    599757
     
    612770
    613771  /* if we're past the last character move back */
    614   if (e->buffx >= owl_editwin_get_numchars_on_line(e, e->buffy)) {
    615     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     772  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     773    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    616774  }
    617775
     
    627785void owl_editwin_key_left(owl_editwin *e)
    628786{
    629   /* move left if we can, and maybe up a line */
    630   if (e->buffx>0) {
    631     e->buffx--;
    632   } else if (e->buffy>0) {
    633     e->buffy--;
    634     e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
    635   }
    636 
    637   /* do we need to scroll up? */
    638   if (e->buffy-e->topline < 0) {
    639     e->topline-=e->winlines/2;
     787  int i;
     788  char * p;
     789  i = _owl_editwin_get_index_from_xy(e);
     790  p = e->buff + i;
     791  p = g_utf8_find_prev_char(e->buff, p);
     792  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     793    p = g_utf8_find_prev_char(e->buff, p);
     794  }
     795  if (p == NULL) p = e->buff;
     796  _owl_editwin_set_xy_by_index(e, p - e->buff);
     797
     798  if (e->buffy - e->topline < 0) {
     799    e->topline -= e->winlines / 2;
    640800  }
    641801
     
    647807{
    648808  int i;
    649 
    650   /* move right if we can, and skip down a line if needed */
    651   i=owl_editwin_get_numchars_on_line(e, e->buffy);
    652   if (e->buffx < i) {
    653     e->buffx++;
    654     /*  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) { */
    655   } else if (_owl_editwin_get_index_from_xy(e) < e->bufflen) {
    656     if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    657       e->buffx=0;
    658       e->buffy++;
    659     }
     809  char * p;
     810  i = _owl_editwin_get_index_from_xy(e);
     811  p = e->buff + i;
     812  p = g_utf8_find_next_char(p, NULL);
     813  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     814    p = g_utf8_find_next_char(p, NULL);
     815  }
     816  if (p == NULL) {
     817    _owl_editwin_set_xy_by_index(e, e->bufflen);
     818  }
     819  else {
     820    _owl_editwin_set_xy_by_index(e, p - e->buff);
    660821  }
    661822
    662823  /* do we need to scroll down? */
    663   if (e->buffy-e->topline >= e->winlines) {
    664     e->topline+=e->winlines/2;
     824  if (e->buffy - e->topline >= e->winlines) {
     825    e->topline += e->winlines / 2;
    665826  }
    666827}
     
    669830{
    670831  int i, x;
     832  gunichar c = '\0';
    671833
    672834  /* if we're starting on a space, find the first non-space */
     
    681843  }
    682844
    683   /* find the next space, newline or end of line and go there, if
    684      already at the end of the line, continue on to the next */
    685   i=owl_editwin_get_numchars_on_line(e, e->buffy);
     845  /* find the next space, newline or end of line and go
     846     there, if already at the end of the line, continue on to the next */
     847  i=owl_editwin_get_numcells_on_line(e, e->buffy);
     848  c = _owl_editwin_get_char_at_xy(e);
    686849  if (e->buffx < i) {
    687850    /* move right till end of line */
    688851    while (e->buffx < i) {
    689       e->buffx++;
    690       if (e->buff[_owl_editwin_get_index_from_xy(e)]==' ') return;
     852      owl_editwin_key_right(e);
     853      c = _owl_editwin_get_char_at_xy(e);
     854      if (c == ' ') return;
    691855      if (e->buffx == i) return;
    692856    }
     
    694858    /* try to move down */
    695859    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
    696       if (e->buffy+1 <  owl_editwin_get_numlines(e)) {
     860      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
    697861        e->buffx=0;
    698862        e->buffy++;
     
    707871void owl_editwin_move_to_previousword(owl_editwin *e)
    708872{
    709   int i, x;
     873  int i;
     874  gunichar c;
     875  char *ptr1, *ptr2;
    710876
    711877  /* are we already at the beginning of the word? */
    712   i=_owl_editwin_get_index_from_xy(e);
    713   if ( (e->buff[i]!=' ' && e->buff[i]!='\n' && e->buff[i]!='\0') &&
    714        (e->buff[i-1]==' ' || e->buff[i-1]=='\n') ) {
     878  c = _owl_editwin_get_char_at_xy(e);
     879  i = _owl_editwin_get_index_from_xy(e);
     880  ptr1 = e->buff + i;
     881  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
     882    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
     883    c = g_utf8_get_char(ptr1);
     884    if (c == ' ' || c == '\n') {
     885      owl_editwin_key_left(e);     
     886    }
     887  }
     888
     889  /* are we starting on a space character? */
     890  i = _owl_editwin_get_index_from_xy(e);
     891  while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
     892    /* find the first non-space */
     893    owl_editwin_key_left(e);     
     894    i = _owl_editwin_get_index_from_xy(e);
     895  }
     896
     897  /* find the last non-space */
     898  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     899  while (ptr1 >= e->buff + e->lock) {
     900    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
     901    if (!ptr2) break;
     902   
     903    c = g_utf8_get_char(ptr2);
     904    if (c == ' ' || c == '\n'){
     905      break;
     906    }
    715907    owl_editwin_key_left(e);
    716   }
    717    
    718   /* are we starting on a space character? */
    719   i=_owl_editwin_get_index_from_xy(e);
    720   if (e->buff[i]==' ' || e->buff[i]=='\n' || e->buff[i]=='\0') {
    721     /* find the first non-space */
    722     for (x=i; x>=e->lock; x--) {
    723       if (e->buff[x]!=' ' && e->buff[x]!='\n' && e->buff[x]!='\0') {
    724         _owl_editwin_set_xy_by_index(e, x);
    725         break;
    726       }
    727     }
    728   }
    729 
    730   /* find the last non-space */
    731   i=_owl_editwin_get_index_from_xy(e);
    732   for (x=i; x>=e->lock; x--) {
    733     if (e->buff[x-1]==' ' || e->buff[x-1]=='\n') {
    734       _owl_editwin_set_xy_by_index(e, x);
    735       break;
    736     }
    737   }
    738   _owl_editwin_set_xy_by_index(e, x);
     908    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     909  }
    739910}
    740911
     
    742913void owl_editwin_delete_nextword(owl_editwin *e)
    743914{
    744   int z;
     915  char *ptr1, *start;
     916  gunichar c;
    745917
    746918  if (e->bufflen==0) return;
    747919
    748   /* if we start out on a space character then gobble all the spaces
    749      up first */
    750   while (1) {
    751     z=_owl_editwin_get_index_from_xy(e);
    752     if (e->buff[z]==' ' || e->buff[z]=='\n') {
    753       owl_editwin_delete_char(e);
    754     } else {
    755       break;
    756     }
    757   }
    758 
    759   /* then nuke the next word */
    760   while (1) {
    761     z=_owl_editwin_get_index_from_xy(e);
    762     /* z == e->bufflen check added to prevent a hang I (nelhage) have
    763        seen repeatedly while using owl. I'm not sure precisely what
    764        conditions lead to it. */
    765     if (z == e->bufflen
    766         || e->buff[z+1]==' ' || e->buff[z+1]=='\n' || e->buff[z+1]=='\0') break;
    767     owl_editwin_delete_char(e);
    768   }
    769   owl_editwin_delete_char(e);
     920  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     921  /* if we start out on a space character then jump past all the
     922     spaces up first */
     923  while (*ptr1 == ' ' || *ptr1 == '\n') {
     924    ++ptr1;
     925  }
     926
     927  /* then jump past the next word */
     928 
     929  while (ptr1 && ptr1 - e->buff < e->bufflen) {
     930    c = g_utf8_get_char(ptr1);
     931    if (c == ' ' || c == '\n' || c == '\0') break;
     932    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     933  }
     934
     935  if (ptr1) { /* We broke on a space, */
     936    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     937    if (ptr1) { /* and there's a character after it, */
     938      /* nuke everything back to our starting point. */
     939      _owl_editwin_remove_bytes(e, ptr1 - start);
     940      return;
     941    }
     942  }
     943 
     944  /* If we get here, we ran out of string, drop what's left. */
     945  *start = '\0';
     946  e->bufflen = start - e->buff;
    770947}
    771948
     
    773950{
    774951  /* go backwards to the last non-space character, then delete chars */
    775   int i, startpos, endpos;
     952  int startpos, endpos;
    776953
    777954  startpos = _owl_editwin_get_index_from_xy(e);
    778955  owl_editwin_move_to_previousword(e);
    779956  endpos = _owl_editwin_get_index_from_xy(e);
    780   for (i=0; i<startpos-endpos; i++) {
    781     owl_editwin_delete_char(e);
    782   }
     957  _owl_editwin_remove_bytes(e, startpos-endpos);
    783958}
    784959
     
    787962  int i;
    788963
    789   if (owl_editwin_get_numchars_on_line(e, e->buffy)>e->buffx) {
     964  if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
    790965    /* normal line */
    791966    i=_owl_editwin_get_index_from_xy(e);
     
    808983void owl_editwin_move_to_line_end(owl_editwin *e)
    809984{
    810   e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     985  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    811986}
    812987
     
    821996  /* go to last char */
    822997  e->buffy=owl_editwin_get_numlines(e)-1;
    823   e->buffx=owl_editwin_get_numchars_on_line(e, e->buffy);
     998  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
    824999  owl_editwin_key_right(e);
    8251000
     
    8611036  /* main loop */
    8621037  while (1) {
    863     i=_owl_editwin_get_index_from_xy(e);
     1038    i = _owl_editwin_get_index_from_xy(e);
    8641039
    8651040    /* bail if we hit the end of the buffer */
    866     if (i>=e->bufflen) break;
     1041    if (i >= e->bufflen || e->buff[i] == '\0') break;
    8671042
    8681043    /* bail if we hit the end of the paragraph */
    869     if (e->buff[i]=='\n' && e->buff[i+1]=='\n') break;
     1044    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
    8701045
    8711046    /* if we've travelled too far, linewrap */
    8721047    if ((e->buffx) >= e->fillcol) {
     1048      int len = e->bufflen;
    8731049      _owl_editwin_linewrap_word(e);
     1050      /* we may have added a character. */
     1051      if (i < save) save += e->bufflen - len;
     1052      _owl_editwin_set_xy_by_index(e, i);
    8741053    }
    8751054
    8761055    /* did we hit the end of a line too soon? */
    877     i=_owl_editwin_get_index_from_xy(e);
    878     if (e->buff[i]=='\n' && e->buffx<e->fillcol-1) {
     1056    /* asedeno: Here we replace a newline with a space. We may want to
     1057       consider removing the space if the characters to either side
     1058       are CJK ideograms.*/
     1059    i = _owl_editwin_get_index_from_xy(e);
     1060    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
    8791061      /* ********* we need to make sure we don't pull in a word that's too long ***********/
    8801062      e->buff[i]=' ';
    8811063    }
    882    
     1064
    8831065    /* fix spacing */
    884     i=_owl_editwin_get_index_from_xy(e);
    885     if (e->buff[i]==' ' && e->buff[i+1]==' ') {
    886       if (e->buff[i-1]=='.' || e->buff[i-1]=='!' || e->buff[i-1]=='?') {
     1066    i = _owl_editwin_get_index_from_xy(e);
     1067    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
     1068      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
    8871069        owl_editwin_key_right(e);
    8881070      } else {
    8891071        owl_editwin_delete_char(e);
    890         /* if we did this ahead of the save point, adjust it */
    891         if (i<save) save--;
     1072        /* if we did this ahead of the save point, adjust it. Changing
     1073           by one is fine here because we're only removing an ASCII
     1074           space. */
     1075        if (i < save) save--;
    8921076      }
    8931077    } else {
    8941078      owl_editwin_key_right(e);
    8951079    }
    896 
    8971080  }
    8981081
     
    9151098int owl_editwin_check_dotsend(owl_editwin *e)
    9161099{
    917   int i;
     1100  char *p, *p_n, *p_p;
     1101  gunichar c;
    9181102
    9191103  if (!e->dotsend) return(0);
    920   for (i=e->bufflen-1; i>0; i--) {
    921     if (e->buff[i] == '.'
    922         && (e->buff[i-1] == '\n' || e->buff[i-1] == '\r')
    923         && (e->buff[i+1] == '\n' || e->buff[i+1] == '\r')) {
    924       e->bufflen = i;
    925       e->buff[i] = '\0';
     1104
     1105  p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
     1106  p_n = g_utf8_find_next_char(p, NULL);
     1107  p_p = g_utf8_find_prev_char(e->buff, p);
     1108  c = g_utf8_get_char(p);
     1109  while (p != NULL) {
     1110    if (*p == '.'
     1111        && p_p != NULL && (*p_p == '\n' || *p_p == '\r')
     1112        && p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
     1113      e->bufflen = p - e->buff;
     1114      e->buff[e->bufflen] = '\0';
    9261115      return(1);
    9271116    }
    928     if (!isspace((int) e->buff[i])) {
    929       return(0);
    930     }
     1117    if (c != '\0' && !g_unichar_isspace(c)) return(0);
     1118    p_n = p;
     1119    p = p_p;
     1120    c = g_utf8_get_char(p);
     1121    p_p = g_utf8_find_prev_char(e->buff, p);
    9311122  }
    9321123  return(0);
    9331124}
    9341125
    935 void owl_editwin_post_process_char(owl_editwin *e, int j)
     1126void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
    9361127{
    9371128  /* check if we need to scroll down */
     
    9391130    e->topline+=e->winlines/2;
    9401131  }
    941   if ((j==13 || j==10) && owl_editwin_check_dotsend(e)) {
     1132  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
    9421133    owl_command_editmulti_done(e);
    9431134    return;
     
    9461137}
    9471138
    948 void owl_editwin_process_char(owl_editwin *e, int j)
    949 {
    950   if (j == ERR) return;
    951   if (j>127 || ((j<32) && (j!=10) && (j!=13))) {
    952     return;
    953   } else {
     1139void _owl_editwin_process_char(owl_editwin *e, gunichar j)
     1140{
     1141  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
    9541142    owl_editwin_insert_char(e, j);
     1143  }
     1144}
     1145
     1146
     1147void owl_editwin_process_char(owl_editwin *e, owl_input j)
     1148{
     1149  if (j.ch == ERR) return;
     1150  /* Ignore ncurses control characters. */
     1151  if (j.ch < 0x100) {
     1152    _owl_editwin_process_char(e, j.uch);
    9551153  }
    9561154}
     
    9791177  }
    9801178
    981   /* now go to the xth character */
    982   ptr2=strchr(ptr1, '\n');
    983   if (!ptr2) {
    984     return(e->buff + e->bufflen - ptr1);
    985   }
    986   return(ptr2-ptr1); /* don't count the newline for now */
     1179  /* now count characters */
     1180  i = 0;
     1181  ptr2 = ptr1;
     1182  while (ptr2 - e->buff < e->bufflen
     1183         && *ptr2 != '\n') {
     1184    ++i;
     1185    ptr2 = g_utf8_next_char(ptr2);
     1186  }
     1187  return i;
     1188}
     1189
     1190int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
     1191{
     1192  int i;
     1193  char *ptr1, *ptr2;
     1194  gunichar c;
     1195
     1196  if (e->bufflen==0) return(0);
     1197 
     1198  /* first go to the yth line */
     1199  ptr1=e->buff;
     1200  for (i=0; i<line; i++) {
     1201    ptr2=strchr(ptr1, '\n');
     1202    if (!ptr2) {
     1203      /* we're already on the last line */
     1204      return(0);
     1205    }
     1206    ptr1=ptr2+1;
     1207  }
     1208
     1209  /* now count cells */
     1210  i = 0;
     1211  ptr2 = ptr1;
     1212  while (ptr2 - e->buff < e->bufflen
     1213         && *ptr2 != '\n') {
     1214    c = g_utf8_get_char(ptr2);
     1215    i += mk_wcwidth(c);
     1216    ptr2 = g_utf8_next_char(ptr2);
     1217  }
     1218  return i;
    9871219}
    9881220
  • fmtext.c

    r005fc22 r6f6330b  
    88void owl_fmtext_init_null(owl_fmtext *f)
    99{
    10   f->textlen=0;
    11   f->bufflen=5;
    12   f->textbuff=owl_malloc(5);
    13   f->fmbuff=owl_malloc(5);
    14   f->fgcolorbuff=owl_malloc(5 * sizeof(short));
    15   f->bgcolorbuff=owl_malloc(5 * sizeof(short));
    16   f->textbuff[0]=0;
    17   f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    18   f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    19   f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
     10  f->textlen = 0;
     11  f->bufflen = 5;
     12  f->textbuff = owl_malloc(5);
     13  f->textbuff[0] = 0;
     14  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     15  f->default_fgcolor = OWL_COLOR_DEFAULT;
     16  f->default_bgcolor = OWL_COLOR_DEFAULT;
    2017}
    2118
     
    2421void owl_fmtext_clear(owl_fmtext *f)
    2522{
    26     f->textlen = 0;
    27     f->textbuff[0] = 0;
    28     f->fmbuff[0]=OWL_FMTEXT_ATTR_NONE;
    29     f->fgcolorbuff[0]=OWL_COLOR_DEFAULT;
    30     f->bgcolorbuff[0]=OWL_COLOR_DEFAULT;
    31 }
    32 
    33 /* Internal function.  Set the attribute 'attr' from index 'first' to
    34  * index 'last'
    35  */
    36 void _owl_fmtext_set_attr(owl_fmtext *f, int attr, int first, int last)
    37 {
    38   int i;
    39   for (i=first; i<=last; i++) {
    40     f->fmbuff[i]=(unsigned char) attr;
    41   }
    42 }
    43 
    44 /* Internal function.  Add the attribute 'attr' to the existing
    45  * attributes from index 'first' to index 'last'
    46  */
    47 void _owl_fmtext_add_attr(owl_fmtext *f, int attr, int first, int last)
    48 {
    49   int i;
    50   for (i=first; i<=last; i++) {
    51     f->fmbuff[i]|=(unsigned char) attr;
    52   }
    53 }
    54 
    55 /* Internal function.  Set the color to be 'color' from index 'first'
    56  * to index 'last
    57  */
    58 void _owl_fmtext_set_fgcolor(owl_fmtext *f, int color, int first, int last)
    59 {
    60   int i;
    61   for (i=first; i<=last; i++) {
    62     f->fgcolorbuff[i]=(short)color;
    63   }
    64 }
    65 
    66 void _owl_fmtext_set_bgcolor(owl_fmtext *f, int color, int first, int last)
    67 {
    68   int i;
    69   for (i=first; i<=last; i++) {
    70     f->bgcolorbuff[i]=(short)color;
    71   }
     23  f->textlen = 0;
     24  f->textbuff[0] = 0;
     25  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
     26  f->default_fgcolor = OWL_COLOR_DEFAULT;
     27  f->default_bgcolor = OWL_COLOR_DEFAULT;
    7228}
    7329
     
    7531{
    7632    if(newlen + 1 > f->bufflen) {
    77       f->textbuff=owl_realloc(f->textbuff, newlen+1);
    78       f->fmbuff=owl_realloc(f->fmbuff, newlen+1);
    79       f->fgcolorbuff=owl_realloc(f->fgcolorbuff, (newlen+1) * sizeof(short));
    80       f->bgcolorbuff=owl_realloc(f->bgcolorbuff, (newlen+1) * sizeof(short));
     33      f->textbuff = owl_realloc(f->textbuff, newlen + 1);
    8134      f->bufflen = newlen+1;
    8235  }
    8336}
    8437
     38int owl_fmtext_is_format_char(gunichar c)
     39{
     40  if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
     41  if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
     42  return 0;
     43}
    8544/* append text to the end of 'f' with attribute 'attr' and color
    8645 * 'color'
    8746 */
    88 void owl_fmtext_append_attr(owl_fmtext *f, char *text, int attr, int fgcolor, int bgcolor)
    89 {
    90   int newlen;
    91   newlen=strlen(f->textbuff)+strlen(text);
     47void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
     48{
     49  char attrbuff[6];
     50  int newlen, a = 0, fg = 0, bg = 0;
     51 
     52  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     53  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     54  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     55
     56  /* Plane-16 characters in UTF-8 are 4 bytes long. */
     57  newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
    9258  _owl_fmtext_realloc(f, newlen);
     59
     60  /* Set attributes */
     61  if (a) {
     62    memset(attrbuff,0,6);
     63    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     64    strcat(f->textbuff, attrbuff);     
     65  }
     66  if (fg) {
     67    memset(attrbuff,0,6);
     68    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     69    strcat(f->textbuff, attrbuff);     
     70  }
     71  if (bg) {
     72    memset(attrbuff,0,6);
     73    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     74    strcat(f->textbuff, attrbuff);     
     75  }
    9376 
    9477  strcat(f->textbuff, text);
    95   _owl_fmtext_set_attr(f, attr, f->textlen, newlen);
    96   _owl_fmtext_set_fgcolor(f, fgcolor, f->textlen, newlen);
    97   _owl_fmtext_set_bgcolor(f, bgcolor, f->textlen, newlen);
     78
     79  /* Reset attributes */
     80  if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     81  if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     82  if (a)  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
    9883  f->textlen=newlen;
    9984}
     
    129114}
    130115
    131 /* Add the attribute 'attr' to all text in 'f' */
    132 void owl_fmtext_addattr(owl_fmtext *f, int attr)
     116/* Add the attribute 'attr' to the default atts for the text in 'f' */
     117void owl_fmtext_addattr(owl_fmtext *f, char attr)
    133118{
    134119  /* add the attribute to all text */
    135   int i, j;
    136 
    137   j=f->textlen;
    138   for (i=0; i<j; i++) {
    139     f->fmbuff[i] |= attr;
    140   }
    141 }
    142 
    143 /* Anywhere the color is NOT ALREDY SET, set the color to 'color'.
    144  * Other colors are left unchanged
     120  f->default_attrs |= attr;
     121}
     122
     123/* Set the default foreground color for this fmtext to 'color'.
     124 * Only affects text that is colored default.
    145125 */
    146126void owl_fmtext_colorize(owl_fmtext *f, int color)
    147127{
    148   /* everywhere the fgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    149   int i, j;
    150 
    151   j=f->textlen;
    152   for(i=0; i<j; i++) {
    153     if (f->fgcolorbuff[i]==OWL_COLOR_DEFAULT) f->fgcolorbuff[i] = (short)color;
    154   }
    155 }
    156 
     128  f->default_fgcolor = color;
     129}
     130
     131/* Set the default foreground color for this fmtext to 'color'.
     132 * Only affects text that is colored default.
     133 */
    157134void owl_fmtext_colorizebg(owl_fmtext *f, int color)
    158135{
    159   /* everywhere the bgcolor is OWL_COLOR_DEFAULT, change it to be 'color' */
    160   int i, j;
    161 
    162   j=f->textlen;
    163   for(i=0; i<j; i++) {
    164     if (f->bgcolorbuff[i]==OWL_COLOR_DEFAULT) f->bgcolorbuff[i] = (short)color;
    165   }
    166 }
     136  f->default_bgcolor = color;
     137}
     138
     139/* Internal function. Parse attrbute character. */
     140void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     141{
     142  if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
     143    *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
     144  }
     145  else if ((c & OWL_FMTEXT_UC_COLOR_BASE) == OWL_FMTEXT_UC_COLOR_BASE) {
     146    if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
     147      *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
     148                  ? OWL_COLOR_DEFAULT
     149                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     150    }
     151    else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
     152      *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
     153                  ? OWL_COLOR_DEFAULT
     154                  : c & OWL_FMTEXT_UC_COLOR_MASK);
     155    }
     156  }
     157}
     158
     159/* Internal function. Scan for attribute characters. */
     160void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
     161{
     162  char *p;
     163  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     164  while (p && p < f->textbuff + start) {
     165    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
     166    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     167  }
     168
    167169
    168170/* Internal function.  Append text from 'in' between index 'start' and
    169171 * 'stop' to the end of 'f'
    170172 */
    171 void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop)
    172 {
    173   int newlen, i;
    174 
    175   newlen=strlen(f->textbuff)+(stop-start+1);
     173void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
     174{
     175  char attrbuff[6];
     176  int newlen, a = 0, fg = 0, bg = 0;
     177  char attr = 0;
     178  short fgcolor = OWL_COLOR_DEFAULT;
     179  short bgcolor = OWL_COLOR_DEFAULT;
     180
     181  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
     182  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
     183  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
     184  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
     185
     186  /* We will reset to defaults after appending the text. We may need
     187     to set initial attributes. */
     188  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
    176189  _owl_fmtext_realloc(f, newlen);
    177190
     191  if (a) {
     192    memset(attrbuff,0,6);
     193    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
     194    strcat(f->textbuff, attrbuff);     
     195  }
     196  if (fg) {
     197    memset(attrbuff,0,6);
     198    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
     199    strcat(f->textbuff, attrbuff);     
     200  }
     201  if (bg) {
     202    memset(attrbuff,0,6);
     203    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
     204    strcat(f->textbuff, attrbuff);     
     205  }
     206
    178207  strncat(f->textbuff, in->textbuff+start, stop-start+1);
     208
     209  /* Reset attributes */
     210  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
     211  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
     212  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
     213
    179214  f->textbuff[newlen]='\0';
    180   for (i=start; i<=stop; i++) {
    181     f->fmbuff[f->textlen+(i-start)]=in->fmbuff[i];
    182     f->fgcolorbuff[f->textlen+(i-start)]=in->fgcolorbuff[i];
    183     f->bgcolorbuff[f->textlen+(i-start)]=in->bgcolorbuff[i];
    184   }
    185215  f->textlen=newlen;
    186216}
     
    207237char *owl_fmtext_print_plain(owl_fmtext *f)
    208238{
    209   return(owl_strdup(f->textbuff));
     239  return owl_strip_format_chars(f->textbuff);
     240}
     241
     242void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
     243{
     244  wattrset(w, A_NORMAL);
     245  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
     246  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
     247  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
     248}
     249
     250void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
     251{
     252  if (owl_global_get_hascolors(&g)) {
     253    *pair = owl_fmtext_get_colorpair(fg, bg);
     254  }
     255}
     256
     257void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
     258{
     259  if (owl_global_get_hascolors(&g)) {
     260      wcolor_set(w,pair,NULL);
     261  }
    210262}
    211263
     
    213265 * must already be initiatlized with curses
    214266 */
    215 void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
    216 {
    217   char *tmpbuff;
    218   int position, trans1, trans2, trans3, len, lastsame;
    219 
     267void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
     268{
     269  /* char *tmpbuff; */
     270  /* int position, trans1, trans2, trans3, len, lastsame; */
     271  char *s, *p;
     272  char attr;
     273  short fg, bg, pair;
     274  int search_results, search_len;
     275 
    220276  if (w==NULL) {
    221277    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
     
    223279  }
    224280
    225   tmpbuff=owl_malloc(f->textlen+10);
    226 
    227   position=0;
    228   len=f->textlen;
    229   while (position<=len) {
    230     /* find the last char with the current format and color */
    231     trans1=owl_util_find_trans(f->fmbuff+position, len-position);
    232     trans2=owl_util_find_trans_short(f->fgcolorbuff+position, len-position);
    233     trans3=owl_util_find_trans_short(f->bgcolorbuff+position, len-position);
    234 
    235     lastsame = (trans1 < trans2) ? trans1 : trans2;
    236     lastsame = (lastsame < trans3) ? lastsame : trans3;
    237     lastsame += position;
    238 
    239     /* set the format */
    240     wattrset(w, A_NORMAL);
    241     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_BOLD) {
    242       wattron(w, A_BOLD);
    243     }
    244     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_REVERSE) {
    245       wattron(w, A_REVERSE);
    246     }
    247     if (f->fmbuff[position] & OWL_FMTEXT_ATTR_UNDERLINE) {
    248       wattron(w, A_UNDERLINE);
    249     }
    250 
    251     /* set the color */
    252     /* warning, this is sort of a hack */
    253     if (owl_global_get_hascolors(&g)) {
    254       short fg, bg, pair;
    255       fg = f->fgcolorbuff[position];
    256       bg = f->bgcolorbuff[position];
    257 
    258       pair = owl_fmtext_get_colorpair(fg, bg);
    259       if (pair != -1) {
    260         wcolor_set(w,pair,NULL);
    261       }
    262     }
    263 
    264     /* add the text */
    265     strncpy(tmpbuff, f->textbuff + position, lastsame-position+1);
    266     tmpbuff[lastsame-position+1]='\0';
    267     waddstr(w, tmpbuff);
    268 
    269     position=lastsame+1;
    270   }
    271   owl_free(tmpbuff);
    272 }
    273 
     281  search_results = (do_search
     282                    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
     283                    : 0);
     284  search_len = (search_results
     285                ? strlen(owl_global_get_search_string(&g))
     286                : 0);
     287  s = f->textbuff;
     288  /* Set default attributes. */
     289  attr = f->default_attrs;
     290  fg = f->default_fgcolor;
     291  bg = f->default_bgcolor;
     292  _owl_fmtext_wattrset(w, attr);
     293  _owl_fmtext_update_colorpair(fg, bg, &pair);
     294  _owl_fmtext_wcolor_set(w, pair);
     295
     296  /* Find next possible format character. */
     297  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     298  while(p) {
     299    if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     300      /* Deal with all text from last insert to here. */
     301      char tmp;
     302   
     303      tmp = p[0];
     304      p[0] = '\0';
     305      if (search_results) {
     306        /* Search is active, so highlight search results. */
     307        char tmp2, *ss;
     308        ss = stristr(s, owl_global_get_search_string(&g));
     309        while (ss) {
     310          /* Found search string, highlight it. */
     311
     312          tmp2 = ss[0];
     313          ss[0] = '\0';
     314          waddstr(w, s);
     315          ss[0] = tmp2;
     316
     317          _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
     318          _owl_fmtext_wcolor_set(w, pair);
     319         
     320          tmp2 = ss[search_len];
     321          ss[search_len] = '\0';
     322          waddstr(w, ss);
     323          ss[search_len] = tmp2;
     324
     325          _owl_fmtext_wattrset(w, attr);
     326          _owl_fmtext_wcolor_set(w, pair);
     327
     328          s = ss + search_len;
     329          ss = stristr(s, owl_global_get_search_string(&g));
     330        }
     331      }
     332      /* Deal with remaining part of string. */
     333      waddstr(w, s);
     334      p[0] = tmp;
     335
     336      /* Deal with new attributes. Initialize to defaults, then
     337         process all consecutive formatting characters. */
     338      attr = f->default_attrs;
     339      fg = f->default_fgcolor;
     340      bg = f->default_bgcolor;
     341      while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     342        _owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
     343        p = g_utf8_next_char(p);
     344      }
     345      _owl_fmtext_wattrset(w, attr | f->default_attrs);
     346      if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
     347      if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
     348      _owl_fmtext_update_colorpair(fg, bg, &pair);
     349      _owl_fmtext_wcolor_set(w, pair);
     350
     351      /* Advance to next non-formatting character. */
     352      s = p;
     353      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     354    }
     355    else {
     356      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     357    }
     358  }
     359  if (s) {
     360    waddstr(w, s);
     361  }
     362}
     363
     364void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
     365{
     366  _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
     367}
     368
     369void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
     370{
     371  _owl_fmtext_curs_waddstr(f, w, 0);
     372}
    274373
    275374/* start with line 'aline' (where the first line is 0) and print
     
    282381 
    283382  /* find the starting line */
    284   ptr1=in->textbuff;
    285   if (aline!=0) {
    286     for (i=0; i<aline; i++) {
    287       ptr1=strchr(ptr1, '\n');
    288       if (!ptr1) return(-1);
    289       ptr1++;
    290     }
    291   }
     383  ptr1 = in->textbuff;
     384  for (i = 0; i < aline; i++) {
     385    ptr1 = strchr(ptr1, '\n');
     386    if (!ptr1) return(-1);
     387    ptr1++;
     388  }
     389 
    292390  /* ptr1 now holds the starting point */
    293391
     392  /* copy the default attributes */
     393  out->default_attrs = in->default_attrs;
     394  out->default_fgcolor = in->default_fgcolor;
     395  out->default_bgcolor = in->default_bgcolor;
     396   
    294397  /* copy in the next 'lines' lines */
    295   if (lines<1) return(-1);
    296 
    297   for (i=0; i<lines; i++) {
    298     offset=ptr1-in->textbuff;
    299     ptr2=strchr(ptr1, '\n');
     398  if (lines < 1) return(-1);
     399
     400  for (i = 0; i < lines; i++) {
     401    offset = ptr1 - in->textbuff;
     402    ptr2 = strchr(ptr1, '\n');
    300403    if (!ptr2) {
    301       _owl_fmtext_append_fmtext(out, in, offset, (in->textlen)-1);
     404      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
    302405      return(-1);
    303406    }
    304     _owl_fmtext_append_fmtext(out, in, offset, (ptr2-ptr1)+offset);
    305     ptr1=ptr2+1;
     407    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
     408    ptr1 = ptr2 + 1;
    306409  }
    307410  return(0);
     
    311414 * ends at 'bcol' or sooner.  The first column is number 0.  The new
    312415 * message is placed in 'out'.  The message is * expected to end in a
    313  * new line for now
     416 * new line for now. NOTE: This needs to be modified to deal with
     417 * backing up if we find a SPACING COMBINING MARK at the end of a
     418 * line. If that happens, we should back up to the last non-mark
     419 * character and stop there.
    314420 */
    315421void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
    316422{
    317   char *ptr1, *ptr2, *last;
    318   int len, offset;
     423  char *ptr_s, *ptr_e, *ptr_c, *last;
     424  int col, st, padding, chwidth;
     425
     426  /* copy the default attributes */
     427  out->default_attrs = in->default_attrs;
     428  out->default_fgcolor = in->default_fgcolor;
     429  out->default_bgcolor = in->default_bgcolor;
    319430
    320431  last=in->textbuff+in->textlen-1;
    321   ptr1=in->textbuff;
    322   while (ptr1<=last) {
    323     ptr2=strchr(ptr1, '\n');
    324     if (!ptr2) {
     432  ptr_s=in->textbuff;
     433  while (ptr_s <= last) {
     434    ptr_e=strchr(ptr_s, '\n');
     435    if (!ptr_e) {
    325436      /* but this shouldn't happen if we end in a \n */
    326437      break;
    327438    }
    328439   
    329     if (ptr2==ptr1) {
     440    if (ptr_e == ptr_s) {
    330441      owl_fmtext_append_normal(out, "\n");
    331       ptr1++;
     442      ++ptr_s;
    332443      continue;
    333444    }
    334445
    335     /* we need to check that we won't run over here */
    336     len=bcol-acol;
    337     if (len > (ptr2-(ptr1+acol))) {
    338       /* the whole line fits with room to spare, don't take a full 'len' */
    339       len=ptr2-(ptr1+acol);
    340     }
    341     if (len>last-ptr1) {
    342       /* the whole rest of the text fits with room to spare, adjust for it */
    343       len-=(last-ptr1);
    344     }
    345     if (len<=0) {
    346       /* saftey check */
     446    col = 0;
     447    st = 0;
     448    padding = 0;
     449    chwidth = 0;
     450    ptr_c = ptr_s;
     451    while(ptr_c < ptr_e) {
     452      gunichar c = g_utf8_get_char(ptr_c);
     453      if (!owl_fmtext_is_format_char(c)) {
     454        chwidth = mk_wcwidth(c);
     455        if (col + chwidth > bcol) break;
     456       
     457        if (col >= acol) {
     458          if (st == 0) {
     459            ptr_s = ptr_c;
     460            padding = col - acol;
     461            ++st;
     462          }
     463        }
     464        col += chwidth;
     465        chwidth = 0;
     466      }
     467      ptr_c = g_utf8_next_char(ptr_c);
     468    }
     469    if (st) {
     470      /* lead padding */
     471      owl_fmtext_append_spaces(out, padding);
     472      if (ptr_c == ptr_e) {
     473        /* We made it to the newline. */
     474        _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     475      }
     476      else {
     477        if (chwidth > 1) {
     478          /* Last char is wide, truncate. */
     479          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
     480          owl_fmtext_append_normal(out, "\n");
     481        }
     482        else {
     483          /* Last char fits perfectly, leave alone.*/
     484          _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
     485        }
     486      }
     487    }
     488    else {
    347489      owl_fmtext_append_normal(out, "\n");
    348       ptr1=ptr2+1;
    349       continue;
    350     }
    351 
    352     offset=ptr1-in->textbuff;
    353     _owl_fmtext_append_fmtext(out, in, offset+acol, offset+acol+len);
    354 
    355     ptr1=ptr2+1;
     490    }
     491    ptr_s = g_utf8_next_char(ptr_e);
    356492  }
    357493}
     
    381517
    382518/* set the charater at 'index' to be 'char'.  If index is out of
    383  * bounds don't do anything */
    384 void owl_fmtext_set_char(owl_fmtext *f, int index, int ch)
     519 * bounds don't do anything. If c or char at index is not ASCII, don't
     520 * do anything because it's not UTF-8 safe. */
     521void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
    385522{
    386523  if ((index < 0) || (index > f->textlen-1)) return;
     524  /* NOT ASCII*/
     525  if (f->textbuff[index] & 0x80 || ch & 0x80) return;
    387526  f->textbuff[index]=ch;
    388527}
     
    401540  dst->bufflen=mallocsize;
    402541  dst->textbuff=owl_malloc(mallocsize);
    403   dst->fmbuff=owl_malloc(mallocsize);
    404   dst->fgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    405   dst->bgcolorbuff=owl_malloc(mallocsize * sizeof(short));
    406542  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
    407   memcpy(dst->fmbuff, src->fmbuff, src->textlen);
    408   memcpy(dst->fgcolorbuff, src->fgcolorbuff, src->textlen * sizeof(short));
    409   memcpy(dst->bgcolorbuff, src->bgcolorbuff, src->textlen * sizeof(short));
    410 }
    411 
    412 /* highlight all instances of "string".  Return the number of
    413  * instances found.  This is a case insensitive search.
    414  */
    415 int owl_fmtext_search_and_highlight(owl_fmtext *f, char *string)
    416 {
    417 
    418   int found, len;
    419   char *ptr1, *ptr2;
    420 
    421   len=strlen(string);
    422   found=0;
    423   ptr1=f->textbuff;
    424   while (ptr1-f->textbuff <= f->textlen) {
    425     ptr2=stristr(ptr1, string);
    426     if (!ptr2) return(found);
    427 
    428     found++;
    429     _owl_fmtext_add_attr(f, OWL_FMTEXT_ATTR_REVERSE,
    430                          ptr2 - f->textbuff,
    431                          ptr2 - f->textbuff + len - 1);
    432 
    433     ptr1=ptr2+len;
    434   }
    435   return(found);
     543  dst->default_attrs = src->default_attrs;
     544  dst->default_fgcolor = src->default_fgcolor;
     545  dst->default_bgcolor = src->default_bgcolor;
    436546}
    437547
     
    441551int owl_fmtext_search(owl_fmtext *f, char *string)
    442552{
    443 
    444553  if (stristr(f->textbuff, string)) return(1);
    445554  return(0);
     
    682791{
    683792  if (f->textbuff) owl_free(f->textbuff);
    684   if (f->fmbuff) owl_free(f->fmbuff);
    685   if (f->fgcolorbuff) owl_free(f->fgcolorbuff);
    686   if (f->bgcolorbuff) owl_free(f->bgcolorbuff);
    687793}
    688794
  • functions.c

    rcdd3959 rdb0ac7e  
    16061606          sprintf(buff, "  Field %i   : ", i+1);
    16071607         
    1608           ptr=owl_zephyr_get_field(n, i+1);
     1608          ptr=owl_zephyr_get_field_as_utf8(n, i+1);
    16091609          len=strlen(ptr);
    16101610          if (len<30) {
     
    21872187void owl_function_start_command(char *line)
    21882188{
    2189   int i, j;
    21902189  owl_editwin *tw;
    21912190
     
    21982197  owl_global_set_needrefresh(&g);
    21992198
    2200   j=strlen(line);
    2201   for (i=0; i<j; i++) {
    2202     owl_editwin_process_char(tw, line[i]);
    2203   }
     2199  owl_editwin_insert_string(tw, line);
    22042200  owl_editwin_redisplay(tw, 0);
    22052201
     
    25992595  }
    26002596  /* downcase it */
    2601   downstr(filtname);
     2597  {
     2598    char *temp = g_utf8_strdown(filtname, -1);
     2599    if (temp) {
     2600      owl_free(filtname);
     2601      filtname = temp;
     2602    }
     2603  }
    26022604  /* turn spaces, single quotes, and double quotes into dots */
    26032605  owl_text_tr(filtname, ' ', '.');
     
    30243026  char *quoted;
    30253027
    3026   buff=malloc(strlen(class)+strlen(inst)+strlen(recip)+100);
     3028  buff=owl_malloc(strlen(class)+strlen(inst)+strlen(recip)+100);
    30273029  strcpy(buff, "class");
    30283030  if (!strcmp(class, "*")) {
     
    33283330          if (ret==0) {
    33293331            for (x=0; x<numlocs; x++) {
    3330               line=malloc(strlen(location[x].host)+strlen(location[x].time)+strlen(location[x].tty)+100);
     3332              line=owl_malloc(strlen(location[x].host)+strlen(location[x].time)+strlen(location[x].tty)+100);
    33313333              tmp=short_zuser(user);
    33323334              sprintf(line, "  %-10.10s %-24.24s %-12.12s  %20.20s\n",
     
    33713373  owl_view *v;
    33723374  FILE *file;
     3375  char *plaintext;
    33733376
    33743377  v=owl_global_get_current_view(&g);
     
    33933396  for (i=0; i<j; i++) {
    33943397    m=owl_view_get_element(v, i);
    3395     fputs(owl_message_get_text(m), file);
     3398    plaintext = owl_strip_format_chars(owl_message_get_text(m));
     3399    if (plaintext) {
     3400      fputs(plaintext, file);
     3401      owl_free(plaintext);
     3402    }
    33963403  }
    33973404  fclose(file);
     
    34343441          _exit(127);
    34353442        }
    3436         parsed=realloc(parsed, sizeof(*parsed) * (myargc+1));
     3443        parsed=owl_realloc(parsed, sizeof(*parsed) * (myargc+1));
    34373444        parsed[myargc] = NULL;
    34383445       
  • global.c

    r8aa83ea3 rdb0ac7e  
    557557    len+=strlen(argv[i])+5;
    558558  }
    559   g->startupargs=malloc(len+5);
     559  g->startupargs=owl_malloc(len+5);
    560560
    561561  strcpy(g->startupargs, "");
  • keymap.c

    rcf83b7a r428834d  
    55
    66/* returns 0 on success */
    7 int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(int), void (*prealways_fn)(int), void (*postalways_fn)(int))
     7int 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))
    88{
    99  if (!name || !desc) return(-1);
     
    151151}
    152152
    153 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))
     153owl_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))
    154154{
    155155  owl_keymap *km;
     
    202202/* processes a keypress.  returns 0 if the keypress was handled,
    203203 * 1 if not handled, -1 on error, and -2 if j==ERR. */
    204 int owl_keyhandler_process(owl_keyhandler *kh, int j)
     204int owl_keyhandler_process(owl_keyhandler *kh, owl_input j)
    205205{
    206206  owl_keymap     *km;
     
    214214
    215215  /* temporarily disallow C-`/C-SPACE until we fix associated bugs */
    216   if (j==ERR || j==0) {
     216  if (j.ch == ERR || j.ch == 0) {
    217217        return(-1);
    218218  }
     
    224224
    225225  /* deal with ESC prefixing */
    226   if (!kh->in_esc && j==27) {
     226  if (!kh->in_esc && j.ch == 27) {
    227227    kh->in_esc = 1;
    228228    return(0);
    229229  }
    230230  if (kh->in_esc) {
    231     j = OWL_META(j);
     231    j.ch = OWL_META(j.ch);
    232232    kh->in_esc = 0;
    233233  }
    234234 
    235   kh->kpstack[++(kh->kpstackpos)] = j;
     235  kh->kpstack[++(kh->kpstackpos)] = j.ch;
    236236  if (kh->kpstackpos >= OWL_KEYMAP_MAXSTACK) {
    237237    owl_keyhandler_reset(kh);
     
    260260      } else if (match == 2) {  /* exact match */
    261261        /* owl_function_debugmsg("processkey: found exact match in %s", km->name); */
    262         owl_keybinding_execute(kb, j);
     262        owl_keybinding_execute(kb, j.ch);
    263263        owl_keyhandler_reset(kh);
    264264        if (km->postalways_fn) {
  • keypress.c

    r948b942 r428834d  
    148148  }
    149149  if (!*kb) {
    150     if (j&OWL_META(0)) {
     150    if (j & OWL_META(0)) {
    151151      strcat(kb, "M-");
    152152      j &= ~OWL_META(0);
     
    163163      strcat(kb, kb2);   
    164164    }
     165   
    165166  } 
    166167  if (!*kb) {
  • keys.c

    r3004c9f rdb0ac7e  
    302302/****************************************************************/
    303303
    304 void owl_keys_recwin_prealways(int j) {
     304void owl_keys_recwin_prealways(owl_input j) {
    305305  /* Clear the message line on subsequent key presses */
    306306  owl_function_makemsg("");
    307307}
    308308
    309 void owl_keys_editwin_default(int j) {
     309void owl_keys_editwin_default(owl_input j) {
    310310  owl_editwin *e;
    311311  if (NULL != (e=owl_global_get_typwin(&g))) {
    312     owl_editwin_process_char(e, j);
     312       owl_editwin_process_char(e, j);
    313313  }
    314314}
    315315
    316 void owl_keys_editwin_postalways(int j) {
     316void owl_keys_editwin_postalways(owl_input j) {
    317317  owl_editwin *e;
    318318  if (NULL != (e=owl_global_get_typwin(&g))) {
    319319    owl_editwin_post_process_char(e, j);
    320   } 
     320  }
    321321  owl_global_set_needrefresh(&g);
    322322}
    323323
    324 void owl_keys_popless_postalways(int j) {
     324void owl_keys_popless_postalways(owl_input j) {
    325325  owl_viewwin *v = owl_global_get_viewwin(&g);
    326326  owl_popwin *pw = owl_global_get_popwin(&g);
     
    331331}
    332332
    333 void owl_keys_default_invalid(int j) {
    334   if (j==ERR) return;
    335   if (j==410) return;
     333void owl_keys_default_invalid(owl_input j) {
     334  if (j.ch==ERR) return;
     335  if (j.ch==410) return;
    336336  owl_keyhandler_invalidkey(owl_global_get_keyhandler(&g));
    337337}
  • logging.c

    raf1920fd ree310eb  
    155155    to = owl_sprintf("jabber:%s", owl_message_get_recipient(m));
    156156  } else if (owl_message_is_type_aim(m)) {
     157    char *temp2;
    157158    temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
    158     downstr(temp);
    159     to = owl_sprintf("aim:%s", temp);
     159    temp2 = g_utf8_strdown(temp,-1);
     160    to = owl_sprintf("aim:%s", temp2);
     161    owl_free(temp2);
    160162    owl_free(temp);
    161163  } else {
     
    267269  } else if (owl_message_is_type_aim(m)) {
    268270    /* we do not yet handle chat rooms */
    269     char *normalto;
    270     normalto=owl_aim_normalize_screenname(owl_message_get_sender(m));
    271     downstr(normalto);
     271    char *normalto, *temp;
     272    temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
     273    normalto = g_utf8_strdown(temp, -1);
    272274    from=frombuff=owl_sprintf("aim:%s", normalto);
    273275    owl_free(normalto);
     276    owl_free(temp);
    274277  } else if (owl_message_is_type_loopback(m)) {
    275278    from=frombuff=owl_strdup("loopback");
     
    290293
    291294  ch=frombuff[0];
    292   if (!isalnum(ch)) from="weird";
     295  if (!g_ascii_isalnum(ch)) from="weird";
    293296
    294297  for (i=0; i<len; i++) {
     
    299302
    300303  if (!personal) {
    301     if (strcmp(from, "weird")) downstr(from);
     304    if (strcmp(from, "weird")) {
     305      char* temp = g_utf8_strdown(frombuff, -1);
     306      if (temp) {
     307        owl_free(frombuff);
     308        from = frombuff = temp;
     309      }
     310    }
    302311  }
    303312
  • message.c

    r18108b1e r07bfbc2  
    7979    owl_list_append_element(&(m->attributes), pair);
    8080  }
    81   owl_pair_set_value(pair, owl_strdup(attrvalue));
     81  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
    8282}
    8383
     
    493493{
    494494  if(m->zwriteline) owl_free(m->zwriteline);
    495   m->zwriteline=strdup(line);
     495  m->zwriteline=owl_strdup(line);
    496496}
    497497
     
    535535  owl_fmtext_init_null(&b);
    536536 
    537   owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline+1, &a);
     537  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline, &a);
    538538  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
    539   if (fgcolor!=OWL_COLOR_DEFAULT) {
    540     owl_fmtext_colorize(&b, fgcolor);
    541   }
    542   if (bgcolor!=OWL_COLOR_DEFAULT) {
    543     owl_fmtext_colorizebg(&b, bgcolor);
    544   }
    545 
    546   if (owl_global_is_search_active(&g)) {
    547     owl_fmtext_search_and_highlight(&b, owl_global_get_search_string(&g));
    548   }
    549      
     539  owl_fmtext_colorize(&b, fgcolor);
     540  owl_fmtext_colorizebg(&b, bgcolor);
     541
    550542  owl_fmtext_curs_waddstr(&b, win);
    551543
     
    892884  }
    893885
    894   m->zwriteline=strdup("");
     886  m->zwriteline=owl_strdup("");
    895887
    896888  /* save the hostname */
     
    974966  }
    975967
    976   m->zwriteline=strdup("");
     968  m->zwriteline=owl_strdup("");
    977969
    978970  owl_message_set_body(m, "<uninitialized>");
  • owl.c

    r52f8dd6 rdb0ac7e  
    4949#include <termios.h>
    5050#include <sys/stat.h>
     51#include <locale.h>
    5152#include "owl.h"
    5253
     
    6061int stderr_replace(void);
    6162#endif
     63
     64#define STDIN 0
    6265
    6366static const char fileIdent[] = "$Id$";
     
    8588  int newstderr;
    8689#endif
     90 
     91  if (!GLIB_CHECK_VERSION (2, 12, 0))
     92    g_error ("GLib version 2.12.0 or above is needed.");
    8793
    8894  argcsave=argc;
     
    9399  debug=0;
    94100  initialsubs=1;
     101
     102  setlocale(LC_ALL, "");
     103 
    95104  if (argc>0) {
    96105    argv++;
     
    210219  {
    211220    owl_dispatch *d = owl_malloc(sizeof(owl_dispatch));
    212     d->fd = fileno(stdin);
     221    d->fd = STDIN;
    213222    d->cfunc = &owl_process_input;
    214223    d->pfunc = NULL;
     
    520529        owl_function_set_cursor(sepwin);
    521530      }
    522       owl_function_debugmsg("owl.c -- doupdate()");
    523531      doupdate();
    524532      owl_global_set_noneedrefresh(&g);
    525533    }
    526 
    527     /* Handle all keypresses.  If no key has been pressed, sleep for a
    528      * little bit, but otherwise do not.  This lets input be grabbed
    529      * as quickly as possbile */
    530534
    531535    /* select on FDs we know about. */
     
    664668void owl_process_input()
    665669{
    666   int ret, j;
     670  int ret;
     671  owl_input j;
    667672  owl_popwin *pw;
    668673  owl_editwin *tw;
    669 
     674  WINDOW *typwin;
     675
     676  typwin = owl_global_get_curs_typwin(&g);
    670677  while (1) {
    671     j = wgetch(owl_global_get_curs_typwin(&g));
    672     if (j == ERR) return;
    673 
     678    j.ch = wgetch(typwin);
     679    if (j.ch == ERR) return;
     680   
    674681    owl_global_set_lastinputtime(&g, time(NULL));
    675682    pw=owl_global_get_popwin(&g);
    676683    tw=owl_global_get_typwin(&g);
     684
     685    j.uch = '\0';
     686    if (j.ch >= KEY_MIN && j.ch <= KEY_MAX) {
     687      /* This is a curses control character. */
     688    }
     689    else if (j.ch > 0x7f && j.ch < 0xfe) {
     690      /* Pull in a full utf-8 character. */
     691      int bytes, i;
     692      char utf8buf[7];
     693      memset(utf8buf, '\0', 7);
     694     
     695      utf8buf[0] = j.ch;
     696     
     697      if ((j.ch & 0xc0) && (~j.ch & 0x20)) bytes = 2;
     698      else if ((j.ch & 0xe0) && (~j.ch & 0x10)) bytes = 3;
     699      else if ((j.ch & 0xf0) && (~j.ch & 0x08)) bytes = 4;
     700      else if ((j.ch & 0xf8) && (~j.ch & 0x04)) bytes = 5;
     701      else if ((j.ch & 0xfc) && (~j.ch & 0x02)) bytes = 6;
     702      else bytes = 1;
     703     
     704      for (i = 1; i < bytes; i++) {
     705        int tmp =  wgetch(typwin);
     706        /* If what we got was not a byte, or not a continuation byte */
     707        if (tmp > 0xff || !(tmp & 0x80 && ~tmp & 0x40)) {
     708          /* ill-formed UTF-8 code unit subsequence, put back the
     709             char we just got. */
     710          ungetch(tmp);
     711          j.ch = ERR;
     712          break;
     713        }
     714        utf8buf[i] = tmp;
     715      }
     716     
     717      if (j.ch != ERR) {
     718        if (g_utf8_validate(utf8buf, -1, NULL)) {
     719          j.uch = g_utf8_get_char(utf8buf);
     720        }
     721        else {
     722          j.ch = ERR;
     723        }
     724      }
     725    }
     726    else if (j.ch <= 0x7f) {
     727      j.uch = j.ch;
     728    }
    677729   
     730    owl_global_set_lastinputtime(&g, time(NULL));
    678731    /* find and activate the current keymap.
    679732     * TODO: this should really get fixed by activating
     
    685738      owl_function_activate_keymap("popless");
    686739    } else if (owl_global_is_typwin_active(&g)
    687                && owl_editwin_get_style(tw) == OWL_EDITWIN_STYLE_ONELINE) {
     740               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_ONELINE) {
    688741      /*
    689742        owl_context_set_editline(owl_global_get_context(&g), tw);
     
    691744      */
    692745    } else if (owl_global_is_typwin_active(&g)
    693                && owl_editwin_get_style(tw) == OWL_EDITWIN_STYLE_MULTILINE) {
     746               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_MULTILINE) {
    694747      owl_context_set_editmulti(owl_global_get_context(&g), tw);
    695748      owl_function_activate_keymap("editmulti");
     
    700753    /* now actually handle the keypress */
    701754    ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j);
    702     if (ret != 0 && ret != 1) {
     755    if (ret!=0 && ret!=1) {
    703756      owl_function_makemsg("Unable to handle keypress");
    704757    }
  • owl.h

    r120291c rdb0ac7e  
    5252#include <termios.h>
    5353#include <libfaim/aim.h>
     54#include <wchar.h>
    5455#include "config.h"
     56#include "glib.h"
    5557#ifdef HAVE_LIBZEPHYR
    5658#include <zephyr/zephyr.h>
     
    101103#define OWL_FMTEXT_ATTR_REVERSE   2
    102104#define OWL_FMTEXT_ATTR_UNDERLINE 4
     105
     106#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
     107#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
     108#define OWL_FMTEXT_UC_ATTR_MASK 0x7
     109#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
     110#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
     111#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
     112#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
     113#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
     114#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
     115#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
     116#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
     117#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
     118
     119#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
     120#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
     121#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x9C\x80"
    103122
    104123#define OWL_COLOR_BLACK     0
     
    210229#endif
    211230
    212 #define OWL_META(key) ((key)|0200)
     231#define OWL_META(key) ((key)|010000)
    213232/* OWL_CTRL is definied in kepress.c */
    214233
     
    250269} owl_variable;
    251270
     271typedef struct _owl_input {
     272  int ch;
     273  gunichar uch;
     274} owl_input;
     275
    252276typedef struct _owl_fmtext {
    253277  int textlen;
    254278  int bufflen;
    255279  char *textbuff;
    256   char *fmbuff;
    257   short *fgcolorbuff;
    258   short *bgcolorbuff;
     280  char default_attrs;
     281  short default_fgcolor;
     282  short default_bgcolor;
    259283} owl_fmtext;
    260284
     
    486510  owl_list  bindings;           /* key bindings */
    487511  struct _owl_keymap *submap;   /* submap */
    488   void (*default_fn)(int j);    /* default action (takes a keypress) */
    489   void (*prealways_fn)(int j);  /* always called before a keypress is received */
    490   void (*postalways_fn)(int j); /* always called after keypress is processed */
     512  void (*default_fn)(owl_input j);      /* default action (takes a keypress) */
     513  void (*prealways_fn)(owl_input j);   /* always called before a keypress is received */
     514  void (*postalways_fn)(owl_input j);  /* always called after keypress is processed */
    491515} owl_keymap;
    492516
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm

    rb72a352 rdb0ac7e  
    2626use Getopt::Long;
    2727Getopt::Long::Configure(qw(no_getopt_compat prefix_pattern=-|--));
     28
     29use utf8;
    2830
    2931our $VERSION = 0.1;
     
    378380                    $vars{jlogin_havepass} = 1;
    379381                    $conn->removeConnection($jidStr);
    380                     BarnOwl::start_password( "Password for $jidStr: ", \&do_login );
     382                    BarnOwl::start_password("Password for $jidStr: ", \&do_login );
    381383                    return "";
    382384                }
     
    487489    }
    488490    else {
    489         $to = shift @ARGV;
     491      $to = shift @ARGV;
    490492    }
    491493
     
    531533    $cmd .= " -t $jwrite_thread" if $jwrite_thread;
    532534    $cmd .= " -s $jwrite_subject" if $jwrite_subject;
    533     BarnOwl::start_edit_win( $cmd, \&process_owl_jwrite );
     535
     536    BarnOwl::start_edit_win($cmd, \&process_owl_jwrite );
    534537}
    535538
  • perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm

    r6b580b0 r5f3168a  
    11use warnings;
    22use strict;
     3use utf8;
    34
    45=head1 NAME
  • perl/modules/Jabber/lib/Net/XMPP/Debug.pm

    rc2bed55 rb7b2a76  
    189189                        {
    190190                            $self->{HANDLE}->autoflush(1);
     191                            binmode $self->{HANDLE}, ":utf8";
    191192                            $Net::XMPP::Debug::HANDLES{$args{file}} = $self->{HANDLE};
    192193                        }
  • perl/modules/Jabber/lib/Net/XMPP/Message.pm

    rc2bed55 r8574801  
    135135                            $Mess->SetMessage(TO=>"bob\@jabber.org",
    136136                                              Subject=>"Lunch",
    137                                               BoDy=>"Let's do lunch!");
     137                                              Body=>"Let's do lunch!");
    138138                            $Mess->SetMessage(to=>"bob\@jabber.org",
    139139                                              from=>"jabber.org",
  • perl/modules/Jabber/lib/XML/Stream.pm

    r5073972 ra8d5a39  
    16591659    {
    16601660        $self->debug(3,"Send: can_write");
    1661        
     1661
    16621662        $self->{SENDSTRING} = Encode::encode_utf8(join("",@_));
    16631663
  • perlconfig.c

    rb67ab6b rdb0ac7e  
    5555    j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
    5656    for (i=0; i<j; i++) {
    57       ptr=owl_zephyr_get_field(owl_message_get_notice(m), i+1);
     57      ptr=owl_zephyr_get_field_as_utf8(owl_message_get_notice(m), i+1);
    5858      av_push(av_zfields, newSVpvn(ptr, strlen(ptr)));
    5959      owl_free(ptr);
     
    434434  PUSHMARK(SP);
    435435  for(i=0;i<argc;i++) {
    436     XPUSHs(sv_2mortal(newSVpv(argv[i], 0)));
     436    SV *tmp = newSVpv(argv[i], 0);
     437    SvUTF8_on(tmp);
     438    XPUSHs(sv_2mortal(tmp));
    437439  }
    438440  PUTBACK;
     
    473475{
    474476  SV *cb = (SV*)(e->cbdata);
     477  SV *text;
    475478  unsigned int n_a;
    476479  dSP;
     
    479482    owl_function_error("Perl callback is NULL!");
    480483  }
     484  text = newSVpv(owl_editwin_get_text(e), 0);
     485  SvUTF8_on(text);
    481486
    482487  ENTER;
     
    484489
    485490  PUSHMARK(SP);
    486   XPUSHs(sv_2mortal(newSVpv(owl_editwin_get_text(e), 0)));
     491  XPUSHs(sv_2mortal(text));
    487492  PUTBACK;
    488493 
  • text.c

    r3bcf125 rf8d9df1  
    5050void owl_text_truncate_cols(char *out, char *in, int acol, int bcol)
    5151{
    52   char *ptr1, *ptr2, *tmpbuff, *last;
    53   int len;
    54 
     52  char *ptr_s, *ptr_e, *ptr_c, *tmpbuff, *last;
     53  int col, cnt, padding;
     54 
    5555  tmpbuff=owl_malloc(strlen(in)+20);
    5656
    5757  strcpy(tmpbuff, "");
    5858  last=in+strlen(in)-1;
    59   ptr1=in;
    60   while (ptr1<last) {
    61     ptr2=strchr(ptr1, '\n');
    62     if (!ptr2) {
     59  ptr_s=in;
     60  while (ptr_s<last) {
     61    ptr_e=strchr(ptr_s, '\n');
     62    if (!ptr_e) {
    6363      /* but this shouldn't happen if we end in a \n */
    6464      break;
    6565    }
    6666   
    67     if (ptr2==ptr1) {
     67    if (ptr_e==ptr_s) {
    6868      strcat(tmpbuff, "\n");
    69       ptr1++;
    70       continue;
    71     }
    72 
     69      ptr_s++;
     70      continue;
     71    }
     72
     73    col = 0;
     74    cnt = 0;
     75    padding = 0;
     76    ptr_c = ptr_s;
     77    while(col < bcol && ptr_c < ptr_e) {
     78      gunichar c = g_utf8_get_char(ptr_c);
     79      if (col + mk_wcwidth(c) > bcol) break;
     80      col += mk_wcwidth(c);
     81      ptr_c = g_utf8_next_char(ptr_c);
     82      if (col >= acol) {
     83        if (cnt == 0) {
     84          ptr_s = ptr_c;
     85          padding = col - acol;
     86        }
     87        ++cnt;
     88      }
     89    }
     90    if (cnt) {
     91      while(padding-- > 0) {
     92        strcat(tmpbuff, " ");
     93      }
     94      strncat(tmpbuff, ptr_s, ptr_c - ptr_s - 1);
     95    }
     96    strcat(tmpbuff, "\n");
     97    ptr_s = ptr_e + 1;
     98#if 0
    7399    /* we need to check that we won't run over here */
    74     if ( (ptr2-ptr1) < (bcol-acol) ) {
    75       len=ptr2-(ptr1+acol);
     100    if ( (ptr_e-ptr_s) < (bcol-acol) ) {
     101      len=ptr_e-(ptr_s+acol);
    76102    } else {
    77103      len=bcol-acol;
    78104    }
    79     if ((ptr1+len)>=last) {
    80       len-=last-(ptr1+len);
    81     }
    82 
    83     strncat(tmpbuff, ptr1+acol, len);
     105    if ((ptr_s+len)>=last) {
     106      len-=last-(ptr_s+len);
     107    }
     108
     109    strncat(tmpbuff, ptr_s+acol, len);
    84110    strcat(tmpbuff, "\n");
    85111
    86     ptr1=ptr2+1;
     112    ptr_s=ptr_e+1;
     113#endif
    87114  }
    88115  strcpy(out, tmpbuff);
     
    275302char *stristr(char *a, char *b)
    276303{
    277   char *x, *y, *ret;
    278 
    279   if ((x=owl_strdup(a))==NULL) return(NULL);
    280   if ((y=owl_strdup(b))==NULL) return(NULL);
    281   downstr(x);
    282   downstr(y);
    283   ret=strstr(x, y);
    284   if (ret==NULL) {
    285     owl_free(x);
    286     owl_free(y);
    287     return(NULL);
    288   }
    289   ret=ret-x+a;
    290   owl_free(x);
    291   owl_free(y);
     304  char *x, *y;
     305  char *ret = NULL;
     306  if ((x = g_utf8_casefold(a, -1)) != NULL) {
     307    if ((y = g_utf8_casefold(b, -1)) != NULL) {
     308      ret = strstr(x, y);
     309      if (ret != NULL) {
     310        ret = ret - x + a;
     311      }
     312      g_free(y);
     313    }
     314    g_free(x);
     315  }
    292316  return(ret);
    293317}
     
    296320int only_whitespace(char *s)
    297321{
    298   int i;
    299   for (i=0; s[i]; i++) {
    300     if (!isspace((int) s[i])) return(0);
     322  if (g_utf8_validate(s,-1,NULL)) {
     323    char *p;
     324    for(p = s; p[0]; p=g_utf8_next_char(p)) {
     325      if (!g_unichar_isspace(g_utf8_get_char(p))) return 0;
     326    }
     327  }
     328  else {
     329    int i;
     330    for (i=0; s[i]; i++) {
     331      if (!isspace((int) s[i])) return(0);
     332    }
    301333  }
    302334  return(1);
     
    327359  tolen  = strlen(to);
    328360  fromlen  = strlen(from);
    329   out = malloc(outlen);
     361  out = owl_malloc(outlen);
    330362
    331363  while (in[inpos]) {
  • util.c

    raf1920fd ree310eb  
    399399}
    400400
    401 /* downcase the string 'foo' */
    402 void downstr(char *foo)
    403 {
    404   int i;
    405   for (i=0; foo[i]!='\0'; i++) {
    406     foo[i]=tolower(foo[i]);
    407   }
    408 }
    409 
    410401/* Caller must free response.
    411402 * Takes in strings which are space-separated lists of tokens
     
    446437void *owl_malloc(size_t size)
    447438{
    448   return(malloc(size));
     439  return(g_malloc(size));
    449440}
    450441
    451442void owl_free(void *ptr)
    452443{
    453   free(ptr);
     444  g_free(ptr);
    454445}
    455446
    456447char *owl_strdup(const char *s1)
    457448{
    458   return(strdup(s1));
     449  return(g_strdup(s1));
    459450}
    460451
    461452void *owl_realloc(void *ptr, size_t size)
    462453{
    463   return(realloc(ptr, size));
     454  return(g_realloc(ptr, size));
    464455}
    465456
    466457/* allocates memory and returns the string or null.
    467458 * caller must free the string.
    468  * from Linux sprintf man page.
    469459 */
    470460char *owl_sprintf(const char *fmt, ...)
    471461{
    472   int n, size = 100;
    473   char *p;
    474462  va_list ap;
    475   if ((p = owl_malloc (size)) == NULL) return (NULL);
    476   while (1) {
    477     /* Try to print in the allocated space. */
    478     va_start(ap, fmt);
    479     n = vsnprintf (p, size, fmt, ap);
    480     va_end(ap);
    481     /* If that worked, return the string. */
    482     if (n > -1 && n < size)
    483       return p;
    484     /* Else try again with more space. */
    485     if (n > -1)    /* glibc 2.1 */
    486       size = n+1; /* precisely what is needed */
    487     else           /* glibc 2.0 */
    488       size *= 2;  /* twice the old size */
    489     if ((p = owl_realloc (p, size)) == NULL)
    490       return NULL;
    491   }
    492 }
     463  char *ret = NULL;
     464  va_start(ap, fmt);
     465  ret = g_strdup_vprintf(fmt, ap);
     466  va_end(ap);
     467  return ret;
     468}
     469
    493470
    494471/* Return the owl color associated with the named color.  Return -1
     
    776753}
    777754
    778 char * owl_get_datadir() {
    779     char * datadir = getenv("BARNOWL_DATA_DIR");
    780     if(datadir != NULL)
    781         return strchr(datadir, '=') + 1;
    782     return DATADIR;
     755char * owl_get_datadir()
     756{
     757  char * datadir = getenv("BARNOWL_DATA_DIR");
     758  if(datadir != NULL)
     759    return strchr(datadir, '=') + 1;
     760  return DATADIR;
     761}
     762
     763/* Strips format characters from a valid utf-8 string. Returns the
     764   empty string if 'in' does not validate. */
     765char * owl_strip_format_chars(char *in)
     766{
     767  char *r;
     768  if (g_utf8_validate(in, -1, NULL)) {
     769    char *s, *p;
     770    r = owl_malloc(strlen(in)+1);
     771    r[0] = '\0';
     772    s = in;
     773    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     774    while(p) {
     775      /* If it's a format character, copy up to it, and skip all
     776         immediately following format characters. */
     777      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     778        strncat(r, s, p-s);
     779        p = g_utf8_next_char(p);
     780        while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
     781          p = g_utf8_next_char(p);
     782        }
     783        s = p;
     784        p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     785      }
     786      else {
     787        p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
     788      }
     789    }
     790    if (s) strcat(r,s);
     791  }
     792  else {
     793    r = owl_strdup("");
     794  }
     795  return r;
     796}
     797
     798/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
     799 * the caller to specify an alternative in the future. We also strip
     800 * out characters in Unicode Plane 16, as we use that plane internally
     801 * for formatting.
     802 */
     803char * owl_validate_or_convert(char *in)
     804{
     805  if (g_utf8_validate(in, -1, NULL)) {
     806    return owl_strip_format_chars(in);
     807  }
     808  else {
     809    return g_convert(in, -1,
     810                     "UTF-8", "ISO-8859-1",
     811                     NULL, NULL, NULL);
     812  }
     813}
     814/* Attempts to convert 'in' to ISO-8859-1. Returns that if possible,
     815   else returns UTF-8.
     816 */
     817char * owl_get_iso_8859_1_if_possible(char *in)
     818{
     819  char *out;
     820  if (g_utf8_validate(in, -1, NULL)) {
     821    out = g_convert(in, -1,
     822                    "ISO-8859-1", "UTF-8",
     823                    NULL, NULL, NULL);
     824    if (!out) {
     825      out = owl_strdup(in);
     826    }
     827  }
     828  else {
     829    out = owl_strdup("");
     830  }
     831  return out;
     832}
     833
     834/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
     835int owl_util_can_break_after(gunichar c)
     836{
     837 
     838  if (c == ' ') return 1;
     839  if (c >= 0x3000 && c <= 0x312f) {
     840    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
     841    if (c == 0x300a || c == 0x300c || c == 0x300e ||
     842        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
     843        c == 0x3018 || c == 0x301a)
     844      return 0;
     845    return 1;
     846  }
     847  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
     848  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
     849  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
     850  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
     851  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
     852  return 0;
    783853}
    784854
  • viewwin.c

    r8721756 r47519e1b  
    7373  owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
    7474
    75   owl_fmtext_curs_waddstr(&fm2, v->curswin);
     75  owl_fmtext_curs_waddstr_without_search(&fm2, v->curswin);
    7676
    7777  /* print the message at the bottom */
  • zcrypt.c

    r9ceee9d r34509d5  
    385385
    386386/* Build a space-separated string from argv from elements between start  *
    387  * and end - 1.  malloc()'s the returned string. */
     387 * and end - 1.  owl_malloc()'s the returned string. */
    388388char *BuildArgString(char **argv, int start, int end) {
    389389  int len = 1;
     
    397397
    398398  /* Allocate memory */
    399   result = (char *)malloc(len);
     399  result = (char *)owl_malloc(len);
    400400  if (result) {
    401401    /* Build the string */
     
    482482      /* Prepare result to be returned */
    483483      char *temp = keyfile;
    484       keyfile = (char *)malloc(strlen(temp) + 1);
     484      keyfile = (char *)owl_malloc(strlen(temp) + 1);
    485485      if (keyfile) {
    486486        strcpy(keyfile, temp);
     
    611611      }
    612612      use_buffer = TRUE;
    613       if ((inptr = inbuff = (char *)malloc(MAX_RESULT)) == NULL) {
     613      if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) {
    614614        printf("Memory allocation error\n");
    615615        return FALSE;
     
    639639      printf("Could not run zwrite\n");
    640640      if (freein && inbuff) {
    641         free(inbuff);
     641        owl_free(inbuff);
    642642      }
    643643      return(FALSE);
     
    685685
    686686  /* Free the input buffer, if necessary */
    687   if (freein && inbuff) free(inbuff);
     687  if (freein && inbuff) owl_free(inbuff);
    688688
    689689  return(!error);
  • zephyr.c

    r9c7a701 r5577606  
    353353  return(owl_strdup(""));
    354354}
     355
     356char *owl_zephyr_get_field_as_utf8(ZNotice_t *n, int j)
     357{
     358  int i, count, save;
     359
     360  /* If there's no message here, just run along now */
     361  if (n->z_message_len == 0)
     362    return(owl_strdup(""));
     363
     364  count=save=0;
     365  for (i = 0; i < n->z_message_len; i++) {
     366    if (n->z_message[i]=='\0') {
     367      count++;
     368      if (count == j) {
     369        /* just found the end of the field we're looking for */
     370        return(owl_validate_or_convert(n->z_message + save));
     371      } else {
     372        save = i + 1;
     373      }
     374    }
     375  }
     376  /* catch the last field, which might not be null terminated */
     377  if (count == j - 1) {
     378    char *tmp, *out;
     379    tmp = owl_malloc(n->z_message_len-save+5);
     380    memcpy(tmp, n->z_message+save, n->z_message_len-save);
     381    tmp[n->z_message_len-save]='\0';
     382    out = owl_validate_or_convert(tmp);
     383    owl_free(tmp);
     384    return out;
     385  }
     386
     387  return(owl_strdup(""));
     388}
    355389#else
    356390char *owl_zephyr_get_field(void *n, int j)
    357391{
    358392  return(owl_strdup(""));
     393}
     394char *owl_zephyr_get_field_as_utf8(void *n, int j)
     395{
     396  return owl_zephyr_get_field(n, j);
    359397}
    360398#endif
  • zwrite.c

    r1fe100c r7b1d048  
    4444        break;
    4545      }
    46       z->class=owl_strdup(myargv[1]);
     46      z->class=owl_get_iso_8859_1_if_possible(myargv[1]);
    4747      myargv+=2;
    4848      myargc-=2;
     
    5252        break;
    5353      }
    54       z->inst=owl_strdup(myargv[1]);
     54      z->inst=owl_get_iso_8859_1_if_possible(myargv[1]);
    5555      myargv+=2;
    5656      myargc-=2;
     
    6060        break;
    6161      }
    62       z->realm=owl_strdup(myargv[1]);
     62      z->realm=owl_get_iso_8859_1_if_possible(myargv[1]);
    6363      myargv+=2;
    6464      myargc-=2;
     
    6868        break;
    6969      }
    70       z->zsig=owl_strdup(myargv[1]);
     70      z->zsig=owl_get_iso_8859_1_if_possible(myargv[1]);
    7171      myargv+=2;
    7272      myargc-=2;
     
    7676        break;
    7777      }
    78       z->opcode=owl_strdup(myargv[1]);
     78      z->opcode=owl_get_iso_8859_1_if_possible(myargv[1]);
    7979      myargv+=2;
    8080      myargc-=2;
     
    9393      myargv++;
    9494      myargc--;
    95       z->message=owl_strdup("");
     95      z->message=owl_get_iso_8859_1_if_possible("");
    9696      while (myargc) {
    97         z->message=realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
     97        z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
    9898        strcat(z->message, myargv[0]);
    9999        strcat(z->message, " ");
     
    113113    } else {
    114114      /* anything unattached is a recipient */
    115       owl_list_append_element(&(z->recips), strdup(myargv[0]));
     115      owl_list_append_element(&(z->recips), owl_get_iso_8859_1_if_possible(myargv[0]));
    116116      myargv++;
    117117      myargc--;
     
    146146
    147147    if (zsigowlvar && *zsigowlvar) {
    148       z->zsig=owl_strdup(zsigowlvar);
     148      z->zsig=owl_get_iso_8859_1_if_possible(zsigowlvar);
    149149    } else if (zsigproc && *zsigproc) {
    150150      FILE *file;
     
    161161      if (!file) {
    162162        if (zsigzvar && *zsigzvar) {
    163           z->zsig=owl_strdup(zsigzvar);
     163          z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
    164164        }
    165165      } else {
     
    175175      }
    176176    } else if (zsigzvar) {
    177       z->zsig=owl_strdup(zsigzvar);
     177      z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
    178178    } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
    179       z->zsig=strdup(pw->pw_gecos);
     179      z->zsig=owl_get_iso_8859_1_if_possible(pw->pw_gecos);
    180180      ptr=strchr(z->zsig, ',');
    181181      if (ptr) {
     
    218218  int i, j;
    219219  char toline[LINE];
     220  char *tmp = NULL;
    220221
    221222  if (z->message) owl_free(z->message);
     
    231232      }
    232233    }
    233     z->message=owl_sprintf("%s\n%s", toline, msg);
     234    tmp = owl_get_iso_8859_1_if_possible(msg);
     235    z->message=owl_sprintf("%s\n%s", toline, tmp);
    234236  } else {
    235     z->message=owl_strdup(msg);
    236   }
     237    z->message=owl_get_iso_8859_1_if_possible(msg);
     238  }
     239  if (tmp) owl_free(tmp);
    237240}
    238241
     
    305308{
    306309  if (z->opcode) owl_free(z->opcode);
    307   z->opcode=owl_strdup(opcode);
     310  z->opcode=owl_get_iso_8859_1_if_possible(opcode);
    308311}
    309312
Note: See TracChangeset for help on using the changeset viewer.