diff options
Diffstat (limited to 'src/fe-gtk/xtext.c')
-rw-r--r-- | src/fe-gtk/xtext.c | 249 |
1 files changed, 135 insertions, 114 deletions
diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 6a499f52..6692b360 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -31,13 +31,19 @@ #include <stdlib.h> #include <time.h> -#include "../../config.h" +#include "config.h" #include "../common/hexchat.h" #include "../common/fe.h" #include "../common/util.h" #include "../common/hexchatc.h" #include "../common/url.h" + +#ifdef WIN32 +#include "marshal.h" +#else #include "../common/marshal.h" +#endif + #include "fe-gtk.h" #include "xtext.h" #include "fkeys.h" @@ -484,7 +490,10 @@ gtk_xtext_adjustment_set (xtext_buffer *buf, int fire_signal) adj->page_increment = adj->page_size; if (adj->value > adj->upper - adj->page_size) + { + buf->scrollbar_down = TRUE; adj->value = adj->upper - adj->page_size; + } if (adj->value < 0) adj->value = 0; @@ -829,7 +838,6 @@ find_x (GtkXText *xtext, textentry *ent, int x, int subline, int indent) int off, len, wid, mbl, mbw; /* Skip to the first chunk of stuff for the subline */ - list = ent->slp; if (subline > 0) { suboff = GPOINTER_TO_INT (g_slist_nth_data (ent->sublines, subline - 1)); @@ -846,6 +854,8 @@ find_x (GtkXText *xtext, textentry *ent, int x, int subline, int indent) list = ent->slp; } /* Step to the first character of the subline */ + if (list == NULL) + return 0; meta = list->data; off = meta->off; len = meta->len; @@ -934,12 +944,12 @@ gtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline, } static textentry * -gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, - int *out_of_bounds, int *ret_subline) +gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, int *out_of_bounds) { textentry *ent; int line; int subline; + int outofbounds; /* Adjust y value for negative rounding, double to int */ if (y < 0) @@ -948,13 +958,12 @@ gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, line = (y + xtext->pixel_offset) / xtext->fontsize; ent = gtk_xtext_nth (xtext, line + (int)xtext->adj->value, &subline); if (!ent) - return 0; + return NULL; if (off) - *off = gtk_xtext_find_x (xtext, x, ent, subline, line, out_of_bounds); - - if (ret_subline) - *ret_subline = subline; + *off = gtk_xtext_find_x (xtext, x, ent, subline, line, &outofbounds); + if (out_of_bounds) + *out_of_bounds = outofbounds; return ent; } @@ -1049,14 +1058,14 @@ gtk_xtext_paint (GtkWidget *widget, GdkRectangle *area) return; } - ent_start = gtk_xtext_find_char (xtext, area->x, area->y, NULL, NULL, NULL); + ent_start = gtk_xtext_find_char (xtext, area->x, area->y, NULL, NULL); if (!ent_start) { xtext_draw_bg (xtext, area->x, area->y, area->width, area->height); goto xit; } ent_end = gtk_xtext_find_char (xtext, area->x + area->width, - area->y + area->height, NULL, NULL, NULL); + area->y + area->height, NULL, NULL); if (!ent_end) ent_end = xtext->buffer->text_last; @@ -1244,13 +1253,14 @@ lamejump: } } /* marking upward? */ - else if (xtext->buffer->last_ent_end == end_ent && + else if (xtext->buffer->last_ent_start != NULL && + xtext->buffer->last_ent_end == end_ent && xtext->buffer->last_offset_end == end_offset) { ent = end_ent; while (ent) { - if (ent == start_ent) + if (ent == start_ent && xtext->buffer->last_ent_start) { gtk_xtext_selection_up (xtext, xtext->buffer->last_ent_start, ent, start_offset); /*gtk_xtext_render_ents (xtext, xtext->buffer->last_ent_start, ent);*/ @@ -1299,99 +1309,104 @@ gtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event, gboolean ren textentry *ent; textentry *ent_end; textentry *ent_start; - int offset_start; - int offset_end; - int subline_start; - int subline_end; - int oob; - int marking_up = FALSE; - int len_start; - int len_end; + int offset_start = 0; + int offset_end = 0; + textentry *low_ent, *high_ent; + int low_x, low_y, low_offs; + int high_x, high_y, high_offs, high_len; - ent_start = gtk_xtext_find_char (xtext, xtext->select_start_x, xtext->select_start_y, &offset_start, &oob, &subline_start); - ent_end = gtk_xtext_find_char (xtext, xtext->select_end_x, xtext->select_end_y, &offset_end, &oob, &subline_end); + if (xtext->buffer->text_first == NULL) + return; - if ((!ent_start || !ent_end) && !xtext->buffer->text_last && xtext->adj->value != xtext->buffer->old_value) - { - gtk_xtext_render_page (xtext); + ent_start = gtk_xtext_find_char (xtext, xtext->select_start_x, xtext->select_start_y, &offset_start, NULL); + ent_end = gtk_xtext_find_char (xtext, xtext->select_end_x, xtext->select_end_y, &offset_end, NULL); + if (ent_start == NULL && ent_end == NULL) return; - } - if (!ent_start) + if ((ent_start != ent_end && xtext->select_start_y > xtext->select_end_y) || /* different entries */ + (ent_start == ent_end && offset_start > offset_end)) /* same entry, different character offsets */ { - ent_start = xtext->buffer->text_last; - offset_start = ent_start->str_len; + /* marking up */ + low_ent = ent_end; + low_x = xtext->select_end_x; + low_y = xtext->select_end_y; + low_offs = offset_end; + high_ent = ent_start; + high_x = xtext->select_start_x; + high_y = xtext->select_start_y; + high_offs = offset_start; } - - if (!ent_end) + else { - ent_end = xtext->buffer->text_last; - offset_end = ent_end->str_len; + /* marking down */ + low_ent = ent_start; + low_x = xtext->select_start_x; + low_y = xtext->select_start_y; + low_offs = offset_start; + high_ent = ent_end; + high_x = xtext->select_end_x; + high_y = xtext->select_end_y; + high_offs = offset_end; } - - if ((ent_start != ent_end && xtext->select_start_y > xtext->select_end_y) || /* different entries */ - (ent_start == ent_end && subline_start > subline_end) || /* different lines */ - (ent_start == ent_end && subline_start == subline_end && xtext->select_start_x > xtext->select_end_x)) /* marking to the left */ + if (low_ent == NULL) + { + low_ent = xtext->buffer->text_first; + low_offs = 0; + } + if (high_ent == NULL) { - marking_up = TRUE; + high_ent = xtext->buffer->text_last; + high_offs = high_ent->str_len; } /* word selection */ if (xtext->word_select) { /* a word selection cannot be started if the cursor is out of bounds in gtk_xtext_button_press */ - gtk_xtext_get_word (xtext, xtext->select_start_x, xtext->select_start_y, NULL, &offset_start, &len_start, NULL); + gtk_xtext_get_word (xtext, low_x, low_y, NULL, &low_offs, NULL, NULL); /* in case the cursor is out of bounds we keep offset_end from gtk_xtext_find_char and fix the length */ - if (gtk_xtext_get_word (xtext, xtext->select_end_x, xtext->select_end_y, NULL, &offset_end, &len_end, NULL) == NULL) - len_end = offset_end == ent_end->str_len? 0: -1; /* -1 for the space, 0 if at the end */ - - if (!marking_up) - offset_end += len_end; - else - offset_start += len_start; + if (gtk_xtext_get_word (xtext, high_x, high_y, NULL, &high_offs, &high_len, NULL) == NULL) + high_len = high_offs == high_ent->str_len? 0: -1; /* -1 for the space, 0 if at the end */ + high_offs += high_len; + if (low_y < 0) + low_offs = xtext->buffer->last_offset_start; + if (high_y > xtext->buffer->window_height) + high_offs = xtext->buffer->last_offset_end; } /* line/ent selection */ else if (xtext->line_select) { - offset_start = marking_up? ent_start->str_len: 0; - offset_end = marking_up? 0: ent_end->str_len; + low_offs = 0; + high_offs = high_ent->str_len; } - - if (marking_up) + /* character selection */ + else { - int temp; - - /* ensure ent_start is above ent_end */ - if (ent_start != ent_end) - { - ent = ent_start; - ent_start = ent_end; - ent_end = ent; - } - - /* switch offsets as well */ - temp = offset_start; - offset_start = offset_end; - offset_end = temp; + if (low_y < 0) + low_offs = xtext->buffer->last_offset_start; + if (high_y > xtext->buffer->window_height) + high_offs = xtext->buffer->last_offset_end; } /* set all the old mark_ fields to -1 */ gtk_xtext_selection_clear (xtext->buffer); - /* set the default values */ - ent_start->mark_end = ent_start->str_len; - ent_end->mark_start = 0; + low_ent->mark_start = low_offs; + low_ent->mark_end = high_offs; - /* set the calculated values (this overwrites the default values if we're on the same ent) */ - ent_start->mark_start = offset_start; - ent_end->mark_end = offset_end; - - /* set all the mark_ fields of the ents within the selection */ - if (ent_start != ent_end) + if (low_ent != high_ent) { - ent = ent_start->next; - while (ent && ent != ent_end) + low_ent->mark_end = low_ent->str_len; + if (high_offs != 0) + { + high_ent->mark_start = 0; + high_ent->mark_end = high_offs; + } + + /* set all the mark_ fields of the ents within the selection */ + ent = low_ent->next; + while (ent && ent != high_ent) { ent->mark_start = 0; ent->mark_end = ent->str_len; @@ -1400,7 +1415,7 @@ gtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event, gboolean ren } if (render) - gtk_xtext_selection_render (xtext, ent_start, ent_end); + gtk_xtext_selection_render (xtext, low_ent, high_ent); } static int @@ -1532,7 +1547,7 @@ gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent, int out_of_bounds = 0; int len_to_offset = 0; - ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds, NULL); + ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds); if (ent == NULL || out_of_bounds || offset < 0 || offset >= ent->str_len) return NULL; @@ -1585,11 +1600,11 @@ gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent, /* make sure we're not before the start of the match */ if (len_to_offset < start) - return 0; + return NULL; /* and not after it */ if (len_to_offset - start >= end - start) - return 0; + return NULL; } return word; @@ -1646,7 +1661,8 @@ gtk_xtext_check_mark_stamp (GtkXText *xtext, GdkModifierType mask) { gboolean redraw = FALSE; - if (mask & STATE_SHIFT || prefs.hex_text_autocopy_stamp) + if ((mask & STATE_SHIFT || prefs.hex_text_autocopy_stamp) + && (!prefs.hex_stamp_text || prefs.hex_text_indent)) { if (!xtext->mark_stamp) { @@ -1707,7 +1723,7 @@ gtk_xtext_get_word_adjust (GtkXText *xtext, int x, int y, textentry **word_ent, } } } - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return word_type; } @@ -1853,7 +1869,7 @@ gtk_xtext_set_clip_owner (GtkWidget * xtext, GdkEventButton * event) gtk_selection_owner_set (xtext, GDK_SELECTION_SECONDARY, event ? event->time : GDK_CURRENT_TIME); } - free (str); + g_free (str); } } @@ -2107,7 +2123,7 @@ gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret) return NULL; /* now allocate mem and copy buffer */ - pos = txt = malloc (len); + pos = txt = g_malloc (len); ent = buf->last_ent_start; while (ent) { @@ -2147,10 +2163,11 @@ gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret) /*stripped = gtk_xtext_conv_color (txt, strlen (txt), &len);*/ stripped = txt; len = strlen (txt); - } else + } + else { stripped = gtk_xtext_strip_color (txt, strlen (txt), NULL, &len, NULL, FALSE); - free (txt); + g_free (txt); } *len_ret = len; @@ -2205,7 +2222,7 @@ gtk_xtext_selection_get (GtkWidget * widget, g_free (new_text); } - free (stripped); + g_free (stripped); } static gboolean @@ -2360,7 +2377,7 @@ xtext_do_chunk(chunk_t *c) if (c->len1 == 0) return; - meta = malloc (sizeof *meta); + meta = g_new (offlen_t, 1); meta->off = c->off1; meta->len = c->len1; meta->emph = c->emph; @@ -2383,7 +2400,7 @@ gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf, int mbl; /* multi-byte length */ if (outbuf == NULL) - new_str = malloc (len + 2); + new_str = g_malloc (len + 2); else new_str = outbuf; @@ -2459,7 +2476,7 @@ bad_utf8: /* Normal ending sequence, and give up if bad utf8 */ if (slpp) *slpp = c.slp; else - g_slist_free_full (c.slp, free); + g_slist_free_full (c.slp, g_free); return new_str; } @@ -2475,7 +2492,7 @@ gtk_xtext_text_width_ent (GtkXText *xtext, textentry *ent) if (ent->slp) { - g_slist_free_full (ent->slp, free); + g_slist_free_full (ent->slp, g_free); ent->slp = NULL; } @@ -2507,7 +2524,7 @@ gtk_xtext_text_width (GtkXText *xtext, unsigned char *text, int len) &new_len, &slp, !xtext->ignore_hidden); width = backend_get_text_width_slp (xtext, new_buf, slp); - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return width; } @@ -3254,7 +3271,7 @@ gtk_xtext_render_stamp (GtkXText * xtext, textentry * ent, { textentry tmp_ent; int jo, ji, hs; - int xsize, y; + int xsize, y, emphasis; /* trashing ent here, so make a backup first */ memcpy (&tmp_ent, ent, sizeof (tmp_ent)); @@ -3264,7 +3281,7 @@ gtk_xtext_render_stamp (GtkXText * xtext, textentry * ent, xtext->jump_out_offset = 0; xtext->jump_in_offset = 0; xtext->hilight_start = 0xffff; /* temp disable */ - int emphasis = 0; + emphasis = 0; if (xtext->mark_stamp) { @@ -3530,7 +3547,7 @@ gtk_xtext_save (GtkXText * xtext, int fh) &newlen, NULL, FALSE); write (fh, buf, newlen); write (fh, "\n", 1); - free (buf); + g_free (buf); ent = ent->next; } } @@ -3641,7 +3658,7 @@ gtk_xtext_nth (GtkXText *xtext, int line, int *subline) break; lines -= g_slist_length (ent->sublines); } - return 0; + return NULL; } } /* -- end of optimization -- */ @@ -3656,7 +3673,7 @@ gtk_xtext_nth (GtkXText *xtext, int line, int *subline) } ent = ent->next; } - return 0; + return NULL; } /* render enta (or an inclusive range enta->entb) */ @@ -3895,10 +3912,10 @@ gtk_xtext_kill_ent (xtext_buffer *buffer, textentry *ent) gtk_xtext_search_textentry_del (buffer, ent); } - g_slist_free_full (ent->slp, free); + g_slist_free_full (ent->slp, g_free); g_slist_free (ent->sublines); - free (ent); + g_free (ent); return visible; } @@ -4033,7 +4050,7 @@ gtk_xtext_clear (xtext_buffer *buf, int lines) while (buf->text_first) { next = buf->text_first->next; - free (buf->text_first); + g_free (buf->text_first); buf->text_first = next; } buf->text_last = NULL; @@ -4191,7 +4208,6 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent) hay = match? g_strdup (str): g_utf8_casefold (str, lstr); lhay = strlen (hay); - off = 0; for (pos = hay, len = lhay; len; off += buf->search_lnee, pos = hay + off, len = lhay - off) @@ -4210,7 +4226,7 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent) } /* Common processing --- */ - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return gl; } @@ -4639,7 +4655,7 @@ gtk_xtext_append_indent (xtext_buffer *buf, if (right_text[right_len-1] == '\n') right_len--; - ent = malloc (left_len + right_len + 2 + sizeof (textentry)); + ent = g_malloc (left_len + right_len + 2 + sizeof (textentry)); str = (unsigned char *) ent + sizeof (textentry); memcpy (str, left_text, left_len); @@ -4660,7 +4676,9 @@ gtk_xtext_append_indent (xtext_buffer *buf, space = 0; /* do we need to auto adjust the separator position? */ - if (buf->xtext->auto_indent && ent->indent < MARGIN + space) + if (buf->xtext->auto_indent && + buf->indent < buf->xtext->max_auto_indent && + ent->indent < MARGIN + space) { tempindent = MARGIN + space + buf->xtext->space_width + left_width; @@ -4681,7 +4699,7 @@ gtk_xtext_append_indent (xtext_buffer *buf, } void -gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) +gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp) { textentry *ent; @@ -4694,7 +4712,7 @@ gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) if (len >= sizeof (buf->xtext->scratch_buffer)) len = sizeof (buf->xtext->scratch_buffer) - 1; - ent = malloc (len + 1 + sizeof (textentry)); + ent = g_malloc (len + 1 + sizeof (textentry)); ent->str = (unsigned char *) ent + sizeof (textentry); ent->str_len = len; if (len) @@ -4703,7 +4721,7 @@ gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) ent->indent = 0; ent->left_len = -1; - gtk_xtext_append_entry (buf, ent, 0); + gtk_xtext_append_entry (buf, ent, stamp); } gboolean @@ -4738,11 +4756,14 @@ gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area) } else { - gtk_xtext_append (out, ent->str, ent->str_len); + gtk_xtext_append (out, ent->str, ent->str_len, 0); } - out->text_last->stamp = ent->stamp; - gtk_xtext_search_textentry_add (out, out->text_last, gl, TRUE); + if (out->text_last) + { + out->text_last->stamp = ent->stamp; + gtk_xtext_search_textentry_add (out, out->text_last, gl, TRUE); + } } ent = ent->next; } @@ -4936,6 +4957,7 @@ gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render) if (buf->window_width != w) { buf->window_width = w; + buf->window_height = h; gtk_xtext_calc_lines (buf, FALSE); if (buf->scrollbar_down) gtk_adjustment_set_value (xtext->adj, xtext->adj->upper - @@ -4959,8 +4981,7 @@ gtk_xtext_buffer_new (GtkXText *xtext) { xtext_buffer *buf; - buf = malloc (sizeof (xtext_buffer)); - memset (buf, 0, sizeof (xtext_buffer)); + buf = g_new0 (xtext_buffer, 1); buf->old_value = -1; buf->xtext = xtext; buf->scrollbar_down = TRUE; @@ -4990,9 +5011,9 @@ gtk_xtext_buffer_free (xtext_buffer *buf) while (ent) { next = ent->next; - free (ent); + g_free (ent); ent = next; } - free (buf); + g_free (buf); } |