Changes in / [130633c:c08a725]


Ignore:
Files:
1 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5df4b9a r68f1afe  
    1 1.2.1
    2  * Fix building with Zephyr support. -nelhage
    3  * Support --with-stack-protector in 'configure'. -nelhage
    4 
    5 1.2
    6  * Fix some typos in source and messages. -adehnert
    7  * Support an explicit --with{out,}-zephyr configure option. -nelhage
    8  * Display a nicer error in :blist if .anyone doesn't exist. -geofft
    9  * Don't zcrypt shift-R replies to zcrypted messages -adehnert
    10  * Export a time_t for messages to perl as 'unix_time' -nelhage
    11  * Get rid of cryptic numeric messages after IRC commands. -ezyang
    12  * IRC: Include IRC admin messages in the 'irc' filter. -geofft
    13  * Fix M-LEFT and M-RIGHT bindings. -nelhage
    14  * Fix replycmd to use right class/instance -adehnert
    15  * Allow SIGINT to interrupt getting the Zephyr buddy list -nelhage
    16  * Break perlwrap.pm into multiple files. -nelhage
    17  * Handle errors in perlwrap.pm better. -nelhage
    18  * Don't attempt to send a Zephyr logout if we never initialized Zephyr. -nelhage
    19  * Display personals better in OneLine mode. -adehnert
    20  * Display context for pings -adehnert
    21  * Support --program-{prefix,suffix,transform}. -nelhage
    22  * Send instanced pings and give useful error messages -adehnert
    23  * Add <message,*,%me%> to default Barnowl subs. -adehnert
    24  * Maintain instance when using shift-R on personals -adehnert
    25  * Improve handling of outgoing instanced personals -adehnert
    26  * Don't require personals to be -i personal. -geofft
    27  * Display context for personals, so as to make <message,*,%me> usable. -geofft
    28  * Implement mark and swap in the message list. -asedeno
    29  * Fix handling of C-SPACE. -nelhage
    30  * Fix some warnings. -nelhage
    31  * Handle SIGINT, and make ^C interrupt searches. -nelhage
    32  * Fix the usage line for punt/unpunt -nelhage
    33  * Small bugfixes to release scripts. -nelhage
    34 
    3511.1.1
    362 * Fix bogus errors 'subscribing to login messages'. -nelhage
  • codelist.pl

    r0982901 r09489b89  
    88
    99foreach $file (@ARGV) {
    10     next if $file eq 'perlglue.c';
    1110    open(FILE, $file);
    1211
  • commands.c

    r2fc8397 r73ba824  
    881881                  "", ""),
    882882
    883   OWLCMD_VOID_CTX("edit:set-mark", owl_editwin_set_mark,
    884                   OWL_CTX_EDIT,
    885                   "sets the mark",
    886                   "", ""),
    887 
    888   OWLCMD_VOID_CTX("edit:exchange-point-and-mark", owl_editwin_exchange_point_and_mark,
    889                   OWL_CTX_EDIT,
    890                   "exchanges the point and the mark",
    891                   "", ""),
    892 
    893   OWLCMD_VOID_CTX("edit:copy-region-as-kill", owl_editwin_copy_region_as_kill,
    894                   OWL_CTX_EDIT,
    895                   "copy the text between the point and the mark",
    896                   "", ""),
    897 
    898   OWLCMD_VOID_CTX("edit:kill-region", owl_editwin_kill_region,
    899                   OWL_CTX_EDIT,
    900                   "kill text between the point and the mark",
    901                   "", ""),
    902 
    903   OWLCMD_VOID_CTX("edit:yank", owl_editwin_yank,
    904                   OWL_CTX_EDIT,
    905                   "insert the current text from the kill buffer",
    906                   "", ""),
    907 
    908883  OWLCMD_VOID_CTX("editline:done", owl_command_editline_done,
    909884                  OWL_CTX_EDITLINE,
     
    938913                  "runs 'editmulti:done'.\n"\
    939914                  "Otherwise runs 'edit:delete-next-char'\n"),
    940 
    941   OWLCMD_VOID_CTX("editmulti:forward-paragraph", owl_editwin_forward_paragraph,
    942                   OWL_CTX_EDITMULTI,
    943                   "Move forward to end of paragraph.",
    944                   "",
    945                   "Move the point to the end of the current paragraph"),
    946 
    947   OWLCMD_VOID_CTX("editmulti:backward-paragraph", owl_editwin_backward_paragraph,
    948                   OWL_CTX_EDITMULTI,
    949                   "Move backward to the start of paragraph.",
    950                   "",
    951                   "Move the point to the start of the current paragraph"),
    952915
    953916  /****************************************************************/
     
    26952658  owl_function_makemsg("Command cancelled.");
    26962659
    2697   if(owl_editwin_get_echochar(e) == 0) {
     2660  if(e->echochar == 0) {
    26982661    hist=owl_editwin_get_history(e);
    26992662    owl_history_store(hist, owl_editwin_get_text(e));
  • configure.ac

    rc08a725 rc08a725  
    11dnl $Id$
    22dnl Process this file with autoconf to produce a configure script.
    3 AC_INIT([BarnOwl],[1.3],[bug-barnowl@mit.edu])
     3AC_INIT([BarnOwl],[1.1.2],[bug-barnowl@mit.edu])
    44AM_INIT_AUTOMAKE([-Wall foreign])
    55
     
    4242        AC_MSG_RESULT(no)
    4343fi
     44PROTECT_CFLAGS=${PROTECT_CFLAGS-"-fstack-protector"}
     45SAVE_CFLAGS=$CFLAGS
     46CFLAGS="$CFLAGS $PROTECT_CFLAGS"
     47AC_MSG_CHECKING(whether protection cflags work)
     48AC_COMPILE_IFELSE(int i;,
     49    [AC_MSG_RESULT(yes)],
     50    [AC_MSG_RESULT(no)
     51    CFLAGS=$SAVE_CFLAGS])
    4452
    45 AC_ARG_WITH([stack-protector],
    46   [AS_HELP_STRING([--with-stack-protector],
    47     [Enable gcc -fstack-protector])],
    48   [],
    49   [with_stack_protector=check])
    5053
    51 AS_IF([test "x$with_stack_protector" != xno],
    52   [
    53     SAVE_CFLAGS=$CFLAGS
    54     CFLAGS="$CFLAGS -fstack-protector"
    55     AC_MSG_CHECKING(whether protection cflags work)
    56     AC_COMPILE_IFELSE(int i;,
    57         [AC_MSG_RESULT(yes)],
    58         [AC_MSG_RESULT(no)
    59         CFLAGS=$SAVE_CFLAGS
    60         if test "x$with_stack_protector" != xcheck; then
    61           AC_MSG_FAILURE([--with-stack-protector selected, but gcc does support it.])
    62         fi])
    63     AC_CHECK_LIB(ssp, __stack_chk_guard)
    64   ])
    65 
     54AC_CHECK_LIB(ssp, __stack_chk_guard)
    6655AC_CHECK_LIB(ncursesw, initscr,, AC_MSG_ERROR(No libncursesw found.))
    6756AC_CHECK_LIB(com_err, com_err)
     
    7160AC_CHECK_LIB(des425, des_cbc_encrypt,,AC_CHECK_LIB(crypto,DES_cbc_encrypt))
    7261AC_CHECK_LIB(resolv, res_search)
    73 
    74 AC_ARG_WITH([zephyr],
    75   [AS_HELP_STRING([--with-libzephyr],
    76     [Disable Zephyr support])],
    77   [],
    78   [with_zephyr=check])
    79 
    80 AS_IF([test "x$with_zephyr" != xno],
    81   [AC_CHECK_LIB([zephyr], [ZGetSender],
    82    [LIBS="$LIBS -lzephyr"
    83     AC_DEFINE([HAVE_LIBZEPHYR], [1],
    84                 [Define if you have libzephyr])
    85     AC_CHECK_LIB([zephyr], [ZInitLocationInfo],
    86       AC_DEFINE([HAVE_LIBZEPHYR_ZINITLOCATIONINFO], [1],
    87                 [Have ZInitLocationInfo]),)
    88    ],
    89    [if test "x$with_zephyr" != xcheck; then
    90       AC_MSG_FAILURE(
    91         [--with-libzephyr was given, but libzephyr does not seem to be available.])
    92     fi
    93    ])])
     62dnl AC_CHECK_LIB(zephyr, ZGetSender,, AC_MSG_ERROR(No zephyr library found.))
     63AC_CHECK_LIB(zephyr, ZGetSender)
     64AC_CHECK_LIB(zephyr, ZInitLocationInfo, AC_DEFINE([HAVE_LIBZEPHYR_ZINITLOCATIONINFO], [], [Have ZInitLocationInfo]),)
    9465
    9566AC_CHECK_FUNCS(use_default_colors resizeterm des_string_to_key des_key_sched des_ecb_encrypt)
  • editwin.c

    r72ab15f r50e671c  
    77static const char fileIdent[] = "$Id$";
    88
    9 #define VALID_EXCURSION (0x9a2b4729)
    10 
    11 typedef struct _owl_editwin_excursion { /*noproto*/
    12   int valid;
    13   int index;
    14   int mark;
    15   int goal_column;
    16   int lock;
    17   struct _owl_editwin_excursion *next;
    18 } oe_excursion;
    19 
    20 struct _owl_editwin { /*noproto*/
    21   char *buff;
    22   owl_history *hist;
    23   int bufflen;
    24   int allocated;
    25   int index;
    26   int mark;
    27   char *killbuf;
    28   int goal_column;
    29   int topindex;
    30   int cursorx;
    31   int winlines, wincols, fillcol, wrapcol;
    32   WINDOW *curswin;
    33   int style;
    34   int lock;
    35   int dotsend;
    36   int echochar;
    37   oe_excursion *excursions;
    38 
    39   char *command;
    40   void (*callback)(struct _owl_editwin*);
    41   void *cbdata;
    42 };
    43 
    44 static void oe_reframe(owl_editwin *e);
    45 static void oe_save_excursion(owl_editwin *e, oe_excursion *x);
    46 static void oe_release_excursion(owl_editwin *e, oe_excursion *x);
    47 static void oe_restore_excursion(owl_editwin *e, oe_excursion *x);
    48 static void oe_restore_mark_only(owl_editwin *e, oe_excursion *x);
    49 static int oe_count_glyphs(char *s);
    50 static int oe_char_width(gunichar c, int column);
    51 static int oe_region_width(owl_editwin *e, int start, int end, int width);
    52 static int oe_find_display_line(owl_editwin *e, int *x, int index);
    53 static void oe_insert_char(owl_editwin *e, gunichar c);
    54 static int owl_editwin_limit_maxcols(int v, int maxv);
    55 static int owl_editwin_check_dotsend(owl_editwin *e);
    56 static int owl_editwin_is_char_in(owl_editwin *e, char *set);
    57 static gunichar owl_editwin_get_char_at_point(owl_editwin *e);
    58 static int owl_editwin_replace_internal(owl_editwin *e, int replace, char *s);
    59 static char *oe_copy_buf(owl_editwin *e, char *buf, int len);
    60 static int oe_copy_region(owl_editwin *e);
    61 static char *oe_chunk(owl_editwin *e, int start, int end);
    62 
    63 #define INCR 4096
    64 
    65 #define WHITESPACE " \n\t"
    66 
    67 owl_editwin *owl_editwin_allocate(void)
    68 {
    69   owl_editwin *e;
    70   e = owl_malloc(sizeof(owl_editwin));
    71   memset(e, 0, sizeof(*e));
    72   return e;
    73 }
    74 
    75 static int oe_count_glyphs(char *s)
    76 {
    77   int count = 0;
    78   char *p;
    79 
    80   for(p = s; *p != 0; p = g_utf8_find_next_char(p, NULL))
    81     if (!g_unichar_ismark(g_utf8_get_char(p)))
    82       count++;
    83 
    84   return count;
    85 }
    86 
    87 static inline void oe_set_index(owl_editwin *e, int index)
    88 {
    89   if (index != e->index) {
    90     e->goal_column = -1;
    91     e->cursorx = -1;
    92   }
    93   e->index = index;
    94 }
    95 
    96 static inline void oe_set_mark(owl_editwin *e, int mark)
    97 {
    98   e->mark = mark;
    99 }
    100 
    101 void owl_editwin_set_mark(owl_editwin *e)
    102 {
    103   oe_set_mark(e, e->index);
    104   /* owl_function_makemsg("Mark set."); */
    105 }
     9#define INCR 5000
    10610
    10711/* initialize the editwin e.
     
    11014void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
    11115{
    112   e->buff=owl_malloc(INCR);
     16  e->buff=owl_malloc(INCR); 
    11317  e->buff[0]='\0';
    11418  e->bufflen=0;
    11519  e->hist=hist;
    11620  e->allocated=INCR;
    117   oe_set_index(e, 0);
    118   oe_set_mark(e, -1);
    119   if (e->killbuf != NULL)
    120     free(e->killbuf);
    121   e->killbuf = NULL;
    122   e->goal_column = -1;
    123   e->cursorx = -1;
    124   e->topindex = 0;
    125   e->excursions = NULL;
    126   owl_editwin_set_curswin(e, win, winlines, wincols);
     21  e->buffx=0;
     22  e->buffy=0;
     23  e->topline=0;
     24  e->winlines=winlines;
     25  e->wincols=wincols;
     26  e->fillcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxfillcols(&g));
     27  e->wrapcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxwrapcols(&g));
     28  e->curswin=win;
    12729  e->style=style;
    12830  if ((style!=OWL_EDITWIN_STYLE_MULTILINE) &&
     
    16769}
    16870
     71void owl_editwin_set_history(owl_editwin *e, owl_history *h)
     72{
     73  e->hist=h;
     74}
     75
    16976owl_history *owl_editwin_get_history(owl_editwin *e)
    17077{
     
    17784}
    17885
    179 void owl_editwin_set_command(owl_editwin *e, char *command)
    180 {
     86void owl_editwin_set_command(owl_editwin *e, char *command) {
    18187  if(e->command) owl_free(e->command);
    18288  e->command = owl_strdup(command);
    18389}
    18490
    185 char *owl_editwin_get_command(owl_editwin *e)
    186 {
     91char *owl_editwin_get_command(owl_editwin *e) {
    18792  if(e->command) return e->command;
    18893  return "";
    18994}
    19095
    191 void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*))
    192 {
     96void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*)) {
    19397  e->callback = cb;
    19498}
    19599
    196 void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*)
    197 {
     100void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*) {
    198101  return e->callback;
    199102}
    200103
    201 void owl_editwin_set_cbdata(owl_editwin *e, void *data)
    202 {
     104void owl_editwin_set_cbdata(owl_editwin *e, void *data) {
    203105  e->cbdata = data;
    204106}
    205107
    206 void *owl_editwin_get_cbdata(owl_editwin *e) {
     108void* owl_editwin_get_cbdata(owl_editwin *e) {
    207109  return e->cbdata;
    208110}
     
    219121}
    220122
    221 static int owl_editwin_limit_maxcols(int v, int maxv)
    222 {
    223   /* maxv > 5 ? MAX(v, vax) : v */
     123int owl_editwin_limit_maxcols(int v, int maxv)
     124{
    224125  if (maxv > 5 && v > maxv) {
    225126    return(maxv);
     
    234135void owl_editwin_set_locktext(owl_editwin *e, char *text)
    235136{
    236   oe_set_index(e, 0);
    237   e->lock = 0;
    238   owl_editwin_replace(e, e->bufflen, text);
    239   e->buff[e->bufflen] = 0;
    240   e->lock=e->bufflen;
    241   oe_set_index(e, e->lock);
     137 
     138  int x, y;
     139
     140  x=e->buffx;
     141  y=e->buffy;
     142  e->buffx=0;
     143  e->buffy=0;
     144  owl_editwin_overwrite_string(e, text);
     145  owl_editwin_overwrite_char(e, '\0');
     146  e->lock=strlen(text);
     147  /* if (text[e->lock-1]=='\n') e->lock--; */
     148  /*  e->buffx=x; */
     149  /*  e->buffy=y; */
     150  _owl_editwin_set_xy_by_index(e, e->lock);
    242151  owl_editwin_redisplay(e, 0);
    243152}
     
    250159void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h)
    251160{
    252   e->hist = h;
    253 
     161  char *ptr;
     162
     163  owl_editwin_set_history(e, h);
    254164  if (e->style==newstyle) return;
    255165
     
    260170
    261171    /* nuke everything after the first line */
    262     owl_editwin_move_to_top(e);
    263     owl_editwin_move_to_end_of_line(e);
    264     owl_editwin_replace(e, oe_count_glyphs(e->buff + e->index),  "");
     172    if (e->bufflen > 0) {
     173      ptr=strchr(e->buff, '\n')-1;
     174      if (ptr) {
     175        e->bufflen=ptr - e->buff;
     176        e->buff[e->bufflen]='\0';
     177        e->buffx=0;
     178        e->buffy=0;
     179      }
     180    }
    265181  }
    266182}
     
    279195{
    280196
    281   int lock = e->lock;
     197  int lock;
    282198  int dotsend=e->dotsend;
    283199  char *locktext=NULL;
    284200  char echochar=e->echochar;
    285201
    286   if (lock > 0) {
    287     locktext = owl_malloc(lock+1);
    288     strncpy(locktext, e->buff, lock);
    289     locktext[lock] = 0;
     202  lock=0;
     203  if (e->lock > 0) {
     204    lock=1;
     205
     206    locktext=owl_malloc(e->lock+20);
     207    strncpy(locktext, e->buff, e->lock);
     208    locktext[e->lock]='\0';
    290209  }
    291210
     
    303222  }
    304223
    305   if (locktext)
    306     owl_free(locktext);
    307 
    308   oe_set_index(e, lock);
     224  if (locktext) owl_free(locktext);
     225  owl_editwin_adjust_for_locktext(e);
     226}
     227
     228/* malloc more space for the buffer */
     229void _owl_editwin_addspace(owl_editwin *e)
     230{
     231  e->buff=owl_realloc(e->buff, e->allocated+INCR);
     232  if (!e->buff) {
     233    /* error */
     234    return;
     235  }
     236  e->allocated+=INCR;
    309237}
    310238
    311239void owl_editwin_recenter(owl_editwin *e)
    312240{
    313   e->topindex = -1;
    314 }
    315 
    316 static void oe_save_excursion(owl_editwin *e, oe_excursion *x)
    317 {
    318   x->index = e->index;
    319   x->mark = e->mark;
    320   x->goal_column = e->goal_column;
    321   x->lock = e->lock;
    322 
    323   x->valid = VALID_EXCURSION;
    324   x->next = e->excursions;
    325   e->excursions = x;
    326 }
    327 
    328 static void oe_release_excursion(owl_editwin *e, oe_excursion *x)
    329 {
    330   oe_excursion *p;
    331 
    332   x->valid = 0;
    333   if (e->excursions == NULL)
    334     /* XXX huh. */ ;
    335   else if (e->excursions == x)
    336     e->excursions = x->next;
    337   else {
    338     for (p = e->excursions; p->next != NULL; p = p->next)
    339       if (p->next == x) {
    340         p->next = p->next->next;
    341         break;
    342       }
    343     /* and if we ran off the end? XXX */
    344   }
    345 }
    346 
    347 static void oe_restore_excursion(owl_editwin *e, oe_excursion *x)
    348 {
    349   if (x->valid == VALID_EXCURSION) {
    350     oe_set_index(e, x->index);
    351     e->goal_column = x->goal_column;
    352     e->mark = x->mark;
    353     e->lock = x->lock;
    354 
    355     oe_release_excursion(e, x);
    356   }
    357 }
    358 
    359 static void oe_restore_mark_only(owl_editwin *e, oe_excursion *x)
    360 {
    361   if (x->valid == VALID_EXCURSION) {
    362     e->mark = x->mark;
    363 
    364     oe_release_excursion(e, x);
    365   }
    366 }
    367 
    368 /* External interface to oe_save_excursion */
    369 owl_editwin_excursion *owl_editwin_begin_excursion(owl_editwin *e)
    370 {
    371   owl_editwin_excursion *x = owl_malloc(sizeof *x);
    372   oe_save_excursion(e, x);
    373   return x;
    374 }
    375 
    376 void owl_editwin_end_excursion(owl_editwin *e, owl_editwin_excursion *x)
    377 {
    378   oe_restore_excursion(e, x);
    379   owl_free(x);
    380 }
    381 
    382 static inline char *oe_next_point(owl_editwin *e, char *p)
    383 {
    384   char *boundary = e->buff + e->bufflen + 1;
    385   char *q;
    386 
    387   q = g_utf8_find_next_char(p, boundary);
    388   while (q && g_unichar_ismark(g_utf8_get_char(q)))
    389     q = g_utf8_find_next_char(q, boundary);
    390 
    391   if (q == p)
    392     return NULL;
    393   return q;
    394 }
    395 
    396 static inline char *oe_prev_point(owl_editwin *e, char *p)
    397 {
    398   char *boundary = e->buff + e->lock;
    399 
    400   p = g_utf8_find_prev_char(boundary, p);
    401   while (p && g_unichar_ismark(g_utf8_get_char(p)))
    402     p = g_utf8_find_prev_char(boundary, p);
    403 
    404   return p;
    405 }
    406 
    407 static int oe_char_width(gunichar c, int column)
    408 {
    409   int cw;
    410 
    411   if (c == 9) /* TAB */
    412     return TABSIZE - column % TABSIZE;
    413 
    414   cw = mk_wcwidth(c);
    415 
    416   if (cw < 0) /* control characters */
    417     cw = 0;
    418 
    419   return cw;
    420 }
    421 
    422 static int oe_find_display_line(owl_editwin *e, int *x, int index)
    423 {
    424   int width = 0, cw;
    425   gunichar c;
    426   char *p;
    427 
    428   while(1) {
    429     /* note the position of the dot */
    430     if (x != NULL && index == e->index && width < e->wincols)
    431       *x = width;
    432 
    433     /* get the current character */
    434     c = g_utf8_get_char(e->buff + index);
    435 
    436     /* figure out how wide it is */
    437     cw = oe_char_width(c, width);
    438 
    439     if (width + cw > e->wincols) {
    440       if (x != NULL && *x == width)
    441         *x = -1;
    442       break;
    443     }
    444     width += cw;
    445 
    446     if (c == '\n') {
    447       if (width < e->wincols)
    448         ++index; /* skip the newline */
    449       break;
    450     }
    451 
    452     /* find the next character */
    453     p = oe_next_point(e, e->buff + index);
    454     if (p == NULL) { /* we ran off the end */
    455       if (x != NULL && e->index > index)
    456         *x = width + 1;
    457       break;
    458     }
    459     index = p - e->buff;
    460 
    461   }
    462   return index;
    463 }
    464 
    465 static void oe_reframe(owl_editwin *e) {
    466   oe_excursion x;
    467   int goal = e->winlines / 2;
    468   int index;
    469   int count = 0;
    470   int point;
    471   int n, i;
    472   int last;
    473 
    474   oe_save_excursion(e, &x);
    475   /* step back line-by-line through the buffer until we have >= goal lines of
    476      display text */
    477   e->lock = 0; /* we can (must) tread on the locktext */
    478 
    479   point = e->index;
    480   last = -1;
    481   while (count < goal) {
    482     index = e->index;
    483     owl_editwin_move_to_beginning_of_line(e);
    484     if (last == e->index)
    485       break;
    486     last = e->index;
    487     for (n = 0, i = e->index; i < index; n++)
    488       i = oe_find_display_line(e, NULL, i);
    489     count += n == 0 ? 1 : n;
    490     if (count < goal)
    491       owl_editwin_point_move(e, -1);
    492   }
    493 
    494   e->topindex = e->index;
    495   /* if we overshot, backtrack */
    496   for (n = 0; n < (count - goal); n++)
    497     e->topindex = oe_find_display_line(e, NULL, e->topindex);
    498 
    499   oe_restore_excursion(e, &x);
    500 }
    501 
    502 static void oe_addnec(owl_editwin *e, int count)
    503 {
    504   int i;
    505 
    506   for (i = 0; i < count; i++)
    507     waddch(e->curswin, e->echochar);
    508 }
    509 
    510 static void oe_mvaddnec(owl_editwin *e, int y, int x, int count)
    511 {
    512   wmove(e->curswin, y, x);
    513   oe_addnec(e, count);
     241  e->topline=e->buffy-(e->winlines/2);
     242  if (e->topline<0) e->topline=0;
     243  if (e->topline>owl_editwin_get_numlines(e)) e->topline=owl_editwin_get_numlines(e);
    514244}
    515245
     
    518248void owl_editwin_redisplay(owl_editwin *e, int update)
    519249{
    520   int x = -1, y = -1, t;
    521   int line, index, lineindex, times = 0;
    522 
    523   do {
    524     werase(e->curswin);
    525 
    526     if (e->topindex == -1 || e->index < e->topindex)
    527       oe_reframe(e);
    528 
    529     line = 0;
    530     index = e->topindex;
    531     while(line < e->winlines) {
    532       lineindex = index;
    533       t = -1;
    534       index = oe_find_display_line(e, &t, lineindex);
    535       if (x == -1 && t != -1)
    536         x = t, y = line;
    537       if (index - lineindex) {
    538         if (!e->echochar)
    539           mvwaddnstr(e->curswin, line, 0,
    540                      e->buff + lineindex,
    541                      index - lineindex);
    542         else {
    543           if(lineindex < e->lock) {
    544             mvwaddnstr(e->curswin, line, 0,
    545                        e->buff + lineindex,
    546                        MIN(index - lineindex,
    547                            e->lock - lineindex));
    548             if (e->lock < index)
    549               oe_addnec(e,
    550                         oe_region_width(e, e->lock, index,
    551                                         oe_region_width(e, lineindex, e->lock, 0)));
    552           } else
    553             oe_mvaddnec(e, line, 0, oe_region_width(e, line, index, 0));
    554         }
    555       }
    556       line++;
    557     }
    558     if (x == -1)
    559         e->topindex = -1; /* force a reframe */
    560     times++;
    561   } while(x == -1 && times < 3);
    562 
    563   wmove(e->curswin, y, x);
    564   e->cursorx = x;
    565 
     250 
     251  char *ptr1, *ptr2, *ptr3, *buff;
     252  int i;
     253
     254  werase(e->curswin);
     255  wmove(e->curswin, 0, 0);
     256
     257  /* start at topline */
     258  ptr1 = e->buff;
     259  for (i = 0; i < e->topline; i++) {
     260    ptr2 = strchr(ptr1, '\n');
     261    if (!ptr2) {
     262      /* we're already on the last line */
     263      break;
     264    }
     265    ptr1 = ptr2 + 1;
     266  }
     267  /* ptr1 now stores the starting point */
     268
     269  /* find the ending point and store it in ptr3 */
     270  ptr2 = ptr1;
     271  ptr3 = ptr1;
     272  for (i = 0; i < e->winlines; i++) {
     273    ptr3 = strchr(ptr2, '\n');
     274    if (!ptr3) {
     275      /* we've hit the last line */
     276      /* print everything to the end */
     277      ptr3 = e->buff + e->bufflen - 1;
     278      ptr3--;
     279      break;
     280    }
     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') {
     289    waddstr(e->curswin, buff);
     290  } else {
     291    /* translate to echochar, *except* for the locktext */
     292    int len;
     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++) {
     305      waddch(e->curswin, e->echochar);
     306    }
     307  }
     308  wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
    566309  wnoutrefresh(e->curswin);
    567   if (update == 1)
     310  if (update == 1) {
    568311    doupdate();
    569 }
    570 
    571 static inline void oe_fixup(int *target, int start, int end, int change) {
    572   if (*target > start) {
    573     if (*target < end)
    574       *target = end;
    575     else
    576       *target += change;
    577   }
    578 }
    579 
    580 int owl_editwin_replace_region(owl_editwin *e, char *s)
    581 {
    582   oe_excursion x;
    583   oe_save_excursion(e, &x);
    584   int ret;
    585 
    586   if(e->index > e->mark) {
    587     owl_editwin_exchange_point_and_mark(e);
    588   }
    589 
    590   ret = owl_editwin_replace_internal(e, e->mark - e->index, s);
    591 
    592   oe_restore_excursion(e, &x);
    593 
    594   return ret;
    595 }
    596 
    597 /* replace 'replace' characters at the point with s, returning the change in size */
    598 int owl_editwin_replace(owl_editwin *e, int replace, char *s)
    599 {
    600   int start, end, i;
    601   char *p;
    602 
    603   if (!g_utf8_validate(s, -1, NULL)) {
    604     owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
    605     return 0;
    606   }
    607 
    608   start = e->index;
    609   for (i = 0, p = e->buff + start; i < replace && p != NULL; i++)
    610     p = oe_next_point(e, p);
    611   if (p != NULL)
    612     end = p - e->buff;
    613   else
    614     end = e->bufflen;
    615 
    616   return owl_editwin_replace_internal(e, end - start, s);
    617 }
    618 
    619 static int owl_editwin_replace_internal(owl_editwin *e, int replace, char *s)
    620 {
    621   int start, end, free, need, size, change;
    622   oe_excursion *x;
    623   char *p;
    624 
    625   start = e->index;
    626   end   = start + replace;
    627 
    628   free = e->allocated - e->bufflen + end - start;
    629 
    630   need = strlen(s) - free;
    631   if (need > 0) {
    632     size = e->allocated + need + INCR - (need % INCR);
    633     p = owl_realloc(e->buff, size);
    634     if (p == NULL) {
    635       /* XXX signal impending doom somehow and don't do anything */
    636       return 0;
    637     }
    638     e->buff = p;
    639     e->allocated = size;
    640   }
    641 
    642   memmove(e->buff + start + strlen(s), e->buff + end, e->bufflen + 1 - end);
    643   memcpy(e->buff + start, s, strlen(s));
    644   change = start - end + strlen(s);
    645   e->bufflen += change;
    646   e->index += strlen(s);
    647 
    648   /* fix up the mark */
    649   oe_fixup(&e->mark, start, end, change);
    650   oe_fixup(&e->topindex, start, end, change);
    651   /* fix up any saved points after the replaced area */
    652   for (x = e->excursions; x != NULL; x = x->next) {
    653     oe_fixup(&x->index, start, end, change);
    654     oe_fixup(&x->mark, start, end, change);
    655   }
    656 
    657   return change;
    658 }
     312  }
     313  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  z = _owl_editwin_get_index_from_xy(e);
     338
     339  if(z != e->bufflen) {
     340    for (i = e->bufflen + n - 1; i > z; i--) {
     341      e->buff[i] = e->buff[i - n];
     342    }
     343  }
     344
     345  e->bufflen += n;
     346  e->buff[e->bufflen] = '\0';
     347
     348}
     349
    659350
    660351/* linewrap the word just before the cursor.
     
    662353 * returns -1 if we could not wrap.
    663354 */
    664 static void _owl_editwin_linewrap_word(owl_editwin *e)
    665 {
    666   oe_excursion x;
     355int _owl_editwin_linewrap_word(owl_editwin *e)
     356{
     357  int x, y;
     358  int i;
     359  char *ptr1, *start;
    667360  gunichar c;
    668361
    669   oe_save_excursion(e, &x);
    670 
    671   while (owl_editwin_point_move(e, -1)) {
    672     c = owl_editwin_get_char_at_point(e);
    673     if (owl_util_can_break_after(c) || c == '\n') {
    674       if (c != '\n')
    675         owl_editwin_replace(e, c != ' ' ? 0 : 1, "\n");
    676       break;
    677     }
    678   }
    679 
    680   oe_restore_excursion(e, &x);
     362  /* saving values */
     363  x = e->buffx;
     364  y = e->buffy;
     365  start = e->buff + e->lock;
     366
     367  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     368  ptr1 = g_utf8_find_prev_char(start, ptr1);
     369
     370  while (ptr1) {
     371    c = g_utf8_get_char(ptr1);
     372    if (owl_util_can_break_after(c)) {
     373      if (c != ' ') {
     374        i = ptr1 - e->buff;
     375        _owl_editwin_set_xy_by_index(e, i);
     376        _owl_editwin_insert_bytes(e, 1);
     377        /* _owl_editwin_insert_bytes may move e->buff. */
     378        ptr1 = e->buff + i;
     379      }
     380      *ptr1 = '\n';
     381      return 0;
     382    }
     383    else if (c == '\n') {
     384      return 0;
     385    }
     386    ptr1 = g_utf8_find_prev_char(start, ptr1);
     387  }
     388  return -1;
     389}
     390
     391/* insert a character at the current point (shift later
     392 * characters over)
     393 */
     394void owl_editwin_insert_char(owl_editwin *e, gunichar c)
     395{
     396  int z, i, ret, len;
     397  char tmp[6];
     398  memset(tmp, '\0', 6);
     399
     400  /* \r is \n */
     401  if (c == '\r') {
     402    c = '\n';
     403  }
     404
     405  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
     406    /* perhaps later this will change some state that allows the string
     407       to be read */
     408    return;
     409  }
     410
     411  g_unichar_to_utf8(c, tmp);
     412  len = strlen(tmp);
     413
     414  /* make sure there is enough memory for the new text */
     415  if ((e->bufflen + len) > (e->allocated - 5)) {
     416    _owl_editwin_addspace(e);
     417  }
     418
     419  /* get the insertion point */
     420  z = _owl_editwin_get_index_from_xy(e);
     421
     422  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
     423  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
     424    ret = _owl_editwin_linewrap_word(e);
     425    if (ret == -1) {
     426      /* we couldn't wrap, insert a hard newline instead */
     427      owl_editwin_insert_char(e, '\n');
     428    }
     429  }
     430
     431  /* shift all the other characters right */
     432  _owl_editwin_insert_bytes(e, len);
     433
     434  /* insert the new character */
     435  for(i = 0; i < len; i++) {
     436    e->buff[z + i] = tmp[i];
     437  }
     438
     439  /* advance the cursor */
     440  z += len;
     441  _owl_editwin_set_xy_by_index(e, z);
     442}
     443
     444/* overwrite the character at the current point with 'c' */
     445void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
     446{
     447  int z, oldlen, newlen, i;
     448  char tmp[6];
     449  memset(tmp, '\0', 6);
     450
     451  /* \r is \n */
     452  if (c == '\r') {
     453    c = '\n';
     454  }
     455 
     456  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
     457    /* perhaps later this will change some state that allows the string
     458       to be read */
     459    return;
     460  }
     461
     462  g_unichar_to_utf8(c, tmp);
     463  newlen = strlen(tmp);
     464
     465  z = _owl_editwin_get_index_from_xy(e);
     466  {
     467    char *t = g_utf8_find_next_char(e->buff + z, NULL);
     468    oldlen = (t ? (t - (e->buff + z)) : 0);
     469  }
     470
     471  /* only if we are at the end of the buffer do we create new space here */
     472  if (z == e->bufflen) {
     473    if ((e->bufflen+newlen) > (e->allocated-5)) {
     474      _owl_editwin_addspace(e);
     475    }
     476  }
     477  /* if not at the end of the buffer, adjust based in char size difference. */
     478  else if (oldlen > newlen) {
     479    _owl_editwin_remove_bytes(e, oldlen-newlen);
     480  }
     481  else /* oldlen < newlen */ {
     482    _owl_editwin_insert_bytes(e, newlen-oldlen);
     483  }
     484  /* Overwrite the old char*/
     485  for (i = 0; i < newlen; i++) {
     486    e->buff[z+i] = tmp[i];
     487  }
     488       
     489  /* housekeeping */
     490  if (z == e->bufflen) {
     491    e->bufflen += newlen;
     492    e->buff[e->bufflen] = '\0';
     493  }
     494 
     495  /* advance the cursor */
     496  z += newlen;
     497  _owl_editwin_set_xy_by_index(e, z);
    681498}
    682499
    683500/* delete the character at the current point, following chars
    684501 * shift left.
    685  */
     502 */ 
    686503void owl_editwin_delete_char(owl_editwin *e)
    687504{
    688   owl_editwin_replace(e, 1, "");
     505  int z;
     506  char *p1, *p2;
     507  gunichar c;
     508
     509  if (e->bufflen == 0) return;
     510 
     511  /* get the deletion point */
     512  z = _owl_editwin_get_index_from_xy(e);
     513
     514  if (z == e->bufflen) return;
     515
     516  p1 = e->buff + z;
     517  p2 = g_utf8_next_char(p1);
     518  c = g_utf8_get_char(p2);
     519  while (g_unichar_ismark(c)) {
     520    p2 = g_utf8_next_char(p2);
     521    c = g_utf8_get_char(p2);
     522  }
     523  _owl_editwin_remove_bytes(e, p2-p1);
    689524}
    690525
     
    692527 * advance the pointer.  If point is at beginning of buffer do
    693528 * nothing.  If point is after the last character swap point-1 with
    694  * point-2.  (Behaves as observed in tcsh and emacs).
     529 * point-2.  (Behaves as observed in tcsh and emacs). 
    695530 */
    696531void owl_editwin_transpose_chars(owl_editwin *e)
    697532{
    698   char *middle, *end, *start, *tmp;
     533  int z;
     534  char *p1, *p2, *p3, *tmp;
    699535
    700536  if (e->bufflen == 0) return;
    701 
    702   if (e->index == e->bufflen)
    703     owl_editwin_point_move(e, -1);     /* point is after last character */
    704 
    705   if (owl_editwin_at_beginning_of_buffer(e))
    706     return;     /* point is at beginning of buffer, do nothing */
     537 
     538  /* get the cursor point */
     539  z = _owl_editwin_get_index_from_xy(e);
     540
     541  if (z == e->bufflen) {
     542    /* point is after last character */
     543    z--;
     544  } 
     545
     546  if (z - 1 < e->lock) {
     547    /* point is at beginning of buffer, do nothing */
     548    return;
     549  }
    707550
    708551  /* Transpose two utf-8 unicode glyphs. */
    709   middle = e->buff + e->index;
    710 
    711   end = oe_next_point(e, middle);
    712   if (end == NULL)
    713     return;
    714 
    715   start = oe_prev_point(e, middle);
    716   if (start == NULL)
    717     return;
    718 
    719   tmp = owl_malloc((end - start) + 1);
    720   tmp[(end - start)] = 0;
    721   memcpy(tmp, middle, end - middle);
    722   memcpy(tmp + (end - middle), start, middle - start);
    723 
    724   owl_editwin_point_move(e, -1);
    725   owl_editwin_replace(e, 2, tmp);
     552  p1 = e->buff + z;
     553
     554  p2 = g_utf8_find_next_char(p1, NULL);
     555  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
     556    p2 = g_utf8_find_next_char(p2, NULL);
     557  }
     558  if (p2 == NULL) return;
     559
     560  p3 = g_utf8_find_prev_char(e->buff, p1);
     561  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
     562    p3 = g_utf8_find_prev_char(p3, NULL);
     563  }
     564  if (p3 == NULL) return;
     565
     566  tmp = owl_malloc(p2 - p3 + 5);
     567  *tmp = '\0';
     568  strncat(tmp, p1, p2 - p1);
     569  strncat(tmp, p3, p1 - p3);
     570  strncpy(p3, tmp, p2 - p3);
     571  owl_free(tmp);
     572  _owl_editwin_set_xy_by_index(e, p3 - e->buff);
    726573}
    727574
     
    729576 * right
    730577 */
    731 void owl_editwin_insert_string(owl_editwin *e, char *s)
    732 {
    733   owl_editwin_replace(e, 0, s);
    734 }
    735 
    736 /* We assume index is not set to point to a mid-char */
    737 static gunichar owl_editwin_get_char_at_point(owl_editwin *e)
    738 {
    739   return g_utf8_get_char(e->buff + e->index);
    740 }
    741 
    742 void owl_editwin_exchange_point_and_mark(owl_editwin *e) {
    743   int tmp;
    744 
    745   if (e->mark != -1) {
    746     tmp = e->mark;
    747     owl_editwin_set_mark(e);
    748     oe_set_index(e, tmp);
    749   }
    750 }
    751 
    752 int owl_editwin_point_move(owl_editwin *e, int delta)
     578void owl_editwin_insert_string(owl_editwin *e, char *string)
    753579{
    754580  char *p;
    755   int change, d = 0;
    756 
    757   change = MAX(delta, - delta);
    758   p = e->buff + e->index;
    759 
    760   while (d < change && p != NULL) {
    761     if (delta > 0)
    762       p = oe_next_point(e, p);
    763     else
    764       p = oe_prev_point(e, p);
    765     if (p != NULL) {
    766       oe_set_index(e, p - e->buff);
    767       d++;
    768     }
    769   }
    770 
    771   return delta > 0 ? d : -d;
    772 }
    773 
    774 int owl_editwin_at_beginning_of_buffer(owl_editwin *e) {
    775   if (e->index == e->lock)
    776     return 1;
    777 
    778   return 0;
    779 }
    780 
    781 int owl_at_end_of_buffer(owl_editwin *e) {
    782   if (e->index == e->bufflen)
    783     return 1;
    784 
    785   return 0;
    786 }
    787 
    788 int owl_editwin_at_beginning_of_line(owl_editwin *e) /*noproto*/
    789 {
    790   oe_excursion x;
    791   int ret;
    792 
    793   if (owl_editwin_at_beginning_of_buffer(e))
    794     return 1;
    795 
    796   oe_save_excursion(e, &x);
    797   owl_editwin_point_move(e, -1);
    798   ret = (owl_editwin_get_char_at_point(e) == '\n');
    799   oe_restore_excursion(e, &x);
    800 
    801   return ret;
    802 }
    803 
    804 static int owl_editwin_is_char_in(owl_editwin *e, char *set)
     581  gunichar c;
     582  if (!g_utf8_validate(string, -1, NULL)) {
     583    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
     584    return;
     585  }
     586  p = string;
     587  c = g_utf8_get_char(p);
     588  while (c) {
     589    _owl_editwin_process_char(e, c);
     590    p = g_utf8_next_char(p);
     591    c = g_utf8_get_char(p);
     592  }
     593}
     594
     595/* write 'string' at the current point, overwriting text that is
     596 * already there
     597 */
     598
     599void owl_editwin_overwrite_string(owl_editwin *e, char *string)
    805600{
    806601  char *p;
    807 
    808   for (p = set; *p != 0; p = g_utf8_find_next_char(p, NULL))
    809     if (owl_editwin_get_char_at_point(e) == g_utf8_get_char(p))
    810       return 1;
    811   return 0;
    812 }
    813 
    814 int owl_editwin_move_if_in(owl_editwin *e, int delta, char *set)
    815 {
    816   int change, distance = 0;
    817   while (owl_editwin_is_char_in(e, set)) {
    818     change = owl_editwin_point_move(e, delta);
    819     distance += change;
    820     if (change == 0)
     602  gunichar c;
     603
     604  if (!g_utf8_validate(string, -1, NULL)) {
     605    owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
     606    return;
     607  }
     608  p = string;
     609  c = g_utf8_get_char(p);
     610  while (c) {
     611    owl_editwin_overwrite_char(e, c);
     612    p = g_utf8_next_char(p);
     613    c = g_utf8_get_char(p);
     614  }
     615}
     616
     617/* get the index into e->buff for the current cursor
     618 * position.
     619 */
     620int _owl_editwin_get_index_from_xy(owl_editwin *e)
     621{
     622  int i;
     623  char *ptr1, *ptr2;
     624  gunichar c;
     625
     626  if (e->bufflen == 0) return(0);
     627 
     628  /* first go to the yth line */
     629  ptr1 = e->buff;
     630  for (i = 0; i < e->buffy; i++) {
     631    ptr2= strchr(ptr1, '\n');
     632    if (!ptr2) {
     633      /* we're already on the last line */
    821634      break;
    822   }
    823   return distance;
    824 }
    825 
    826 int owl_editwin_move_if_not_in(owl_editwin *e, int delta, char *set)
    827 {
    828   int change, distance = 0;
    829   while (!owl_editwin_is_char_in(e, set)) {
    830     change = owl_editwin_point_move(e, delta);
    831     distance += change;
    832     if (change == 0)
    833       break;
    834   }
    835   return distance;
    836 }
    837 
    838 int owl_editwin_move_to_beginning_of_line(owl_editwin *e)
    839 {
    840   int distance = 0;
    841 
    842   if (!owl_editwin_at_beginning_of_line(e)) {
    843     /* move off the \n if were at the end of a line */
    844     distance += owl_editwin_point_move(e, -1);
    845     distance += owl_editwin_move_if_not_in(e, -1, "\n");
    846     if (distance && !owl_editwin_at_beginning_of_buffer(e))
    847       distance += owl_editwin_point_move(e, 1);
    848   }
    849   e->goal_column = 0; /* subtleties */
    850 
    851   return distance;
    852 }
    853 
    854 int owl_editwin_move_to_end_of_line(owl_editwin *e)
    855 {
    856   return owl_editwin_move_if_not_in(e, 1, "\n");
    857 }
    858 
    859 int owl_editwin_line_move(owl_editwin *e, int delta)
    860 {
    861   int goal_column, change, ll, distance;
    862   int count = 0;
    863 
    864   change = MAX(delta, -delta);
    865 
    866   goal_column = e->goal_column;
    867   distance = owl_editwin_move_to_beginning_of_line(e);
    868   goal_column = goal_column == -1 ? -distance : goal_column;
    869 
    870   while(count < change) {
    871     if (delta > 0) {
    872       distance += owl_editwin_move_if_not_in(e, 1, "\n");
    873       distance += owl_editwin_point_move(e, 1);
    874     } else {
    875       /* I really want to assert delta < 0 here */
    876       distance += owl_editwin_point_move(e, -1); /* to the newline on
    877                                                     the previous line */
    878       distance += owl_editwin_move_to_beginning_of_line(e);
    879     }
    880     count++;
    881   }
    882 
    883   distance += (ll = owl_editwin_move_to_end_of_line(e));
    884   if (ll > goal_column)
    885     distance += owl_editwin_point_move(e, goal_column - ll);
    886 
    887   e->goal_column = goal_column;
    888 
    889   return distance;
     635    }
     636    ptr1 = ptr2 + 1;
     637  }
     638
     639  /* now go to the xth cell */
     640  ptr2 = ptr1;
     641  i = 0;
     642  while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
     643    c = g_utf8_get_char(ptr2);
     644    i += (c == '\n' ? 1 : mk_wcwidth(c));
     645    ptr2 = g_utf8_next_char(ptr2);
     646  }
     647  while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
     648    ptr2 = g_utf8_next_char(ptr2);
     649  }
     650  if (ptr2 == NULL) return e->bufflen;
     651  return(ptr2 - e->buff);
     652}
     653
     654/* We assume x,y are not set to point to a mid-char */
     655gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
     656{
     657  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
     658}
     659
     660
     661void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
     662{
     663  char *ptr1, *ptr2, *target;
     664  gunichar c;
     665
     666  e->buffx = 0;
     667  e->buffy = 0;
     668
     669  ptr1 = e->buff;
     670  target = ptr1 + index;
     671  /* target sanitizing */
     672  if ((target[0] & 0x80) && (~target[0] & 0x40)) {
     673    /* middle of a utf-8 character, back up to previous character. */
     674    target = g_utf8_find_prev_char(e->buff, target);
     675  }
     676  c = g_utf8_get_char(target);
     677  while (g_unichar_ismark(c) && target > e->buff) {
     678    /* Adjust the target off of combining characters and the like. */
     679    target = g_utf8_find_prev_char(e->buff, target);
     680    c = g_utf8_get_char(target);
     681  }
     682  /* If we start with a mark, something is wrong.*/
     683  if (g_unichar_ismark(c)) return;
     684
     685  /* Now our target should be acceptable. */
     686  ptr2 = strchr(ptr1, '\n');
     687  while (ptr2 != NULL && ptr2 < target) {
     688    e->buffy++;
     689    ptr1 = ptr2 + 1;
     690    ptr2 = strchr(ptr1, '\n');
     691  }
     692  ptr2 = ptr1;
     693  while (ptr2 != NULL && ptr2 < target) {
     694    c = g_utf8_get_char(ptr2);
     695    e->buffx += mk_wcwidth(c);
     696    ptr2 = g_utf8_next_char(ptr2);
     697  }
     698}
     699
     700int _owl_editwin_cursor_adjustment(owl_editwin *e)
     701{
     702  char *ptr1, *ptr2;
     703  gunichar c;
     704  int x, i;
     705
     706  /* Find line */
     707  ptr1 = e->buff;
     708  ptr2 = strchr(ptr1, '\n');
     709  for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
     710    ptr1 = ptr2 + 1;
     711    ptr2 = strchr(ptr1, '\n');
     712  }
     713  ptr2 = ptr1;
     714
     715  /* Find char */
     716  x = 0;
     717  while (ptr2 != NULL && x < e->buffx) {
     718    if (*ptr2 == '\n') return 0;
     719    c = g_utf8_get_char(ptr2);
     720    x += mk_wcwidth(c);
     721    ptr2 = g_utf8_next_char(ptr2);
     722  }
     723 
     724  /* calculate x offset */
     725  return x - e->buffx;
     726}
     727
     728void owl_editwin_adjust_for_locktext(owl_editwin *e)
     729{
     730  /* if we happen to have the cursor over locked text
     731   * move it to be out of the locktext region */
     732  if (_owl_editwin_get_index_from_xy(e) < e->lock) {
     733    _owl_editwin_set_xy_by_index(e, e->lock);
     734  }
    890735}
    891736
     
    895740   * and shift later chars left
    896741   */
    897   if(owl_editwin_point_move(e, -1))
     742  if (_owl_editwin_get_index_from_xy(e) > e->lock) {
     743    owl_editwin_key_left(e);
    898744    owl_editwin_delete_char(e);
     745  }
     746  owl_editwin_adjust_for_locktext(e);
    899747}
    900748
    901749void owl_editwin_key_up(owl_editwin *e)
    902750{
    903   owl_editwin_line_move(e, -1);
     751  if (e->buffy > 0) e->buffy--;
     752  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     753    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
     754  }
     755
     756  /* do we need to scroll? */
     757  if (e->buffy-e->topline < 0) {
     758    e->topline-=e->winlines/2;
     759  }
     760
     761  owl_editwin_adjust_for_locktext(e);
    904762}
    905763
    906764void owl_editwin_key_down(owl_editwin *e)
    907765{
    908   owl_editwin_line_move(e, 1);
     766  /* move down if we can */
     767  if (e->buffy+1 < owl_editwin_get_numlines(e)) e->buffy++;
     768
     769  /* if we're past the last character move back */
     770  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
     771    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
     772  }
     773
     774  /* do we need to scroll? */
     775  if (e->buffy-e->topline > e->winlines) {
     776    e->topline+=e->winlines/2;
     777  }
     778
     779  /* adjust for locktext */
     780  owl_editwin_adjust_for_locktext(e);
    909781}
    910782
    911783void owl_editwin_key_left(owl_editwin *e)
    912784{
    913   owl_editwin_point_move(e, -1);
     785  int i;
     786  char * p;
     787  i = _owl_editwin_get_index_from_xy(e);
     788  p = e->buff + i;
     789  p = g_utf8_find_prev_char(e->buff, p);
     790  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     791    p = g_utf8_find_prev_char(e->buff, p);
     792  }
     793  if (p == NULL) p = e->buff;
     794  _owl_editwin_set_xy_by_index(e, p - e->buff);
     795
     796  if (e->buffy - e->topline < 0) {
     797    e->topline -= e->winlines / 2;
     798  }
     799
     800  /* make sure to avoid locktext */
     801  owl_editwin_adjust_for_locktext(e);
    914802}
    915803
    916804void owl_editwin_key_right(owl_editwin *e)
    917805{
    918   owl_editwin_point_move(e, 1);
    919 }
    920 
    921 int owl_editwin_forward_word(owl_editwin *e)
    922 {
    923   int distance;
     806  int i;
     807  char * p;
     808  i = _owl_editwin_get_index_from_xy(e);
     809  p = e->buff + i;
     810  p = g_utf8_find_next_char(p, NULL);
     811  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
     812    p = g_utf8_find_next_char(p, NULL);
     813  }
     814  if (p == NULL) {
     815    _owl_editwin_set_xy_by_index(e, e->bufflen);
     816  }
     817  else {
     818    _owl_editwin_set_xy_by_index(e, p - e->buff);
     819  }
     820
     821  /* do we need to scroll down? */
     822  if (e->buffy - e->topline >= e->winlines) {
     823    e->topline += e->winlines / 2;
     824  }
     825}
     826
     827void owl_editwin_move_to_nextword(owl_editwin *e)
     828{
     829  int i, x;
     830  gunichar c = '\0';
     831
    924832  /* if we're starting on a space, find the first non-space */
    925   distance = owl_editwin_move_if_in(e, 1, WHITESPACE);
    926 
    927   /* now find the end of this word */
    928   distance += owl_editwin_move_if_not_in(e, 1, WHITESPACE);
    929 
    930   return distance;
    931 }
    932 
    933 void owl_editwin_move_to_nextword(owl_editwin *e)
    934 {
    935   owl_editwin_forward_word(e);
     833  i=_owl_editwin_get_index_from_xy(e);
     834  if (e->buff[i]==' ') {
     835    for (x=i; x<e->bufflen; x++) {
     836      if (e->buff[x]!=' ' && e->buff[x]!='\n') {
     837        _owl_editwin_set_xy_by_index(e, x);
     838        break;
     839      }
     840    }
     841  }
     842
     843  /* find the next space, newline or end of line and go
     844     there, if already at the end of the line, continue on to the next */
     845  i=owl_editwin_get_numcells_on_line(e, e->buffy);
     846  c = _owl_editwin_get_char_at_xy(e);
     847  if (e->buffx < i) {
     848    /* move right till end of line */
     849    while (e->buffx < i) {
     850      owl_editwin_key_right(e);
     851      c = _owl_editwin_get_char_at_xy(e);
     852      if (c == ' ') return;
     853      if (e->buffx == i) return;
     854    }
     855  } else if (e->buffx == i) {
     856    /* try to move down */
     857    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
     858      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
     859        e->buffx=0;
     860        e->buffy++;
     861        owl_editwin_move_to_nextword(e);
     862      }
     863    }
     864  }
    936865}
    937866
    938867/* go backwards to the last non-space character
    939868 */
    940 int owl_editwin_backward_word(owl_editwin *e)
    941 {
    942   oe_excursion x;
    943   int distance = 0;
    944   int further = 0;
    945   int beginning;
    946   /* if in middle of word, beginning of word */
    947 
    948   /* if at beginning of a word, find beginning of previous word */
    949 
    950   if (owl_editwin_is_char_in(e, WHITESPACE)) {
    951     /* if in whitespace past end of word, find a word , the find the beginning*/
    952     distance += owl_editwin_move_if_in(e, -1, WHITESPACE); /* leaves us on the last
    953                                                               character of the word */
    954     oe_save_excursion(e, &x);
    955     /* are we at the beginning of a word? */
    956     owl_editwin_point_move(e, -1);
    957     beginning = owl_editwin_is_char_in(e, WHITESPACE);
    958     oe_restore_excursion(e, &x);
    959     if (beginning)
    960       return distance;
    961    } else {
    962     /* in the middle of the word; */
    963     oe_save_excursion(e, &x);
    964     further += owl_editwin_point_move(e, -1);
    965     if (owl_editwin_is_char_in(e, WHITESPACE)) { /* we were at the beginning */
    966       distance += owl_editwin_backward_word(e); /* previous case */
    967       oe_release_excursion(e, &x);
    968       return distance + further;
     869void owl_editwin_move_to_previousword(owl_editwin *e)
     870{
     871  int i;
     872  gunichar c;
     873  char *ptr1, *ptr2;
     874
     875  /* are we already at the beginning of the word? */
     876  c = _owl_editwin_get_char_at_xy(e);
     877  i = _owl_editwin_get_index_from_xy(e);
     878  ptr1 = e->buff + i;
     879  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
     880    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
     881    c = g_utf8_get_char(ptr1);
     882    if (c == ' ' || c == '\n') {
     883      owl_editwin_key_left(e);     
     884    }
     885  }
     886
     887  /* are we starting on a space character? */
     888  i = _owl_editwin_get_index_from_xy(e);
     889  while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
     890    /* find the first non-space */
     891    owl_editwin_key_left(e);     
     892    i = _owl_editwin_get_index_from_xy(e);
     893  }
     894
     895  /* find the last non-space */
     896  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     897  while (ptr1 >= e->buff + e->lock) {
     898    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
     899    if (!ptr2) break;
     900   
     901    c = g_utf8_get_char(ptr2);
     902    if (c == ' ' || c == '\n'){
     903      break;
     904    }
     905    owl_editwin_key_left(e);
     906    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     907  }
     908}
     909
     910
     911void owl_editwin_delete_nextword(owl_editwin *e)
     912{
     913  char *ptr1, *start;
     914  gunichar c;
     915
     916  if (e->bufflen==0) return;
     917
     918  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
     919  /* if we start out on a space character then jump past all the
     920     spaces up first */
     921  while (*ptr1 == ' ' || *ptr1 == '\n') {
     922    ++ptr1;
     923  }
     924
     925  /* then jump past the next word */
     926 
     927  while (ptr1 && ptr1 - e->buff < e->bufflen) {
     928    c = g_utf8_get_char(ptr1);
     929    if (c == ' ' || c == '\n' || c == '\0') break;
     930    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     931  }
     932
     933  if (ptr1) { /* We broke on a space, */
     934    ptr1 = g_utf8_find_next_char(ptr1, NULL);
     935    if (ptr1) { /* and there's a character after it, */
     936      /* nuke everything back to our starting point. */
     937      _owl_editwin_remove_bytes(e, ptr1 - start);
     938      return;
     939    }
     940  }
     941 
     942  /* If we get here, we ran out of string, drop what's left. */
     943  *start = '\0';
     944  e->bufflen = start - e->buff;
     945}
     946
     947void owl_editwin_delete_previousword(owl_editwin *e)
     948{
     949  /* go backwards to the last non-space character, then delete chars */
     950  int startpos, endpos;
     951
     952  startpos = _owl_editwin_get_index_from_xy(e);
     953  owl_editwin_move_to_previousword(e);
     954  endpos = _owl_editwin_get_index_from_xy(e);
     955  _owl_editwin_remove_bytes(e, startpos-endpos);
     956}
     957
     958void owl_editwin_delete_to_endofline(owl_editwin *e)
     959{
     960  int i;
     961
     962  if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
     963    /* normal line */
     964    i=_owl_editwin_get_index_from_xy(e);
     965    while(i < e->bufflen) {
     966      if (e->buff[i]!='\n') {
     967        owl_editwin_delete_char(e);
     968      } else if ((e->buff[i]=='\n') && (i==e->bufflen-1)) {
     969        owl_editwin_delete_char(e);
     970      } else {
     971        return;
     972      }
     973    }
     974  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) {
     975    /* line with cursor at the end but not on very last line */
     976    owl_editwin_key_right(e);
     977    owl_editwin_backspace(e);
     978  }
     979}
     980
     981void owl_editwin_move_to_line_end(owl_editwin *e)
     982{
     983  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
     984}
     985
     986void owl_editwin_move_to_line_start(owl_editwin *e)
     987{
     988  e->buffx=0;
     989  owl_editwin_adjust_for_locktext(e);
     990}
     991
     992void owl_editwin_move_to_end(owl_editwin *e)
     993{
     994  /* go to last char */
     995  e->buffy=owl_editwin_get_numlines(e)-1;
     996  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
     997  owl_editwin_key_right(e);
     998
     999  /* do we need to scroll? */
     1000  /*
     1001  if (e->buffy-e->topline > e->winlines) {
     1002    e->topline+=e->winlines/2;
     1003  }
     1004  */
     1005  owl_editwin_recenter(e);
     1006}
     1007
     1008void owl_editwin_move_to_top(owl_editwin *e)
     1009{
     1010  _owl_editwin_set_xy_by_index(e, 0);
     1011
     1012  /* do we need to scroll? */
     1013  e->topline=0;
     1014
     1015  owl_editwin_adjust_for_locktext(e);
     1016}
     1017
     1018void owl_editwin_fill_paragraph(owl_editwin *e)
     1019{
     1020  int i, save;
     1021
     1022  /* save our starting point */
     1023  save=_owl_editwin_get_index_from_xy(e);
     1024
     1025  /* scan back to the beginning of this paragraph */
     1026  for (i=save; i>=e->lock; i--) {
     1027    if ( (i<=e->lock) ||
     1028         ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
     1029      _owl_editwin_set_xy_by_index(e, i+1);
     1030      break;
     1031    }
     1032  }
     1033
     1034  /* main loop */
     1035  while (1) {
     1036    i = _owl_editwin_get_index_from_xy(e);
     1037
     1038    /* bail if we hit the end of the buffer */
     1039    if (i >= e->bufflen || e->buff[i] == '\0') break;
     1040
     1041    /* bail if we hit the end of the paragraph */
     1042    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
     1043
     1044    /* bail if we hit a trailing dot on the buffer */
     1045    if (e->buff[i] == '\n' && e->buff[i+1] == '.'
     1046        && ((i+2) >= e->bufflen || e->buff[i+2] == '\0'))
     1047      break;
     1048
     1049    /* if we've travelled too far, linewrap */
     1050    if ((e->buffx) >= e->fillcol) {
     1051      int len = e->bufflen;
     1052      _owl_editwin_linewrap_word(e);
     1053      /* we may have added a character. */
     1054      if (i < save) save += e->bufflen - len;
     1055      _owl_editwin_set_xy_by_index(e, i);
     1056    }
     1057
     1058    /* did we hit the end of a line too soon? */
     1059    /* asedeno: Here we replace a newline with a space. We may want to
     1060       consider removing the space if the characters to either side
     1061       are CJK ideograms.*/
     1062    i = _owl_editwin_get_index_from_xy(e);
     1063    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
     1064      /* ********* we need to make sure we don't pull in a word that's too long ***********/
     1065      e->buff[i]=' ';
     1066    }
     1067
     1068    /* fix spacing */
     1069    i = _owl_editwin_get_index_from_xy(e);
     1070    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
     1071      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
     1072        owl_editwin_key_right(e);
     1073      } else {
     1074        owl_editwin_delete_char(e);
     1075        /* if we did this ahead of the save point, adjust it. Changing
     1076           by one is fine here because we're only removing an ASCII
     1077           space. */
     1078        if (i < save) save--;
     1079      }
    9691080    } else {
    970       oe_restore_excursion(e, &x);
    971     }
    972   }
    973   distance += owl_editwin_move_if_not_in(e, -1, WHITESPACE);
    974   /* will go past */
    975   if (e->index > e->lock)
    976     distance += owl_editwin_point_move(e, 1);
    977   return distance;
    978 }
    979 
    980 void owl_editwin_move_to_previousword(owl_editwin *e)
    981 {
    982   owl_editwin_backward_word(e);
    983 }
    984 
    985 void owl_editwin_delete_nextword(owl_editwin *e)
    986 {
    987   oe_excursion x;
    988 
    989   oe_save_excursion(e, &x);
    990   oe_set_mark(e, e->index);
    991   owl_editwin_forward_word(e);
    992   owl_editwin_kill_region(e);
    993   oe_restore_mark_only(e, &x);
    994 }
    995 
    996 void owl_editwin_delete_previousword(owl_editwin *e)
    997 {
    998   oe_excursion x;
    999 
    1000   oe_save_excursion(e, &x);
    1001   oe_set_mark(e, e->index);
    1002   owl_editwin_backward_word(e);
    1003   owl_editwin_kill_region(e);
    1004   oe_restore_mark_only(e, &x);
    1005 }
    1006 
    1007 void owl_editwin_move_to_line_end(owl_editwin *e)
    1008 {
    1009   owl_editwin_move_to_end_of_line(e);
    1010 }
    1011 
    1012 void owl_editwin_delete_to_endofline(owl_editwin *e)
    1013 {
    1014   oe_excursion x;
    1015   int distance;
    1016 
    1017   oe_save_excursion(e, &x);
    1018   owl_editwin_set_mark(e);
    1019   distance = owl_editwin_move_to_end_of_line(e);
    1020   if (distance)
    1021     owl_editwin_kill_region(e);
    1022   else
    1023     owl_editwin_replace(e, 1, "");
    1024   oe_restore_excursion(e, &x);
    1025 }
    1026 
    1027 void owl_editwin_yank(owl_editwin *e)
    1028 {
    1029   if (e->killbuf != NULL)
    1030     owl_editwin_replace(e, 0, e->killbuf);
    1031 }
    1032 
    1033 static char *oe_copy_buf(owl_editwin *e, char *buf, int len)
    1034 {
    1035   char *p;
    1036 
    1037   p = owl_malloc(len + 1);
    1038 
    1039   if (p != NULL) {
    1040     owl_free(e->killbuf);
    1041     e->killbuf = p;
    1042     memcpy(e->killbuf, buf, len);
    1043     e->killbuf[len] = 0;
    1044   }
    1045 
    1046   return p;
    1047 }
    1048 
    1049 static int oe_copy_region(owl_editwin *e)
    1050 {
    1051   char *p;
    1052   int start, end;
    1053 
    1054   if (e->mark == -1)
    1055     return 0;
    1056 
    1057   start = MIN(e->index, e->mark);
    1058   end = MAX(e->index, e->mark);
    1059 
    1060   p = oe_copy_buf(e, e->buff + start, end - start);
    1061   if (p != NULL)
    1062     return end - start;
    1063   return 0;
    1064 }
    1065 
    1066 void owl_editwin_copy_region_as_kill(owl_editwin *e)
    1067 {
    1068   oe_copy_region(e);
    1069 }
    1070 
    1071 void owl_editwin_kill_region(owl_editwin *e)
    1072 {
    1073   if (e->index > e->mark)
    1074     owl_editwin_exchange_point_and_mark(e);
    1075 
    1076   owl_editwin_replace(e, oe_copy_region(e), "");
    1077 }
    1078 
    1079 void owl_editwin_move_to_line_start(owl_editwin *e)
    1080 {
    1081   owl_editwin_move_to_beginning_of_line(e);
    1082 }
    1083 
    1084 void owl_editwin_move_to_end(owl_editwin *e)
    1085 {
    1086   oe_set_index(e, e->bufflen);
    1087 }
    1088 
    1089 void owl_editwin_move_to_top(owl_editwin *e)
    1090 {
    1091   oe_set_index(e, e->lock);
    1092 }
    1093 
    1094 void owl_editwin_backward_paragraph(owl_editwin *e)
    1095 {
    1096   owl_editwin_point_move(e, -1);
    1097   for (; e->index >= e->lock; owl_editwin_point_move(e, -1)) {
    1098     if (e->index <= e->lock ||
    1099         ((e->buff[e->index] == '\n') && (e->buff[e->index - 1]=='\n')))
    1100       break;
    1101   }
    1102 }
    1103 
    1104 void owl_editwin_forward_paragraph(owl_editwin *e)
    1105 {
    1106   owl_editwin_point_move(e, 1);
    1107   /* scan forward to the start of the next paragraph */
    1108   for(; e->index < e->bufflen; owl_editwin_point_move(e, 1)) {
    1109     if (e->buff[e->index -1] == '\n' && e->buff[e->index] == '\n')
    1110       break;
    1111   }
    1112 }
    1113 
    1114 int owl_editwin_current_column(owl_editwin *e)
    1115 {
    1116   oe_excursion x;
    1117   int lineindex;
    1118 
    1119   oe_save_excursion(e, &x);
    1120   owl_editwin_move_to_beginning_of_line(e);
    1121   lineindex = e->index;
    1122   oe_restore_excursion(e, &x);
    1123   return oe_region_width(e, lineindex, e->index, 0);
    1124 }
    1125 
    1126 void owl_editwin_fill_paragraph(owl_editwin *e)
    1127 {
    1128   oe_excursion x;
    1129   gunichar ch;
    1130   int sentence;
    1131 
    1132   oe_save_excursion(e, &x);
    1133 
    1134   /* Mark the end of the paragraph */
    1135   owl_editwin_forward_paragraph(e);
    1136   /* Skip the trailing newline */
    1137   owl_editwin_point_move(e, -1);
    1138   owl_editwin_set_mark(e);
    1139 
    1140   owl_editwin_backward_paragraph(e);
    1141 
    1142   /* Don't mess with the leading newline */
    1143   if (owl_editwin_get_char_at_point(e) == '\n')
    1144     owl_editwin_point_move(e, 1);
    1145 
    1146   /*
    1147    * First pass: Scan forward replacing all series of spaces with ' '
    1148    * (or nothing after CJK ideograms)
    1149    */
    1150   sentence = 0;
    1151   for(;e->index < e->mark; owl_editwin_point_move(e, 1)) {
    1152     /* bail if we hit a trailing dot on the buffer */
    1153     if (strcmp(e->buff + e->index, "\n.") == 0) {
    1154       owl_editwin_set_mark(e);
    1155       break;
    1156     }
    1157 
    1158     ch = owl_editwin_get_char_at_point(e);
    1159 
    1160     if (owl_util_can_break_after(ch) || ch == '\n') {
    1161       if (g_unichar_isspace(ch)) {
    1162         owl_editwin_replace(e, 1, " ");
    1163       }
    1164 
    1165       if (sentence && g_unichar_isspace(owl_editwin_get_char_at_point(e)))
    1166         owl_editwin_point_move(e, 1);
    1167 
    1168       while(g_unichar_isspace(owl_editwin_get_char_at_point(e))
    1169             && e->index < e->mark) {
    1170         owl_editwin_delete_char(e);
    1171       }
    1172     }
    1173 
    1174     if(ch == '.' || ch == '!' || ch == '?')
    1175       sentence = 1;
    1176     else
    1177       sentence = 0;
    1178   }
    1179 
    1180   owl_editwin_backward_paragraph(e);
    1181 
    1182   /* Now go through inserting newlines as needed */
    1183   while(e->index < e->mark) {
    1184     /* if we've travelled too far, linewrap */
    1185     if (owl_editwin_current_column(e) >= e->fillcol)
    1186       _owl_editwin_linewrap_word(e);
    1187     owl_editwin_point_move(e, 1);
    1188   }
    1189 
    1190   oe_restore_excursion(e, &x);
     1081      owl_editwin_key_right(e);
     1082    }
     1083  }
     1084
     1085  /* put cursor back at starting point */
     1086  _owl_editwin_set_xy_by_index(e, save);
     1087
     1088  /* do we need to scroll? */
     1089  if (e->buffy-e->topline < 0) {
     1090    e->topline-=e->winlines/2;
     1091  }
    11911092}
    11921093
     
    11941095int owl_editwin_is_at_end(owl_editwin *e)
    11951096{
    1196   return (only_whitespace(e->buff + e->index));
    1197 }
    1198 
    1199 static int owl_editwin_check_dotsend(owl_editwin *e)
    1200 {
    1201   int zdot;
    1202   oe_excursion x;
     1097  int cur=_owl_editwin_get_index_from_xy(e);
     1098  return (only_whitespace(e->buff+cur));
     1099}
     1100
     1101int owl_editwin_check_dotsend(owl_editwin *e)
     1102{
     1103  char *p, *p_n, *p_p;
     1104  gunichar c;
    12031105
    12041106  if (!e->dotsend) return(0);
    1205   if (e->index != e->bufflen) return (0);
    1206 
    1207   oe_save_excursion(e, &x);
    1208 
    1209   owl_editwin_point_move(e, -3);
    1210 
    1211   zdot = (strcmp(e->buff + e->index, "\n.\n") == 0);
    1212 
    1213   oe_restore_excursion(e, &x);
    1214 
    1215   return zdot;
     1107
     1108  p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
     1109  p_n = g_utf8_find_next_char(p, NULL);
     1110  p_p = g_utf8_find_prev_char(e->buff, p);
     1111  c = g_utf8_get_char(p);
     1112  while (p != NULL) {
     1113    if (*p == '.'
     1114        && p_p != NULL && (*p_p == '\n' || *p_p == '\r')
     1115        && p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
     1116      e->bufflen = p - e->buff;
     1117      e->buff[e->bufflen] = '\0';
     1118      return(1);
     1119    }
     1120    if (c != '\0' && !g_unichar_isspace(c)) return(0);
     1121    p_n = p;
     1122    p = p_p;
     1123    c = g_utf8_get_char(p);
     1124    p_p = g_utf8_find_prev_char(e->buff, p);
     1125  }
     1126  return(0);
    12161127}
    12171128
    12181129void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
    12191130{
    1220   /* XXX force a redisplay? */
     1131  /* check if we need to scroll down */
     1132  if (e->buffy-e->topline >= e->winlines) {
     1133    e->topline+=e->winlines/2;
     1134  }
    12211135  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
    12221136    owl_command_editmulti_done(e);
    12231137    return;
    12241138  }
    1225   owl_editwin_redisplay(e, 0);
    1226 }
    1227 
    1228 static int oe_region_width(owl_editwin *e, int start, int end, int offset)
    1229 {
    1230   char *p;
    1231   int width = offset;
     1139  owl_editwin_redisplay(e, 0); 
     1140}
     1141
     1142void _owl_editwin_process_char(owl_editwin *e, gunichar j)
     1143{
     1144  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
     1145    owl_editwin_insert_char(e, j);
     1146  }
     1147}
     1148
     1149
     1150void owl_editwin_process_char(owl_editwin *e, owl_input j)
     1151{
     1152  if (j.ch == ERR) return;
     1153  /* Ignore ncurses control characters. */
     1154  if (j.ch < 0x100) {
     1155    _owl_editwin_process_char(e, j.uch);
     1156  }
     1157}
     1158
     1159char *owl_editwin_get_text(owl_editwin *e)
     1160{
     1161  return(e->buff+e->lock);
     1162}
     1163
     1164int owl_editwin_get_numchars_on_line(owl_editwin *e, int line)
     1165{
     1166  int i;
     1167  char *ptr1, *ptr2;
     1168
     1169  if (e->bufflen==0) return(0);
    12321170 
    1233   for(p = e->buff + start;
    1234       p < e->buff + end;
    1235       p = g_utf8_find_next_char(p, NULL))
    1236     width += oe_char_width(g_utf8_get_char(p), width);
    1237 
    1238   return width - offset;
    1239 }
    1240 
    1241 static void oe_insert_char(owl_editwin *e, gunichar c)
    1242 {
    1243   oe_excursion x;
    1244   char tmp[7];
    1245   int replaced = -1;
    1246 
    1247   if (c == '\r') /* translate CRs to NLs */
    1248     c = '\n';
    1249 
    1250   if (!g_unichar_iscntrl(c) || c == '\n' || c== '\t' ) {
    1251     memset(tmp, 0, 7);
    1252 
    1253     if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
    1254       return;
    1255     }
    1256 
    1257     if (e->cursorx != -1 && e->cursorx + oe_char_width(c, e->cursorx) > e->wrapcol) {
    1258       /* XXX this is actually wrong:
    1259        * + If the line has been been wrapped, we can be past the wrap column but
    1260        *   e->cursorx be much smaller.
    1261        * + If the user went back and inserted a bunch of stuff in the middle of
    1262        *   the line, there may be more than one word past the wrap column.
    1263        */
    1264       oe_save_excursion(e, &x);
    1265 
    1266       if (c == ' ' || c == '\t') {
    1267         owl_editwin_point_move(e, -1);
    1268         replaced = -owl_editwin_move_if_in(e, -1, " \t");
    1269         if (!replaced) {
    1270           c = '\n';
    1271           replaced = -1;
    1272         }
    1273       } else {
    1274         while(!owl_editwin_at_beginning_of_line(e)) {
    1275           owl_editwin_point_move(e, -1);
    1276           if (owl_util_can_break_after(owl_editwin_get_char_at_point(e))) {
    1277             replaced = -owl_editwin_move_if_in(e, -1, " \t");
    1278             break;
    1279           }
    1280         }
    1281         if (owl_editwin_at_beginning_of_line(e))
    1282           replaced = -1;
    1283       }
    1284       if (replaced && !owl_editwin_at_beginning_of_line(e))
    1285         owl_editwin_point_move(e, 1);
    1286       if (replaced >= 0) {
    1287         owl_editwin_replace(e, replaced, "\n");
    1288       }
    1289       oe_restore_excursion(e, &x);
    1290     }
    1291 
    1292     if (replaced >= 0 && (c == ' ' || c == '\t'))
    1293       return; /* our work here is done */
    1294 
    1295     g_unichar_to_utf8(c, tmp);
    1296     owl_editwin_replace(e, 0, tmp);
    1297   }
    1298 }
    1299 
    1300 void owl_editwin_process_char(owl_editwin *e, owl_input j)
    1301 {
    1302   if (j.ch == ERR)
    1303     return;
    1304   /* Ignore ncurses control characters. */
    1305   if (j.ch < 0x100) {
    1306     oe_insert_char(e, j.uch);
    1307   }
    1308 }
    1309 
    1310 char *owl_editwin_get_text(owl_editwin *e)
    1311 {
    1312   return(e->buff+e->lock);
    1313 }
    1314 
    1315 char *owl_editwin_get_region(owl_editwin *e)
    1316 {
    1317   int start, end;
    1318   start = e->index;
    1319   end   = e->mark;
    1320   if(start > end) {
    1321     int tmp = end;
    1322     end = start;
    1323     start = tmp;
    1324   }
    1325 
    1326   return oe_chunk(e, start, end);
    1327 }
    1328 
    1329 int owl_editwin_get_echochar(owl_editwin *e)
    1330 {
    1331   return e->echochar;
    1332 }
    1333 
    1334 static char *oe_chunk(owl_editwin *e, int start, int end)
    1335 {
    1336   char *p;
     1171  /* first go to the yth line */
     1172  ptr1=e->buff;
     1173  for (i=0; i<line; i++) {
     1174    ptr2=strchr(ptr1, '\n');
     1175    if (!ptr2) {
     1176      /* we're already on the last line */
     1177      return(0);
     1178    }
     1179    ptr1=ptr2+1;
     1180  }
     1181
     1182  /* now count characters */
     1183  i = 0;
     1184  ptr2 = ptr1;
     1185  while (ptr2 - e->buff < e->bufflen
     1186         && *ptr2 != '\n') {
     1187    ++i;
     1188    ptr2 = g_utf8_next_char(ptr2);
     1189  }
     1190  return i;
     1191}
     1192
     1193int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
     1194{
     1195  int i;
     1196  char *ptr1, *ptr2;
     1197  gunichar c;
     1198
     1199  if (e->bufflen==0) return(0);
    13371200 
    1338   p = owl_malloc(end - start + 1);
    1339   memcpy(p, e->buff + start, end - start);
    1340   p[end - start] = 0;
    1341 
    1342   return p;
    1343 }
    1344 
    1345 /*
    1346  * The only guarantee made about these values is that comparisons
    1347  * between them, as well as comparison between multiple calls to these
    1348  * functions without modifying the editwin in-between, are meaningful.
    1349  */
    1350 
    1351 int owl_editwin_get_point(owl_editwin *e)
    1352 {
    1353   return e->index;
    1354 }
    1355 
    1356 int owl_editwin_get_mark(owl_editwin *e)
    1357 {
    1358   return e->mark;
    1359 }
    1360 
    1361 
    1362 
    1363 /*
    1364  * Local Variables:
    1365  * mode:C
    1366  * c-basic-offset:2
    1367  * End:
    1368  */
     1201  /* first go to the yth line */
     1202  ptr1=e->buff;
     1203  for (i=0; i<line; i++) {
     1204    ptr2=strchr(ptr1, '\n');
     1205    if (!ptr2) {
     1206      /* we're already on the last line */
     1207      return(0);
     1208    }
     1209    ptr1=ptr2+1;
     1210  }
     1211
     1212  /* now count cells */
     1213  i = 0;
     1214  ptr2 = ptr1;
     1215  while (ptr2 - e->buff < e->bufflen
     1216         && *ptr2 != '\n') {
     1217    c = g_utf8_get_char(ptr2);
     1218    i += mk_wcwidth(c);
     1219    ptr2 = g_utf8_next_char(ptr2);
     1220  }
     1221  return i;
     1222}
     1223
     1224int owl_editwin_get_numlines(owl_editwin *e)
     1225{
     1226  return(owl_text_num_lines(e->buff));
     1227}
     1228
  • functions.c

    re6d989f r8daf504  
    224224
    225225/* Create an outgoing zephyr message and return a pointer to it.  Does
    226  * not put it on the global queue, use owl_global_messagequeue_addmsg() for
     226 * not put it on the global queue, use owl_function_add_message() for
    227227 * that.
    228228 */
     
    246246 * message or NULL if we're not logged into AIM (and thus unable to
    247247 * create the message).  Does not put it on the global queue.  Use
    248  * owl_global_messagequeue_addmsg() for that .
     248 * owl_function_add_message() for that .
    249249 */
    250250owl_message *owl_function_make_outgoing_aim(char *body, char *to)
     
    267267/* Create an outgoing loopback message and return a pointer to it.
    268268 * Does not append it to the global queue, use
    269  * owl_global_messagequeue_addmsg() for that.
     269 * owl_function_add_message() for that.
    270270 */
    271271owl_message *owl_function_make_outgoing_loopback(char *body)
     
    25702570 *
    25712571 * if the curmsg is a personal zephyr return a filter name
    2572  *    to the zephyr conversation with that user.
     2572 *    to the zephyr converstaion with that user.
    25732573 * If the curmsg is a zephyr class message, instance foo, recip *,
    25742574 *    return a filter name to the class, inst.
     
    31083108      ret=owl_zephyr_get_anyone_list(&anyone, filename);
    31093109      if (ret) {
    3110         if (errno == ENOENT) {
    3111           owl_fmtext_append_normal(&fm, " You have not added any zephyr buddies.  Use the\n");
    3112           owl_fmtext_append_normal(&fm, " command ':addbuddy zephyr ");
    3113           owl_fmtext_append_bold(  &fm, "<username>");
    3114           owl_fmtext_append_normal(&fm, "'.\n");
    3115         } else {
    3116           owl_fmtext_append_normal(&fm, " Could not read zephyr buddies from the .anyone file.\n");
    3117         }
     3110        owl_fmtext_append_normal(&fm, "  Error opening file for zephyr buddies.\n");
    31183111      } else {
    31193112        j=owl_list_get_size(&anyone);
     
    36013594  _owl_function_mark_message(m);
    36023595  owl_global_set_curmsg(&g, owl_view_get_nearest_to_msgid(v, marked_id));
    3603   owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
    36043596  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
    36053597  owl_global_set_direction_downwards(&g);
  • global.c

    ra556caa rbd783db  
    4747  g->rightshift=0;
    4848
    49   g->tw = owl_editwin_allocate();
    50   owl_editwin_init(g->tw, NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
     49  owl_editwin_init(&(g->tw), NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
    5150
    5251  owl_keyhandler_init(&g->kh);
     
    148147  g->typwin=newwin(typwin_lines, cols, g->recwinlines+2, 0);
    149148
    150   owl_editwin_set_curswin(g->tw, g->typwin, typwin_lines, g->cols);
     149  owl_editwin_set_curswin(&(g->tw), g->typwin, typwin_lines, g->cols);
    151150
    152151  idlok(g->typwin, FALSE);
     
    262261
    263262owl_editwin *owl_global_get_typwin(owl_global *g) {
    264   return(g->tw);
     263  return(&(g->tw));
    265264}
    266265
     
    479478  owl_mainwin_redisplay(&(g->mw));
    480479  sepbar(NULL);
    481   owl_editwin_redisplay(g->tw, 0);
     480  owl_editwin_redisplay(&(g->tw), 0);
    482481  owl_function_full_redisplay(&g);
    483482
  • help.c

    re6d989f r799b60e  
    5858     "\n"
    5959     "    M-n           View zephyrs in selected conversation\n"
    60      "    M-N           View zephyrs in selected conversation of instance\n"
     60     "    M-N           View zephyrs in selected converstaion of instance\n"
    6161     "    M-p           View only personal zephyrs\n"
    6262     "    V             Change to back to home view ('all' by default)\n"
  • keys.c

    r2fc8397 r4f0a2ee  
    4545  BIND_CMD("M-O 3 C",     "edit:move-next-word", "");
    4646  BIND_CMD("M-RIGHT",     "edit:move-next-word", "");
    47   BIND_CMD("M-[ 1 ; 3 D", "edit:move-next-word", "");
    4847  BIND_CMD("M-b",         "edit:move-prev-word", "");
    4948  BIND_CMD("M-O 3 D",     "edit:move-prev-word", "");
    5049  BIND_CMD("M-LEFT",      "edit:move-prev-word", "");
    51   BIND_CMD("M-[ 1 ; 3 C", "edit:move-next-word", "");
    5250
    5351  BIND_CMD("LEFT",        "edit:move-left", "");
     
    8482  BIND_CMD("M-q",         "edit:fill-paragraph", "");
    8583
    86   BIND_CMD("C-@",         "edit:set-mark", "");
    87   BIND_CMD("C-x C-x",     "edit:exchange-point-and-mark", "");
    88 
    89   BIND_CMD("M-w",         "edit:copy-region-as-kill", "");
    90   BIND_CMD("C-w",         "edit:kill-region", "");
    91   BIND_CMD("C-y",         "edit:yank", "");
    92 
    9384  BIND_CMD("C-l",         "( edit:recenter ; redisplay )", "");
    9485
     
    109100  BIND_CMD("M-[ B",   "editmulti:move-down-line", "");
    110101  BIND_CMD("C-n",     "editmulti:move-down-line", "");
    111 
    112   BIND_CMD("M-}",     "editmulti:forward-paragraph", "");
    113   BIND_CMD("M-{",     "editmulti:backward-paragraph", "");
    114102
    115103  /* This would be nice, but interferes with C-c to cancel */
  • owl.c

    r301c975 r1be5823  
    145145  /* turn ISTRIP off */
    146146  tcgetattr(0, &tio);
    147   tio.c_iflag &= ~(ISTRIP|IEXTEN);
     147  tio.c_iflag &= ~ISTRIP;
    148148  tio.c_cc[VQUIT] = 0;
    149149  tcsetattr(0, TCSAFLUSH, &tio);
  • owl.h

    r37f27bc r37f27bc  
    419419} owl_history;
    420420
    421 typedef struct _owl_editwin owl_editwin;
    422 typedef struct _owl_editwin_excursion owl_editwin_excursion;
     421typedef struct _owl_editwin {
     422  char *buff;
     423  owl_history *hist;
     424  int bufflen;
     425  int allocated;
     426  int buffx, buffy;
     427  int topline;
     428  int winlines, wincols, fillcol, wrapcol;
     429  WINDOW *curswin;
     430  int style;
     431  int lock;
     432  int dotsend;
     433  int echochar;
     434
     435  char *command;
     436  void (*callback)(struct _owl_editwin*);
     437  void *cbdata;
     438} owl_editwin;
    423439
    424440typedef struct _owl_keybinding {
     
    535551  int config_format;
    536552  void *buffercbdata;
    537   owl_editwin *tw;
     553  owl_editwin tw;
    538554  owl_viewwin vw;
    539555  void *perl;
  • perl/lib/BarnOwl.pm

    r22b54a7 rfd8dfe7  
    1818use BarnOwl::Style;
    1919use BarnOwl::Timer;
    20 use BarnOwl::Editwin;
    2120
    2221=head1 NAME
     
    317316}
    318317
    319 =head2 Modify filters by appending text
    320 
    321 =cut
    322 
    323 BarnOwl::new_command("filterappend",
    324     sub { filter_append_helper('appending', '', @_); },
    325     {
    326         summary => "append '<text>' to filter",
    327         usage => "filterappend <filter> <text>",
    328     });
    329 
    330 BarnOwl::new_command("filterand",
    331     sub { filter_append_helper('and-ing', 'and', @_); },
    332     {
    333         summary => "append 'and <text>' to filter",
    334         usage => "filterand <filter> <text>",
    335     });
    336 
    337 BarnOwl::new_command("filteror",
    338     sub { filter_append_helper('or-ing', 'or', @_); },
    339     {
    340         summary => "append 'or <text>' to filter",
    341         usage => "filteror <filter> <text>",
    342     });
    343 
    344 =head3 filter_append_helper ACTION SEP FUNC FILTER APPEND_TEXT
    345 
    346 Helper to append to filters.
    347 
    348 =cut
    349 
    350 sub filter_append_helper
    351 {
    352     my $action = shift;
    353     my $sep = shift;
    354     my $func = shift;
    355     my $filter = shift;
    356     my @append = @_;
    357     my $oldfilter = BarnOwl::getfilter($filter);
    358     chomp $oldfilter;
    359     my $newfilter = join(' ', $oldfilter, $sep, @_);
    360     my $msgtext = "To filter '$filter' $action\n'".join(' ', @append)."' to get\n'$newfilter'";
    361     if (BarnOwl::getvar('showfilterchange') eq 'on') {
    362         BarnOwl::admin_message("Filter", $msgtext);
    363     }
    364     BarnOwl::filter($filter, $newfilter);
    365     return;
    366 }
    367 BarnOwl::new_variable_bool("showfilterchange",
    368                            { default => 1,
    369                              summary => 'Show modifications to filters by filterappend and friends.'});
    370318
    3713191;
  • perl/lib/BarnOwl/Message.pm

    rd1ae4a4 rfd8dfe7  
    2222sub direction   { return shift->{"direction"}; }
    2323sub time        { return shift->{"time"}; }
    24 sub unix_time   { return shift->{"unix_time"}; }
    2524sub id          { return shift->{"id"}; }
    2625sub body        { return shift->{"body"}; }
  • perl/lib/BarnOwl/Message/Zephyr.pm

    r30e7ffd rbc8275e  
    179179
    180180    my $cmd;
    181     if(lc $self->opcode eq 'crypt' and ( not $sender or $self->is_private)) {
    182         # Responses to zcrypted messages should be zcrypted, so long as we
    183         # aren't switching to personals
     181    if(lc $self->opcode eq 'crypt') {
    184182        $cmd = 'zcrypt';
    185183    } else {
  • perl/lib/BarnOwl/Style/Default.pm

    r5550eb0 ree183be  
    33
    44package BarnOwl::Style::Default;
    5 use POSIX qw(strftime);
    6 
    75################################################################################
    86# Branching point for various formatting functions in this style.
     
    4240    my $self = shift;
    4341    my $m = shift;
    44     return strftime('%H:%M', localtime($m->unix_time));
     42    my ($time) = $m->time =~ /(\d\d:\d\d)/;
     43    return $time;
    4544}
    4645
  • perl/modules/IRC/lib/BarnOwl/Module/IRC.pm

    r48f7d12 r1b62a55  
    6060    register_commands();
    6161    register_handlers();
    62     BarnOwl::filter('irc type ^IRC$ or ( type ^admin$ and adminheader ^IRC$ )');
     62    BarnOwl::filter('irc type ^IRC$');
    6363}
    6464
     
    375375    $conn->conn->disconnect;
    376376    delete $ircnets{$conn->alias};
    377     return;
    378377}
    379378
     
    388387        BarnOwl::start_edit_win("/msg -a " . $conn->alias . " $to", sub {process_msg($conn, $to, @_)});
    389388    }
    390     return;
    391389}
    392390
     
    417415       );
    418416    BarnOwl::queue_message($msg);
    419     return;
    420417}
    421418
     
    426423    $target ||= shift;
    427424    $conn->conn->mode($target, @_);
    428     return;
    429425}
    430426
     
    436432    push @{$channels{$chan}}, $conn;
    437433    $conn->conn->join($chan, @_);
    438     return;
    439434}
    440435
     
    445440    $channels{$chan} = [grep {$_ ne $conn} @{$channels{$chan} || []}];
    446441    $conn->conn->part($chan);
    447     return;
    448442}
    449443
     
    453447    my $nick = shift or die("Usage: $cmd <new nick>\n");
    454448    $conn->conn->nick($nick);
    455     return;
    456449}
    457450
     
    462455    $conn->names_tmp([]);
    463456    $conn->conn->names($chan);
    464     return;
    465457}
    466458
     
    470462    my $who = shift || die("Usage: $cmd <user>\n");
    471463    $conn->conn->whois($who);
    472     return;
    473464}
    474465
     
    477468    my $conn = shift;
    478469    $conn->conn->motd;
    479     return;
    480470}
    481471
     
    487477    }
    488478    BarnOwl::popless_ztext($message);
    489     return;
    490479}
    491480
     
    496485    BarnOwl::error("WHO $cmd $conn $who");
    497486    $conn->conn->who($who);
    498     return;
    499487}
    500488
     
    504492    my $type = shift || die("Usage: $cmd <chiklmouy> [server] \n");
    505493    $conn->conn->stats($type, @_);
    506     return;
    507494}
    508495
     
    512499    my $chan = shift;
    513500    $conn->conn->topic($chan, @_ ? join(" ", @_) : undef);
    514     return;
    515501}
    516502
     
    519505    my $conn = shift;
    520506    $conn->conn->sl(join(" ", @_));
    521     return;
    522507}
    523508
  • perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm

    r7c83a32 r32620ac  
    273273        $self->whois_tmp
    274274    );
    275     $self->whois_tmp('');
     275    $self->whois_tmp([]);
    276276}
    277277
  • perlconfig.c

    ra556caa rfd8dfe7  
    8787  }
    8888  (void)hv_store(h, "time", strlen("time"), newSVpv(owl_message_get_timestr(m),0),0);
    89   (void)hv_store(h, "unix_time", strlen("unix_time"), newSViv(m->time), 0);
    9089  (void)hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
    9190  (void)hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
     
    482481void owl_perlconfig_edit_callback(owl_editwin *e)
    483482{
    484   SV *cb = (SV*)owl_editwin_get_cbdata(e);
     483  SV *cb = (SV*)(e->cbdata);
    485484  SV *text;
    486485  dSP;
     
    509508
    510509  SvREFCNT_dec(cb);
    511   owl_editwin_set_cbdata(e, NULL);
     510  e->cbdata = NULL;
    512511}
    513512
  • perlglue.xs

    rc6ecf5c rfd8dfe7  
    429429                owl_function_debugmsg("Freeing timer %p", t);
    430430                                owl_select_remove_timer(t);
    431 
    432 MODULE = BarnOwl                PACKAGE = BarnOwl::Editwin
    433 
    434 int
    435 replace(count, string)
    436         int count;
    437         char *string;
    438         CODE:
    439                 RETVAL = owl_editwin_replace(owl_global_get_typwin(&g), count, string);
    440         OUTPUT:
    441                 RETVAL
    442 
    443 int
    444 point_move(delta)
    445         int delta;
    446         CODE:
    447                 RETVAL = owl_editwin_point_move(owl_global_get_typwin(&g), delta);
    448         OUTPUT:
    449                 RETVAL
    450 
    451 int
    452 replace_region(string)
    453         char *string;
    454         CODE:
    455                 RETVAL = owl_editwin_replace_region(owl_global_get_typwin(&g), string);
    456         OUTPUT:
    457                 RETVAL
    458 
    459 char *
    460 get_region()
    461         PREINIT:
    462                 char *region;
    463         CODE:
    464                 region = owl_editwin_get_region(owl_global_get_typwin(&g));
    465                 RETVAL = region;
    466         OUTPUT:
    467                 RETVAL
    468         CLEANUP:
    469                 owl_free(region);
    470 
    471 SV *
    472 save_excursion(sub)
    473         SV *sub;
    474         PROTOTYPE: &
    475         PREINIT:
    476                 int count;
    477                 owl_editwin_excursion *x;
    478         CODE:
    479         {
    480                 x = owl_editwin_begin_excursion(owl_global_get_typwin(&g));
    481                 count = call_sv(sub, G_SCALAR|G_EVAL|G_NOARGS);
    482                 owl_editwin_end_excursion(owl_global_get_typwin(&g), x);
    483 
    484                 if(SvTRUE(ERRSV)) {
    485                         croak(NULL);
    486                 }
    487 
    488                 SPAGAIN;
    489                 if(count == 1)
    490                         RETVAL = SvREFCNT_inc(POPs);
    491                 else
    492                         XSRETURN_UNDEF;
    493 
    494         }
    495         OUTPUT:
    496                 RETVAL
    497 
    498 int
    499 current_column()
    500         CODE:
    501                 RETVAL = owl_editwin_current_column(owl_global_get_typwin(&g));
    502         OUTPUT:
    503                 RETVAL
    504 
    505 int
    506 point()
    507         CODE:
    508                 RETVAL = owl_editwin_get_point(owl_global_get_typwin(&g));
    509         OUTPUT:
    510                 RETVAL
    511 
    512 int
    513 mark()
    514         CODE:
    515                 RETVAL = owl_editwin_get_mark(owl_global_get_typwin(&g));
    516         OUTPUT:
    517                 RETVAL
  • scripts/locker-build

    rdb98968 rdb98968  
    8888        --prefix="/mit/barnowl/builds/barnowl-$VERS" --mandir=/mit/barnowl/man \
    8989        --program-suffix="-$VERS" \
    90         --with-zephyr --without-stack-protector \
     90        PROTECT_CFLAGS=-fno-stack-protector \
    9191        || die "configure failed"
    9292
  • tester.c

    r3e8ff1e reab5aa1  
    77owl_global g;
    88
    9 #define OWL_UTIL_NTESTS  9
     9#define OWL_UTIL_NTESTS  6
    1010#define OWL_DICT_NTESTS  19
    1111#define OWL_OBARRAY_NTESTS  6
  • text.c

    r3e8ff1e rf34dd65  
    125125
    126126  return(out2);
    127 }
    128 
    129 #define OWL_TAB_WIDTH 8
    130 
    131 /* Caller must free return */
    132 char *owl_text_expand_tabs(char *in)
    133 {
    134   int ntabs = 0;
    135   char *p = in;
    136   char *ret, *out;
    137   int col;
    138 
    139   while(*p) {
    140     if (*(p++) == '\t') ntabs++;
    141   }
    142 
    143   ret = owl_malloc(strlen(in) + 1 + OWL_TAB_WIDTH * ntabs);
    144 
    145   p = in;
    146   out = ret;
    147 
    148   col = 0;
    149   while(*p) {
    150     switch(*p) {
    151     case '\t':
    152       do {*(out++) = ' '; col++; } while (col % OWL_TAB_WIDTH);
    153       break;
    154     case '\n':
    155       col = -1;
    156     default:
    157       col++;
    158       *(out++) = *p;
    159     }
    160     p++;
    161   }
    162 
    163   *out = 0;
    164 
    165   return ret;
    166127}
    167128
  • util.c

    r3e8ff1e r7bf51d5  
    789789              !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
    790790
    791   FAIL_UNLESS("expand_tabs 1",
    792               !strcmp("        hi", owl_text_expand_tabs("\thi")));
    793 
    794   FAIL_UNLESS("expand_tabs 2",
    795               !strcmp("        hi\nword    tab", owl_text_expand_tabs("\thi\nword\ttab")));
    796 
    797   FAIL_UNLESS("expand_tabs 3",
    798               !strcmp("                2 tabs", owl_text_expand_tabs("\t\t2 tabs")));
    799 
    800791  /* if (numfailed) printf("*** WARNING: failures encountered with owl_util\n"); */
    801792  printf("# END testing owl_util (%d failures)\n", numfailed);
  • zwrite.c

    ra52d13a r3ef779b  
    99int owl_zwrite_create_from_line(owl_zwrite *z, char *line)
    1010{
    11   int argc, badargs, myargc, i, len;
     11  int argc, badargs, myargc;
    1212  char **argv, **myargv;
    13   char *msg = NULL;
    1413
    1514  badargs=0;
    1615 
    17   /* start with null entries */
     16  /* start with null entires */
    1817  z->realm=NULL;
    1918  z->class=NULL;
     
    8382        break;
    8483      }
    85       /* we must already have users or a class or an instance */
     84      /* we must already have users or a class or an instance*/
    8685      if (owl_list_get_size(&(z->recips))<1 && (!z->class) && (!z->inst)) {
    8786        badargs=1;
     
    9291      myargv++;
    9392      myargc--;
    94       len = 0;
    95       for (i=0;i<myargc;i++) {
    96         len += strlen(myargv[i-1]) + 1;
    97       }
    98       msg = owl_malloc(len);
    99       msg[0] = '\0';
     93      z->message = owl_strdup("");
    10094      while (myargc) {
    101         strcat(msg, myargv[0]);
    102         strcat(msg, " ");
    103         myargc--;
    104         myargv++;
    105       }
    106       msg[strlen(msg)-1] = '\0';
     95        z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
     96        strcat(z->message, myargv[0]);
     97        strcat(z->message, " ");
     98        myargc--;
     99        myargv++;
     100      }
     101      z->message[strlen(z->message)-1]='\0'; /* remove last space */
    107102      break;
    108103    } else if (!strcmp(myargv[0], "-C")) {
     
    141136  if (z->opcode==NULL) z->opcode=owl_strdup("");
    142137  /* z->message is allowed to stay NULL */
    143 
    144   if(msg) {
    145     owl_zwrite_set_message(z, msg);
    146     owl_free(msg);
    147   }
    148 
     138 
    149139  return(0);
    150140}
     
    232222  int i, j;
    233223  char *toline = NULL;
    234   char *tmp = NULL, *tmp2;
     224  char *tmp = NULL;
    235225
    236226  if (z->message) owl_free(z->message);
     
    250240    }
    251241    tmp = owl_validate_utf8(msg);
    252     tmp2 = owl_text_expand_tabs(tmp);
    253     z->message=owl_sprintf("%s\n%s", toline, tmp2);
     242    z->message=owl_sprintf("%s\n%s", toline, tmp);
    254243    owl_free(toline);
    255     owl_free(tmp);
    256     owl_free(tmp2);
    257244  } else {
    258     tmp=owl_validate_utf8(msg);
    259     z->message=owl_text_expand_tabs(tmp);
    260     owl_free(tmp);
    261   }
     245    z->message=owl_validate_utf8(msg);
     246  }
     247  if (tmp) owl_free(tmp);
    262248}
    263249
Note: See TracChangeset for help on using the changeset viewer.