From 510eff37ce36322ea362b574b19301c05152a9a0 Mon Sep 17 00:00:00 2001 From: Yevgen Muntyan <17531749+muntyan@users.noreply.github.com> Date: Fri, 9 Jun 2006 14:28:17 -0500 Subject: [PATCH] Making drawing like vte's --- moo/mooterm/mooterm-draw.c | 408 ++++++---- moo/mooterm/mooterm-private.h | 17 +- moo/mooterm/mooterm-text.c | 5 +- moo/mooterm/mooterm.c | 118 ++- moo/mooterm/mootermbuffer.c | 10 +- moo/mooterm/mootermparser.c | 207 ++--- moo/mooterm/mootermparser.h | 2 +- moo/mooterm/mootermpt-cygwin.c | 45 +- moo/mooterm/mootermpt-unix.c | 60 +- patch/vte-drawing.patch | 1301 -------------------------------- 10 files changed, 569 insertions(+), 1604 deletions(-) delete mode 100644 patch/vte-drawing.patch diff --git a/moo/mooterm/mooterm-draw.c b/moo/mooterm/mooterm-draw.c index 6a3640e5..42947414 100644 --- a/moo/mooterm/mooterm-draw.c +++ b/moo/mooterm/mooterm-draw.c @@ -31,6 +31,9 @@ #define HOW_MANY(x__,y__) (((x__) + (y__) - 1) / (y__)) +static void add_update_timeout (MooTerm *term); + + static void font_calculate (MooTermFont *font) { @@ -147,7 +150,7 @@ _moo_term_font_free (MooTermFont *font) void -_moo_term_invalidate (MooTerm *term) +_moo_term_invalidate (MooTerm *term) { GdkRectangle rec = {0, 0, term->priv->width, term->priv->height}; _moo_term_invalidate_screen_rect (term, &rec); @@ -385,6 +388,7 @@ _moo_term_cursor_moved (MooTerm *term, { term->priv->cursor_row = buf_cursor_row (buf); term->priv->cursor_col = buf_cursor_col_display (buf); + add_update_timeout (term); } } @@ -434,14 +438,14 @@ moo_term_draw (MooTerm *term, int width = term->priv->width; int height = term->priv->height; GdkRectangle clip = {0, 0, width, height}; - GdkRegion *screen_region = NULL; +// GdkRegion *screen_region = NULL; g_return_if_fail (region != NULL); gdk_region_get_rectangles (region, &rects, &n_rects); - if (term->priv->changed) - screen_region = gdk_region_new (); +// if (term->priv->changed) +// screen_region = gdk_region_new (); for (i = 0; i < n_rects; ++i) { @@ -455,22 +459,22 @@ moo_term_draw (MooTerm *term, term_draw_range (term, drawable, top_line + r->y + j, r->x, r->width); - - if (screen_region) - gdk_region_union_with_rect (screen_region, r); +// +// if (screen_region) +// gdk_region_union_with_rect (screen_region, r); } } - if (term->priv->changed && !gdk_region_empty (screen_region)) - { - gdk_region_subtract (term->priv->changed, - screen_region); - if (gdk_region_empty (term->priv->changed)) - region_destroy (&term->priv->changed); - } +// if (term->priv->changed && !gdk_region_empty (screen_region)) +// { +// gdk_region_subtract (term->priv->changed, +// screen_region); +// if (gdk_region_empty (term->priv->changed)) +// region_destroy (&term->priv->changed); +// } - if (screen_region) - gdk_region_destroy (screen_region); +// if (screen_region) +// gdk_region_destroy (screen_region); g_free (rects); } @@ -501,107 +505,110 @@ region_union_with_rect (GdkRegion **region, } -static gboolean -update_timeout (MooTerm *term) -{ - GdkRegion *region, *changed, *clip_region; - GdkRectangle *rectangles; - int n_rectangles, i; - int top_line = term_top_line (term); - int scrollback = buf_scrollback (term->priv->buffer); - GdkWindow *window = GTK_WIDGET(term)->window; - gboolean need_redraw = FALSE; - GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; - - if (!GTK_WIDGET_DRAWABLE (term)) - return TRUE; - - gdk_window_freeze_updates (window); - - if (!term->priv->changed && - term->priv->cursor_col == term->priv->cursor_col_old && - term->priv->cursor_row == term->priv->cursor_row_old) - goto out; - - if (term->priv->changed) - { - changed = term->priv->changed; - term->priv->changed = NULL; - } - else - { - changed = gdk_region_new (); - } - - if (term->priv->cursor_col != term->priv->cursor_col_old || - term->priv->cursor_row != term->priv->cursor_row_old) - { - int row; - - row = scrollback + term->priv->cursor_row - top_line; - if (term->priv->cursor_col < term->priv->width && - row >= 0 && row < (int) term->priv->height) - { - GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; - gdk_region_union_with_rect (changed, &rect); - } - - row = scrollback + term->priv->cursor_row_old - top_line; - if (term->priv->cursor_col_old < term->priv->width && - row >= 0 && row < (int) term->priv->height) - { - GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; - gdk_region_union_with_rect (changed, &rect); - } - } - - clip_region = gdk_region_rectangle (&clip); - gdk_region_intersect (changed, clip_region); - gdk_region_destroy (clip_region); - - if (gdk_region_empty (changed)) - { - gdk_region_destroy (changed); - goto out; - } - - gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); - g_return_val_if_fail (n_rectangles > 0, TRUE); - - for (i = 0; i < n_rectangles; ++i) - { - rect_screen_to_window (term, &rectangles[i], &rectangles[i]); - } - - region = gdk_region_rectangle (&rectangles[0]); - - for (i = 1; i < n_rectangles; ++i) - gdk_region_union_with_rect (region, &rectangles[i]); - - gdk_window_invalidate_region (window, region, FALSE); - need_redraw = TRUE; - - g_free (rectangles); - gdk_region_destroy (region); - gdk_region_destroy (changed); - -out: - term->priv->cursor_col_old = term->priv->cursor_col; - term->priv->cursor_row_old = term->priv->cursor_row; - gdk_window_thaw_updates (window); - - if (need_redraw) - { - if (g_timer_elapsed (term->priv->redraw_timer, NULL) > REDRAW_INTERVAL) - gdk_window_process_updates (GTK_WIDGET(term)->window, FALSE); - } - else - { - g_timer_start (term->priv->redraw_timer); - } - - return TRUE; -} +// static gboolean +// update_timeout (MooTerm *term) +// { +// GdkRegion *region, *changed, *clip_region; +// GdkRectangle *rectangles; +// int n_rectangles, i; +// int top_line = term_top_line (term); +// int scrollback = buf_scrollback (term->priv->buffer); +// GdkWindow *window = GTK_WIDGET(term)->window; +// gboolean need_redraw = FALSE; +// GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; +// +// if (!GTK_WIDGET_DRAWABLE (term)) +// return TRUE; +// +// gdk_window_freeze_updates (window); +// +// if (!term->priv->changed && +// term->priv->cursor_col == term->priv->cursor_col_old && +// term->priv->cursor_row == term->priv->cursor_row_old) +// goto out; +// +// if (term->priv->changed) +// { +// changed = term->priv->changed; +// term->priv->changed = NULL; +// } +// else +// { +// changed = gdk_region_new (); +// } +// +// if (term->priv->cursor_col != term->priv->cursor_col_old || +// term->priv->cursor_row != term->priv->cursor_row_old) +// { +// int row; +// +// row = scrollback + term->priv->cursor_row - top_line; +// if (term->priv->cursor_col < term->priv->width && +// row >= 0 && row < (int) term->priv->height) +// { +// GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; +// gdk_region_union_with_rect (changed, &rect); +// } +// +// row = scrollback + term->priv->cursor_row_old - top_line; +// if (term->priv->cursor_col_old < term->priv->width && +// row >= 0 && row < (int) term->priv->height) +// { +// GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; +// gdk_region_union_with_rect (changed, &rect); +// } +// } +// +// clip_region = gdk_region_rectangle (&clip); +// gdk_region_intersect (changed, clip_region); +// gdk_region_destroy (clip_region); +// +// if (gdk_region_empty (changed)) +// { +// gdk_region_destroy (changed); +// goto out; +// } +// +// gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); +// g_return_val_if_fail (n_rectangles > 0, TRUE); +// +// for (i = 0; i < n_rectangles; ++i) +// { +// rect_screen_to_window (term, &rectangles[i], &rectangles[i]); +// } +// +// region = gdk_region_rectangle (&rectangles[0]); +// +// for (i = 1; i < n_rectangles; ++i) +// gdk_region_union_with_rect (region, &rectangles[i]); +// +// gdk_window_invalidate_region (window, region, FALSE); +// need_redraw = TRUE; +// +// g_free (rectangles); +// gdk_region_destroy (region); +// gdk_region_destroy (changed); +// +// out: +// term->priv->cursor_col_old = term->priv->cursor_col; +// term->priv->cursor_row_old = term->priv->cursor_row; +// gdk_window_thaw_updates (window); +// +// if (need_redraw) +// { +// if (g_timer_elapsed (term->priv->redraw_timer, NULL) > REDRAW_INTERVAL) +// { +// gdk_window_process_updates (GTK_WIDGET(term)->window, FALSE); +// g_timer_start (term->priv->redraw_timer); +// } +// } +// else +// { +// g_timer_start (term->priv->redraw_timer); +// } +// +// return TRUE; +// } gboolean @@ -612,12 +619,10 @@ _moo_term_expose_event (GtkWidget *widget, GdkRegion *text_region; MooTerm *term = MOO_TERM (widget); - g_assert (term_top_line (term) <= buf_scrollback (term->priv->buffer)); + if (widget->window != event->window) + return FALSE; - if (!term->priv->update_timeout) - term->priv->update_timeout = - g_timeout_add_full (UPDATE_PRIORITY, UPDATE_TIMEOUT, - (GSourceFunc) update_timeout, term, NULL); + g_assert (term_top_line (term) <= buf_scrollback (term->priv->buffer)); text_rec.width = PIXEL_WIDTH (term); text_rec.height = PIXEL_HEIGHT (term); @@ -627,10 +632,8 @@ _moo_term_expose_event (GtkWidget *widget, if (!gdk_region_empty (text_region)) moo_term_draw (term, event->window, text_region); - g_timer_start (term->priv->redraw_timer); - gdk_region_destroy (text_region); - return TRUE; + return FALSE; } @@ -1002,20 +1005,21 @@ term_draw_cursor (MooTerm *term, } -void -_moo_term_buf_content_changed (MooTerm *term, - MooTermBuffer *buf) +static void +add_buffer_changed (MooTerm *term) { GdkRegion *changed; guint top_line, scrollback; int height; + MooTermBuffer *buf; if (!GTK_WIDGET_DRAWABLE (term)) return; + buf = term->priv->buffer; changed = buf->priv->changed; - if (buf != term->priv->buffer || !changed || gdk_region_empty (changed)) + if (!changed || gdk_region_empty (changed)) return; buf->priv->changed = NULL; @@ -1056,6 +1060,151 @@ _moo_term_buf_content_changed (MooTerm *term, } +static gboolean +invalidate_window (MooTerm *term) +{ + GdkRegion *region, *changed, *clip_region; + GdkRectangle *rectangles; + int n_rectangles, i; + int top_line = term_top_line (term); + int scrollback = buf_scrollback (term->priv->buffer); + GdkWindow *window = GTK_WIDGET(term)->window; + gboolean need_redraw = FALSE; + GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; + + if (!GTK_WIDGET_DRAWABLE (term)) + return FALSE; + + add_buffer_changed (term); + + if (!term->priv->changed && + term->priv->cursor_col == term->priv->cursor_col_old && + term->priv->cursor_row == term->priv->cursor_row_old) + goto out; + + if (term->priv->changed) + { + changed = term->priv->changed; + term->priv->changed = NULL; + } + else + { + changed = gdk_region_new (); + } + + if (term->priv->cursor_col != term->priv->cursor_col_old || + term->priv->cursor_row != term->priv->cursor_row_old) + { + int row; + + row = scrollback + term->priv->cursor_row - top_line; + if (term->priv->cursor_col < term->priv->width && + row >= 0 && row < (int) term->priv->height) + { + GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; + gdk_region_union_with_rect (changed, &rect); + } + + row = scrollback + term->priv->cursor_row_old - top_line; + if (term->priv->cursor_col_old < term->priv->width && + row >= 0 && row < (int) term->priv->height) + { + GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; + gdk_region_union_with_rect (changed, &rect); + } + } + + clip_region = gdk_region_rectangle (&clip); + gdk_region_intersect (changed, clip_region); + gdk_region_destroy (clip_region); + + if (gdk_region_empty (changed)) + { + gdk_region_destroy (changed); + goto out; + } + + gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); + g_return_val_if_fail (n_rectangles > 0, TRUE); + + for (i = 0; i < n_rectangles; ++i) + { + rect_screen_to_window (term, &rectangles[i], &rectangles[i]); + } + + region = gdk_region_rectangle (&rectangles[0]); + + for (i = 1; i < n_rectangles; ++i) + gdk_region_union_with_rect (region, &rectangles[i]); + + gdk_window_invalidate_region (window, region, FALSE); + need_redraw = TRUE; + + g_free (rectangles); + gdk_region_destroy (region); + gdk_region_destroy (changed); + +out: + term->priv->cursor_col_old = term->priv->cursor_col; + term->priv->cursor_row_old = term->priv->cursor_row; + + return need_redraw; +} + +static gboolean +update_delay_timeout (MooTerm *term) +{ + /* We only stop the timer if no update request was received in this + * past cycle. + */ + if (invalidate_window (term)) + return TRUE; + + term->priv->update_timer = 0; + return FALSE; +} + +static gboolean +update_timeout (MooTerm *term) +{ + invalidate_window (term); + + /* Set a timer such that we do not invalidate for a while. */ + /* This limits the number of times we draw to ~40fps. */ + term->priv->update_timer = + g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, + UPDATE_REPEAT_TIMEOUT, + (GSourceFunc) update_delay_timeout, + term, NULL); + + return FALSE; +} + +static void +add_update_timeout (MooTerm *term) +{ + if (!term->priv->update_timer) + term->priv->update_timer = + g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, + UPDATE_TIMEOUT, + (GSourceFunc) update_timeout, + term, NULL); +} + +void +_moo_term_buf_content_changed (MooTerm *term, + MooTermBuffer *buf) +{ + if (GTK_WIDGET_DRAWABLE (term) && + buf == term->priv->buffer && + buf->priv->changed && + !gdk_region_empty (buf->priv->changed)) + { + add_update_timeout (term); + } +} + + void _moo_term_buffer_scrolled (MooTermBuffer *buf, guint lines, @@ -1065,6 +1214,7 @@ _moo_term_buffer_scrolled (MooTermBuffer *buf, { GdkRectangle rect = {0, 0, term->priv->width, term->priv->height}; region_union_with_rect (&term->priv->changed, &rect); + add_update_timeout (term); } } diff --git a/moo/mooterm/mooterm-private.h b/moo/mooterm/mooterm-private.h index bcadbc33..b9d5733d 100644 --- a/moo/mooterm/mooterm-private.h +++ b/moo/mooterm/mooterm-private.h @@ -38,11 +38,13 @@ G_BEGIN_DECLS #define PT_WRITER_PRIORITY G_PRIORITY_DEFAULT #define PT_READER_PRIORITY G_PRIORITY_DEFAULT -#define ADJUSTMENT_PRIORITY G_PRIORITY_HIGH_IDLE +#define ADJUSTMENT_PRIORITY G_PRIORITY_DEFAULT_IDLE #define ADJUSTMENT_DELTA 30.0 -#define UPDATE_PRIORITY G_PRIORITY_DEFAULT -#define UPDATE_TIMEOUT 30 -#define REDRAW_INTERVAL 0.6 + +#define UPDATE_TIMEOUT 10 +#define UPDATE_REPEAT_TIMEOUT 40 +#define PROCESS_INCOMING_TIMEOUT 10 +#define INPUT_CHUNK_SIZE 4096 #define MIN_TERMINAL_WIDTH 8 #define MIN_TERMINAL_HEIGHT 4 @@ -81,6 +83,8 @@ typedef struct _MooTermFont MooTermFont; struct _MooTermPrivate { struct _MooTermPt *pt; struct _MooTermParser *parser; + GString *incoming; + guint process_timeout; struct _MooTermBuffer *buffer; struct _MooTermBuffer *primary_buffer; @@ -115,10 +119,9 @@ struct _MooTermPrivate { MooTermFont *font; GdkRegion *changed; /* screen coordinates */ - guint update_timeout; - GTimer *redraw_timer; guint cursor_row_old; /* cursor has been here, and it's been invalidated */ guint cursor_col_old; + guint update_timer; GdkGC *clip; gboolean font_changed; @@ -242,6 +245,8 @@ void _moo_term_pause_cursor_blinking (MooTerm *term); void _moo_term_set_cursor_blinks (MooTerm *term, gboolean blinks); +gsize _moo_term_get_input_chunk_len (MooTerm *term); + /*************************************************************************/ /* vt commands diff --git a/moo/mooterm/mooterm-text.c b/moo/mooterm/mooterm-text.c index 33b8b753..d4401f5f 100644 --- a/moo/mooterm/mooterm-text.c +++ b/moo/mooterm/mooterm-text.c @@ -205,7 +205,8 @@ static int segment_sym_diff (Segment *s1, Segment *s2, } -static void invalidate_segment (Segment *segm, guint num) +static void +invalidate_segment (Segment *segm, guint num) { MooTerm *term; int top_line; @@ -223,7 +224,7 @@ static void invalidate_segment (Segment *segm, guint num) MooTermIter end = segm[i].end; GdkRectangle rect; - _moo_term_iter_order (&start, &end); + _moo_term_iter_order (&start, &end); if (ITER_ROW (&start) < ITER_ROW (&end)) { diff --git a/moo/mooterm/mooterm.c b/moo/mooterm/mooterm.c index 0d4a42e0..84816822 100644 --- a/moo/mooterm/mooterm.c +++ b/moo/mooterm/mooterm.c @@ -257,7 +257,7 @@ moo_term_init (MooTerm *term) term->priv->pt = _moo_term_pt_new (term); g_signal_connect_swapped (term->priv->pt, "child-died", G_CALLBACK (child_died), term); - + term->priv->incoming = g_string_new_len (NULL, INPUT_CHUNK_SIZE); term->priv->parser = _moo_term_parser_new (term); _moo_term_init_palette (term); @@ -271,9 +271,6 @@ moo_term_init (MooTerm *term) term->priv->width = 80; term->priv->height = 24; - term->priv->redraw_timer = g_timer_new (); - g_timer_stop (term->priv->redraw_timer); - term->priv->selection = _moo_term_selection_new (term); term->priv->cursor_visible = TRUE; @@ -360,11 +357,16 @@ moo_term_init (MooTerm *term) #define OBJECT_UNREF(obj__) if (obj__) g_object_unref (obj__) -static void moo_term_finalize (GObject *object) +static void +moo_term_finalize (GObject *object) { guint i, j; MooTerm *term = MOO_TERM (object); + if (term->priv->process_timeout) + g_source_remove (term->priv->process_timeout); + g_string_free (term->priv->incoming, TRUE); + if (term->priv->cursor_blink_timeout_id) g_source_remove (term->priv->cursor_blink_timeout_id); @@ -382,8 +384,6 @@ static void moo_term_finalize (GObject *object) if (term->priv->changed) gdk_region_destroy (term->priv->changed); - g_timer_destroy (term->priv->redraw_timer); - OBJECT_UNREF (term->priv->layout); OBJECT_UNREF (term->priv->im); @@ -557,9 +557,9 @@ moo_term_unrealize (GtkWidget *widget) guint i; MooTerm *term = MOO_TERM (widget); - if (term->priv->update_timeout) - g_source_remove (term->priv->update_timeout); - term->priv->update_timeout = 0; + if (term->priv->update_timer) + g_source_remove (term->priv->update_timer); + term->priv->update_timer = 0; if (term->priv->menu) g_object_unref (term->priv->menu); @@ -682,7 +682,7 @@ static void buf_size_changed (MooTerm *term, } -#define equal(a, b) (ABS((a)-(b)) < 0.4) +#define EQUAL(a, b) (ABS((a)-(b)) < 0.4) static void update_adjustment (MooTerm *term) { @@ -697,17 +697,12 @@ static void update_adjustment (MooTerm *term) value = term_top_line (term); page_size = term->priv->height; - if ((ABS (upper - term->priv->adjustment->upper) > - ADJUSTMENT_DELTA * page_size) || - (ABS (value - term->priv->adjustment->value) > - ADJUSTMENT_DELTA * page_size)) - { - now = TRUE; - } + now = ABS (upper - term->priv->adjustment->upper) > ADJUSTMENT_DELTA * page_size || + ABS (value - term->priv->adjustment->value) > ADJUSTMENT_DELTA * page_size; - if (!equal (adj->lower, 0.0) || !equal (adj->upper, upper) || - !equal (adj->value, value) || !equal (adj->page_size, page_size) || - !equal (adj->page_increment, page_size) || !equal (adj->step_increment, 1.0)) + if (!EQUAL (adj->lower, 0.0) || !EQUAL (adj->upper, upper) || + !EQUAL (adj->value, value) || !EQUAL (adj->page_size, page_size) || + !EQUAL (adj->page_increment, page_size) || !EQUAL (adj->step_increment, 1.0)) { adj->lower = 0.0; adj->upper = upper; @@ -729,19 +724,18 @@ static void update_adjustment_value (MooTerm *term) if (!term->priv->adjustment) return; - if (ABS (value - term->priv->adjustment->value) > - ADJUSTMENT_DELTA * term->priv->height) - { - now = TRUE; - } + now = ABS (value - term->priv->adjustment->value) > + ADJUSTMENT_DELTA * term->priv->height; - if (!equal (term->priv->adjustment->value, value)) + if (!EQUAL (term->priv->adjustment->value, value)) { term->priv->adjustment->value = value; queue_adjustment_value_changed (term, now); } } +#undef EQUAL + static void adjustment_value_changed (MooTerm *term) { @@ -761,8 +755,9 @@ static void adjustment_value_changed (MooTerm *term) } -static void queue_adjustment_changed (MooTerm *term, - gboolean now) +static void +queue_adjustment_changed (MooTerm *term, + gboolean now) { if (now) { @@ -1070,10 +1065,45 @@ moo_term_paste_clipboard (MooTerm *term, } +static gboolean +process_incoming (MooTerm *term) +{ + gboolean done; + +// if (term->priv->incoming->len > 2*INPUT_CHUNK_SIZE) +// g_print ("process_incoming: %d chars\n", +// term->priv->incoming->len); + + done = !term->priv->incoming->len || + _moo_term_parser_parse (term->priv->parser, + term->priv->incoming->str, + term->priv->incoming->len); + + if (term->priv->incoming->len > INPUT_CHUNK_SIZE) + { + g_string_free (term->priv->incoming, TRUE); + term->priv->incoming = g_string_new_len (NULL, INPUT_CHUNK_SIZE); + } + else + { + g_string_truncate (term->priv->incoming, 0); + } + + term->priv->process_timeout = 0; + + if (!done) + term->priv->process_timeout = + g_timeout_add (PROCESS_INCOMING_TIMEOUT, + (GSourceFunc) process_incoming, + term); + + return FALSE; +} + void -moo_term_feed (MooTerm *term, - const char *data, - int len) +moo_term_feed (MooTerm *term, + const char *data, + int len) { if (!len) return; @@ -1083,7 +1113,29 @@ moo_term_feed (MooTerm *term, if (len < 0) len = strlen (data); - _moo_term_parser_parse (term->priv->parser, data, len); +// g_print ("moo_term_feed: %d chars\n", len); + g_string_append_len (term->priv->incoming, data, len); + + if (!term->priv->process_timeout) + term->priv->process_timeout = + g_timeout_add (PROCESS_INCOMING_TIMEOUT, + (GSourceFunc) process_incoming, + term); +} + + +gsize +_moo_term_get_input_chunk_len (MooTerm *term) +{ + switch (term->priv->incoming->len / INPUT_CHUNK_SIZE) + { + case 0: + return INPUT_CHUNK_SIZE - term->priv->incoming->len; + case 1: + return INPUT_CHUNK_SIZE / 2; + default: + return 0; + } } diff --git a/moo/mooterm/mootermbuffer.c b/moo/mooterm/mootermbuffer.c index 4b33a7ad..e688cb8d 100644 --- a/moo/mooterm/mootermbuffer.c +++ b/moo/mooterm/mootermbuffer.c @@ -584,16 +584,18 @@ _moo_term_buffer_cursor_move (MooTermBuffer *buf, } -void _moo_term_buffer_cursor_moved (MooTermBuffer *buf) +void +_moo_term_buffer_cursor_moved (MooTermBuffer *buf) { if (!buf->priv->freeze_cursor_notify) g_signal_emit (buf, signals[CURSOR_MOVED], 0); } -void _moo_term_buffer_cursor_move_to (MooTermBuffer *buf, - int row, - int col) +void +_moo_term_buffer_cursor_move_to (MooTermBuffer *buf, + int row, + int col) { int width = buf_screen_width (buf); int height = buf_screen_height (buf); diff --git a/moo/mooterm/mootermparser.c b/moo/mooterm/mootermparser.c index f37c126d..348c2d44 100644 --- a/moo/mooterm/mootermparser.c +++ b/moo/mooterm/mootermparser.c @@ -60,7 +60,8 @@ static void exec_dcs (MooTermParser *parser); #define iter_free g_free -static InputIter *iter_new (MooTermParser *parser) +static InputIter * +iter_new (MooTermParser *parser) { InputIter *iter = g_new (InputIter, 1); @@ -72,14 +73,16 @@ static InputIter *iter_new (MooTermParser *parser) } -static gboolean iter_eof (InputIter *iter) +static gboolean +iter_eof (InputIter *iter) { return !iter->old && iter->offset >= iter->parser->input.data_len; } -static void iter_forward (InputIter *iter) +static void +iter_forward (InputIter *iter) { g_assert (!iter_eof (iter)); @@ -97,7 +100,8 @@ static void iter_forward (InputIter *iter) } -static void iter_backward (InputIter *iter) +static void +iter_backward (InputIter *iter) { g_assert (iter->offset || (!iter->old && iter->parser->input.old_data->len)); @@ -115,14 +119,16 @@ static void iter_backward (InputIter *iter) } -static void iter_set_eof (InputIter *iter) +static void +iter_set_eof (InputIter *iter) { iter->old = FALSE; iter->offset = iter->parser->input.data_len; } -static guchar iter_get_char (InputIter *iter) +static guchar +iter_get_char (InputIter *iter) { g_assert (!iter_eof (iter)); @@ -133,7 +139,8 @@ static guchar iter_get_char (InputIter *iter) } -static void save_cmd (MooTermParser *parser) +static void +save_cmd (MooTermParser *parser) { GString *old = parser->input.old_data; guint offset = parser->cmd_start->offset; @@ -168,7 +175,8 @@ static void save_cmd (MooTermParser *parser) } -static void save_character (MooTermParser *parser) +static void +save_character (MooTermParser *parser) { g_string_truncate (parser->input.old_data, 0); g_string_append_len (parser->input.old_data, @@ -178,7 +186,9 @@ static void save_character (MooTermParser *parser) } -static void one_char_cmd (MooTermParser *parser, guchar c) +static void +one_char_cmd (MooTermParser *parser, + guchar c) { flush_chars (parser); DEBUG_ONE_CHAR(c); @@ -276,7 +286,8 @@ static void one_char_cmd (MooTermParser *parser, guchar c) /* returns 0 on end of input */ -static guchar get_char (MooTermParser *parser) +static guchar +get_char (MooTermParser *parser) { guchar c = 0; @@ -304,19 +315,22 @@ static guchar get_char (MooTermParser *parser) } -static void flush_chars (MooTermParser *parser) +static void +flush_chars (MooTermParser *parser) { if (parser->character->len) { - g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, - parser->character->str); +// g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, +// parser->character->str); VT_PRINT_CHAR (ERROR_CHAR); g_string_truncate (parser->character, 0); } } -static void process_char (MooTermParser *parser, guchar c) +static void +process_char (MooTermParser *parser, + guchar c) { if (parser->character->len || c >= 128) { @@ -333,8 +347,8 @@ static void process_char (MooTermParser *parser, guchar c) break; case -1: - g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, - parser->character->str); +// g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, +// parser->character->str); VT_PRINT_CHAR (ERROR_CHAR); g_string_truncate (parser->character, 0); break; @@ -352,7 +366,8 @@ static void process_char (MooTermParser *parser, guchar c) } -static void parser_init (MooTermParser *parser) +static void +parser_init (MooTermParser *parser) { parser->save = FALSE; @@ -377,7 +392,8 @@ static void parser_init (MooTermParser *parser) } -static void parser_finish (MooTermParser *parser) +static void +parser_finish (MooTermParser *parser) { if (!parser->save) g_string_truncate (parser->input.old_data, 0); @@ -385,7 +401,7 @@ static void parser_finish (MooTermParser *parser) MooTermParser* -_moo_term_parser_new (MooTerm *term) +_moo_term_parser_new (MooTerm *term) { MooTermParser *p = g_new0 (MooTermParser, 1); @@ -437,10 +453,10 @@ _moo_term_parser_free (MooTermParser *parser) } -void -_moo_term_parser_parse (MooTermParser *parser, - const char *string, - guint len) +static void +parser_do_parse (MooTermParser *parser, + const char *string, + guint len) { guchar c; @@ -801,12 +817,27 @@ STATE_DCS_ESCAPE_: } +gboolean +_moo_term_parser_parse (MooTermParser *parser, + const char *string, + guint len) +{ + parser_do_parse (parser, string, len); + +// if (parser->save) +// g_print ("saved %d chars\n", parser->input.old_data->len); + + return !parser->save; +} + + /***************************************************************************/ /* Parsing and executing received command sequence */ -static void exec_cmd (MooTermParser *parser, - guchar cmd) +static void +exec_cmd (MooTermParser *parser, + guchar cmd) { switch (cmd) { @@ -871,8 +902,9 @@ static void exec_cmd (MooTermParser *parser, } -static void init_yyparse (MooTermParser *parser, - LexType lex_type) +static void +init_yyparse (MooTermParser *parser, + LexType lex_type) { parser->lex.lex = lex_type; parser->lex.part = PART_START; @@ -882,7 +914,8 @@ static void init_yyparse (MooTermParser *parser, } -int _moo_term_yylex (MooTermParser *parser) +int +_moo_term_yylex (MooTermParser *parser) { guint offset = parser->lex.offset; @@ -1042,7 +1075,8 @@ int _moo_term_yylex (MooTermParser *parser) } -char *_moo_term_current_ctl (MooTermParser *parser) +char * +_moo_term_current_ctl (MooTermParser *parser) { GString *s; char *nice; @@ -1087,7 +1121,8 @@ char *_moo_term_current_ctl (MooTermParser *parser) } -static void exec_escape_sequence (MooTermParser *parser) +static void +exec_escape_sequence (MooTermParser *parser) { init_yyparse (parser, LEX_ESCAPE); DEBUG_CONTROL; @@ -1095,7 +1130,8 @@ static void exec_escape_sequence (MooTermParser *parser) } -static void exec_csi (MooTermParser *parser) +static void +exec_csi (MooTermParser *parser) { init_yyparse (parser, LEX_CONTROL); DEBUG_CONTROL; @@ -1103,7 +1139,8 @@ static void exec_csi (MooTermParser *parser) } -static void exec_dcs (MooTermParser *parser) +static void +exec_dcs (MooTermParser *parser) { init_yyparse (parser, LEX_DCS); DEBUG_CONTROL; @@ -1111,8 +1148,9 @@ static void exec_dcs (MooTermParser *parser) } -void _moo_term_yyerror (MooTermParser *parser, - G_GNUC_UNUSED const char *string) +void +_moo_term_yyerror (MooTermParser *parser, + G_GNUC_UNUSED const char *string) { char *s = _moo_term_current_ctl (parser); g_warning ("parse error: '%s'\n", s); @@ -1120,8 +1158,9 @@ void _moo_term_yyerror (MooTermParser *parser, } -static void exec_apc (MooTermParser *parser, - guchar final) +static void +exec_apc (MooTermParser *parser, + guchar final) { char *s = g_strdup_printf ("\237%s%c", parser->data->str, final); char *nice = _moo_term_nice_bytes (s, -1); @@ -1131,8 +1170,9 @@ static void exec_apc (MooTermParser *parser, } -static void exec_pm (MooTermParser *parser, - guchar final) +static void +exec_pm (MooTermParser *parser, + guchar final) { char *s = g_strdup_printf ("\236%s%c", parser->data->str, final); char *nice = _moo_term_nice_bytes (s, -1); @@ -1142,8 +1182,9 @@ static void exec_pm (MooTermParser *parser, } -static void exec_osc (MooTermParser *parser, - guchar final) +static void +exec_osc (MooTermParser *parser, + guchar final) { if (parser->data->len >= 2 && parser->data->str[0] >= '0' && @@ -1178,58 +1219,56 @@ static void exec_osc (MooTermParser *parser, } -char *_moo_term_nice_char (guchar c) +char * +_moo_term_nice_char (guchar c) { if (' ' <= c && c <= '~') - { return g_strndup ((char*)&c, 1); - } - else + + switch (c) { - switch (c) - { - case 0x1B: - return g_strdup (""); - case 0x84: - return g_strdup (""); - case 0x85: - return g_strdup (""); - case 0x88: - return g_strdup (""); - case 0x8D: - return g_strdup (""); - case 0x8E: - return g_strdup (""); - case 0x8F: - return g_strdup (""); - case 0x90: - return g_strdup (""); - case 0x98: - return g_strdup (""); - case 0x9A: - return g_strdup (""); - case 0x9B: - return g_strdup (""); - case 0x9C: - return g_strdup (""); - case 0x9D: - return g_strdup (""); - case 0x9E: - return g_strdup (""); - case 0x9F: - return g_strdup (""); - default: - if ('A' - 64 <= c && c <= ']' - 64) - return g_strdup_printf ("^%c", c + 64); - else - return g_strdup_printf ("<%d>", c); - } + case 0x1B: + return g_strdup (""); + case 0x84: + return g_strdup (""); + case 0x85: + return g_strdup (""); + case 0x88: + return g_strdup (""); + case 0x8D: + return g_strdup (""); + case 0x8E: + return g_strdup (""); + case 0x8F: + return g_strdup (""); + case 0x90: + return g_strdup (""); + case 0x98: + return g_strdup (""); + case 0x9A: + return g_strdup (""); + case 0x9B: + return g_strdup (""); + case 0x9C: + return g_strdup (""); + case 0x9D: + return g_strdup (""); + case 0x9E: + return g_strdup (""); + case 0x9F: + return g_strdup (""); } + + if ('A' - 64 <= c && c <= ']' - 64) + return g_strdup_printf ("^%c", c + 64); + else + return g_strdup_printf ("<%d>", c); } -char *_moo_term_nice_bytes (const char *string, - int len) +char * +_moo_term_nice_bytes (const char *string, + int len) { int i; GString *str; diff --git a/moo/mooterm/mootermparser.h b/moo/mooterm/mootermparser.h index 5d15144f..06558dfb 100644 --- a/moo/mooterm/mootermparser.h +++ b/moo/mooterm/mootermparser.h @@ -90,7 +90,7 @@ typedef struct _MooTermParser { MooTermParser *_moo_term_parser_new (MooTerm *term); void _moo_term_parser_free (MooTermParser *parser); -void _moo_term_parser_parse (MooTermParser *parser, +gboolean _moo_term_parser_parse (MooTermParser *parser, const char *string, guint len); void _moo_term_parser_reset (MooTermParser *parser); diff --git a/moo/mooterm/mootermpt-cygwin.c b/moo/mooterm/mootermpt-cygwin.c index 478f1118..b02a53e5 100644 --- a/moo/mooterm/mootermpt-cygwin.c +++ b/moo/mooterm/mootermpt-cygwin.c @@ -27,7 +27,6 @@ #define TRY_NUM 10 #define SLEEP_TIME 10 #define TERM_EMULATION "xterm" -#define READ_CHUNK_SIZE 1024 #define WRITE_CHUNK_SIZE 4096 #define POLL_TIME 5 #define POLL_NUM 1 @@ -36,7 +35,8 @@ static char *HELPER_DIR = NULL; #define HELPER_BINARY "termhelper.exe" -void moo_term_set_helper_directory (const char *dir) +void +moo_term_set_helper_directory (const char *dir) { g_free (HELPER_DIR); HELPER_DIR = g_strdup (dir); @@ -193,10 +193,11 @@ fork_command (MooTermPt *pt_gen, pt->out_io = g_io_channel_win32_new_fd (pt->out); g_io_channel_set_encoding (pt->out_io, NULL, NULL); g_io_channel_set_buffered (pt->in_io, FALSE); - pt->out_watch_id = g_io_add_watch (pt->out_io, - (GIOCondition)(G_IO_IN | G_IO_PRI | G_IO_HUP), - (GIOFunc) read_helper_out, - pt); + pt->out_watch_id = g_io_add_watch_full (pt->out_io, + G_PRIORITY_DEFAULT_IDLE, + G_IO_IN | G_IO_PRI | G_IO_HUP, + (GIOFunc) read_helper_out, + pt, NULL); // GSource *src = g_main_context_find_source_by_id (NULL, helper.out_watch_id); // if (src) g_source_set_priority (src, READ_HELPER_OUT_PRIORITY); @@ -229,29 +230,31 @@ read_helper_out (GIOChannel *source, } else if (condition & (G_IO_IN | G_IO_PRI)) { - char buf[READ_CHUNK_SIZE]; - int count = 0; - gsize read; + char buf[INPUT_CHUNK_SIZE]; + gsize count = 0, read, to_read; int again = TRY_NUM; - g_io_channel_read_chars (source, buf, 1, &read, &err); - if (read == 1) ++count; + to_read = _moo_term_get_input_chunk_len (MOO_TERM_PT(pt)->priv->term); + g_assert (to_read <= sizeof (buf)); - while (again && !err && !error_occured && count < READ_CHUNK_SIZE) + if (!to_read) + return TRUE; + + g_io_channel_read_chars (source, buf, 1, &read, &err); + + if (read == 1) + ++count; + + while (again && !err && !error_occured && count < to_read) { if (g_io_channel_get_buffer_condition (source) & G_IO_IN) { g_io_channel_read_chars (source, buf + count, 1, &read, &err); if (read == 1) - { ++count; - } - else - { - if (--again) - g_usleep (SLEEP_TIME); - } + else if (--again) + g_usleep (SLEEP_TIME); } else { @@ -260,7 +263,7 @@ read_helper_out (GIOChannel *source, } } - if (count > 0) + if (count) moo_term_feed (MOO_TERM_PT(pt)->priv->term, buf, count); error_occured = (err != NULL); @@ -292,7 +295,7 @@ read_helper_out (GIOChannel *source, static void -kill_child (MooTermPt *pt_gen) +kill_child (MooTermPt *pt_gen) { MooTermPtCyg *pt = MOO_TERM_PT_CYG (pt_gen); diff --git a/moo/mooterm/mootermpt-unix.c b/moo/mooterm/mootermpt-unix.c index ec8b4a72..cbe6f5eb 100644 --- a/moo/mooterm/mootermpt-unix.c +++ b/moo/mooterm/mootermpt-unix.c @@ -37,7 +37,6 @@ #endif #define TERM_EMULATION "xterm" -#define READ_CHUNK_SIZE 1024 #define WRITE_CHUNK_SIZE 4096 #define POLL_TIME 5 #define POLL_NUM 1 @@ -258,10 +257,11 @@ fork_argv (MooTermPt *pt_gen, g_io_channel_set_encoding (pt->io, NULL, NULL); g_io_channel_set_buffered (pt->io, FALSE); - pt->io_watch_id = g_io_add_watch (pt->io, - G_IO_IN | G_IO_PRI | G_IO_HUP, - (GIOFunc) read_child_out, - pt); + pt->io_watch_id = g_io_add_watch_full (pt->io, + G_PRIORITY_DEFAULT_IDLE, + G_IO_IN | G_IO_PRI | G_IO_HUP, + (GIOFunc) read_child_out, + pt, NULL); src = g_main_context_find_source_by_id (NULL, pt->io_watch_id); @@ -328,28 +328,31 @@ static void kill_child (MooTermPt *pt_gen) } -static gboolean read_child_out (G_GNUC_UNUSED GIOChannel *source, - GIOCondition condition, - MooTermPtUnix *pt) +static gboolean +read_child_out (G_GNUC_UNUSED GIOChannel *source, + GIOCondition condition, + MooTermPtUnix *pt) { gboolean error_occured = FALSE; int error_no = 0; - char buf[READ_CHUNK_SIZE]; - int current = 0; + char buf[INPUT_CHUNK_SIZE]; guint again = POLL_NUM; + gsize to_read; + gsize current = 0; + /* try to read leftover from the pipe */ if (condition & G_IO_HUP) { - int r; + int bytes; g_message ("%s: G_IO_HUP", G_STRLOC); error_no = errno; - r = read (pt->master, buf, READ_CHUNK_SIZE); + bytes = read (pt->master, buf, sizeof (buf)); - if (r > 0) - feed_buffer (pt, buf, r); + if (bytes > 0) + feed_buffer (pt, buf, bytes); goto error; } @@ -362,11 +365,22 @@ static gboolean read_child_out (G_GNUC_UNUSED GIOChannel *source, g_assert (condition & (G_IO_IN | G_IO_PRI)); + to_read = _moo_term_get_input_chunk_len (MOO_TERM_PT(pt)->priv->term); + g_assert (to_read <= sizeof (buf)); + + if (!to_read) + { +// g_print ("read_child_out: skipping\n"); + return TRUE; + } + if (pt->non_block) { - int r = read (pt->master, buf, READ_CHUNK_SIZE); + int bytes; - switch (r) + bytes = read (pt->master, buf, to_read); + + switch (bytes) { case -1: if (errno != EAGAIN && errno != EINTR) @@ -388,14 +402,14 @@ static gboolean read_child_out (G_GNUC_UNUSED GIOChannel *source, g_free (s); } #endif - feed_buffer (pt, buf, r); + feed_buffer (pt, buf, bytes); break; } return TRUE; } - while (again && !error_occured && current < READ_CHUNK_SIZE) + while (again && !error_occured && current < to_read) { struct pollfd fd = {pt->master, POLLIN | POLLPRI, 0}; @@ -492,12 +506,12 @@ error: } -static void feed_buffer (MooTermPtUnix *pt, - const char *string, - int len) +static void +feed_buffer (MooTermPtUnix *pt, + const char *string, + int len) { - moo_term_feed (MOO_TERM_PT(pt)->priv->term, - string, len); + moo_term_feed (MOO_TERM_PT(pt)->priv->term, string, len); } diff --git a/patch/vte-drawing.patch b/patch/vte-drawing.patch deleted file mode 100644 index 67af52dc..00000000 --- a/patch/vte-drawing.patch +++ /dev/null @@ -1,1301 +0,0 @@ -diff -r 6e0a42baf315 moo/mooterm/mooterm-draw.c ---- a/moo/mooterm/mooterm-draw.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mooterm-draw.c Thu Jun 08 20:30:03 2006 -0500 -@@ -147,7 +147,7 @@ _moo_term_font_free (MooTermFont *fon - - - void --_moo_term_invalidate (MooTerm *term) -+_moo_term_invalidate (MooTerm *term) - { - GdkRectangle rec = {0, 0, term->priv->width, term->priv->height}; - _moo_term_invalidate_screen_rect (term, &rec); -@@ -434,14 +434,14 @@ moo_term_draw (MooTerm *term, - int width = term->priv->width; - int height = term->priv->height; - GdkRectangle clip = {0, 0, width, height}; -- GdkRegion *screen_region = NULL; -+// GdkRegion *screen_region = NULL; - - g_return_if_fail (region != NULL); - - gdk_region_get_rectangles (region, &rects, &n_rects); - -- if (term->priv->changed) -- screen_region = gdk_region_new (); -+// if (term->priv->changed) -+// screen_region = gdk_region_new (); - - for (i = 0; i < n_rects; ++i) - { -@@ -455,22 +455,22 @@ moo_term_draw (MooTerm *term, - term_draw_range (term, drawable, - top_line + r->y + j, - r->x, r->width); -- -- if (screen_region) -- gdk_region_union_with_rect (screen_region, r); -+// -+// if (screen_region) -+// gdk_region_union_with_rect (screen_region, r); - } - } - -- if (term->priv->changed && !gdk_region_empty (screen_region)) -- { -- gdk_region_subtract (term->priv->changed, -- screen_region); -- if (gdk_region_empty (term->priv->changed)) -- region_destroy (&term->priv->changed); -- } -- -- if (screen_region) -- gdk_region_destroy (screen_region); -+// if (term->priv->changed && !gdk_region_empty (screen_region)) -+// { -+// gdk_region_subtract (term->priv->changed, -+// screen_region); -+// if (gdk_region_empty (term->priv->changed)) -+// region_destroy (&term->priv->changed); -+// } -+ -+// if (screen_region) -+// gdk_region_destroy (screen_region); - - g_free (rects); - } -@@ -501,107 +501,110 @@ region_union_with_rect (GdkRegion **re - } - - --static gboolean --update_timeout (MooTerm *term) --{ -- GdkRegion *region, *changed, *clip_region; -- GdkRectangle *rectangles; -- int n_rectangles, i; -- int top_line = term_top_line (term); -- int scrollback = buf_scrollback (term->priv->buffer); -- GdkWindow *window = GTK_WIDGET(term)->window; -- gboolean need_redraw = FALSE; -- GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; -- -- if (!GTK_WIDGET_DRAWABLE (term)) -- return TRUE; -- -- gdk_window_freeze_updates (window); -- -- if (!term->priv->changed && -- term->priv->cursor_col == term->priv->cursor_col_old && -- term->priv->cursor_row == term->priv->cursor_row_old) -- goto out; -- -- if (term->priv->changed) -- { -- changed = term->priv->changed; -- term->priv->changed = NULL; -- } -- else -- { -- changed = gdk_region_new (); -- } -- -- if (term->priv->cursor_col != term->priv->cursor_col_old || -- term->priv->cursor_row != term->priv->cursor_row_old) -- { -- int row; -- -- row = scrollback + term->priv->cursor_row - top_line; -- if (term->priv->cursor_col < term->priv->width && -- row >= 0 && row < (int) term->priv->height) -- { -- GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; -- gdk_region_union_with_rect (changed, &rect); -- } -- -- row = scrollback + term->priv->cursor_row_old - top_line; -- if (term->priv->cursor_col_old < term->priv->width && -- row >= 0 && row < (int) term->priv->height) -- { -- GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; -- gdk_region_union_with_rect (changed, &rect); -- } -- } -- -- clip_region = gdk_region_rectangle (&clip); -- gdk_region_intersect (changed, clip_region); -- gdk_region_destroy (clip_region); -- -- if (gdk_region_empty (changed)) -- { -- gdk_region_destroy (changed); -- goto out; -- } -- -- gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); -- g_return_val_if_fail (n_rectangles > 0, TRUE); -- -- for (i = 0; i < n_rectangles; ++i) -- { -- rect_screen_to_window (term, &rectangles[i], &rectangles[i]); -- } -- -- region = gdk_region_rectangle (&rectangles[0]); -- -- for (i = 1; i < n_rectangles; ++i) -- gdk_region_union_with_rect (region, &rectangles[i]); -- -- gdk_window_invalidate_region (window, region, FALSE); -- need_redraw = TRUE; -- -- g_free (rectangles); -- gdk_region_destroy (region); -- gdk_region_destroy (changed); -- --out: -- term->priv->cursor_col_old = term->priv->cursor_col; -- term->priv->cursor_row_old = term->priv->cursor_row; -- gdk_window_thaw_updates (window); -- -- if (need_redraw) -- { -- if (g_timer_elapsed (term->priv->redraw_timer, NULL) > REDRAW_INTERVAL) -- gdk_window_process_updates (GTK_WIDGET(term)->window, FALSE); -- } -- else -- { -- g_timer_start (term->priv->redraw_timer); -- } -- -- return TRUE; --} -+// static gboolean -+// update_timeout (MooTerm *term) -+// { -+// GdkRegion *region, *changed, *clip_region; -+// GdkRectangle *rectangles; -+// int n_rectangles, i; -+// int top_line = term_top_line (term); -+// int scrollback = buf_scrollback (term->priv->buffer); -+// GdkWindow *window = GTK_WIDGET(term)->window; -+// gboolean need_redraw = FALSE; -+// GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; -+// -+// if (!GTK_WIDGET_DRAWABLE (term)) -+// return TRUE; -+// -+// gdk_window_freeze_updates (window); -+// -+// if (!term->priv->changed && -+// term->priv->cursor_col == term->priv->cursor_col_old && -+// term->priv->cursor_row == term->priv->cursor_row_old) -+// goto out; -+// -+// if (term->priv->changed) -+// { -+// changed = term->priv->changed; -+// term->priv->changed = NULL; -+// } -+// else -+// { -+// changed = gdk_region_new (); -+// } -+// -+// if (term->priv->cursor_col != term->priv->cursor_col_old || -+// term->priv->cursor_row != term->priv->cursor_row_old) -+// { -+// int row; -+// -+// row = scrollback + term->priv->cursor_row - top_line; -+// if (term->priv->cursor_col < term->priv->width && -+// row >= 0 && row < (int) term->priv->height) -+// { -+// GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; -+// gdk_region_union_with_rect (changed, &rect); -+// } -+// -+// row = scrollback + term->priv->cursor_row_old - top_line; -+// if (term->priv->cursor_col_old < term->priv->width && -+// row >= 0 && row < (int) term->priv->height) -+// { -+// GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; -+// gdk_region_union_with_rect (changed, &rect); -+// } -+// } -+// -+// clip_region = gdk_region_rectangle (&clip); -+// gdk_region_intersect (changed, clip_region); -+// gdk_region_destroy (clip_region); -+// -+// if (gdk_region_empty (changed)) -+// { -+// gdk_region_destroy (changed); -+// goto out; -+// } -+// -+// gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); -+// g_return_val_if_fail (n_rectangles > 0, TRUE); -+// -+// for (i = 0; i < n_rectangles; ++i) -+// { -+// rect_screen_to_window (term, &rectangles[i], &rectangles[i]); -+// } -+// -+// region = gdk_region_rectangle (&rectangles[0]); -+// -+// for (i = 1; i < n_rectangles; ++i) -+// gdk_region_union_with_rect (region, &rectangles[i]); -+// -+// gdk_window_invalidate_region (window, region, FALSE); -+// need_redraw = TRUE; -+// -+// g_free (rectangles); -+// gdk_region_destroy (region); -+// gdk_region_destroy (changed); -+// -+// out: -+// term->priv->cursor_col_old = term->priv->cursor_col; -+// term->priv->cursor_row_old = term->priv->cursor_row; -+// gdk_window_thaw_updates (window); -+// -+// if (need_redraw) -+// { -+// if (g_timer_elapsed (term->priv->redraw_timer, NULL) > REDRAW_INTERVAL) -+// { -+// gdk_window_process_updates (GTK_WIDGET(term)->window, FALSE); -+// g_timer_start (term->priv->redraw_timer); -+// } -+// } -+// else -+// { -+// g_timer_start (term->priv->redraw_timer); -+// } -+// -+// return TRUE; -+// } - - - gboolean -@@ -612,12 +615,10 @@ _moo_term_expose_event (GtkWidget * - GdkRegion *text_region; - MooTerm *term = MOO_TERM (widget); - -+ if (widget->window != event->window) -+ return FALSE; -+ - g_assert (term_top_line (term) <= buf_scrollback (term->priv->buffer)); -- -- if (!term->priv->update_timeout) -- term->priv->update_timeout = -- g_timeout_add_full (UPDATE_PRIORITY, UPDATE_TIMEOUT, -- (GSourceFunc) update_timeout, term, NULL); - - text_rec.width = PIXEL_WIDTH (term); - text_rec.height = PIXEL_HEIGHT (term); -@@ -627,10 +628,8 @@ _moo_term_expose_event (GtkWidget * - if (!gdk_region_empty (text_region)) - moo_term_draw (term, event->window, text_region); - -- g_timer_start (term->priv->redraw_timer); -- - gdk_region_destroy (text_region); -- return TRUE; -+ return FALSE; - } - - -@@ -1002,20 +1001,21 @@ term_draw_cursor (MooTerm *term, - } - - --void --_moo_term_buf_content_changed (MooTerm *term, -- MooTermBuffer *buf) -+static void -+add_buffer_changed (MooTerm *term) - { - GdkRegion *changed; - guint top_line, scrollback; - int height; -+ MooTermBuffer *buf; - - if (!GTK_WIDGET_DRAWABLE (term)) - return; - -+ buf = term->priv->buffer; - changed = buf->priv->changed; - -- if (buf != term->priv->buffer || !changed || gdk_region_empty (changed)) -+ if (!changed || gdk_region_empty (changed)) - return; - - buf->priv->changed = NULL; -@@ -1056,6 +1056,157 @@ _moo_term_buf_content_changed (MooTerm - } - - -+static gboolean -+vte_invalidate_region (MooTerm *term) -+{ -+ GdkRegion *region, *changed, *clip_region; -+ GdkRectangle *rectangles; -+ int n_rectangles, i; -+ int top_line = term_top_line (term); -+ int scrollback = buf_scrollback (term->priv->buffer); -+ GdkWindow *window = GTK_WIDGET(term)->window; -+ gboolean need_redraw = FALSE; -+ GdkRectangle clip = {0, 0, term->priv->width, term->priv->height}; -+ -+ if (!GTK_WIDGET_DRAWABLE (term)) -+ return FALSE; -+ -+ add_buffer_changed (term); -+ -+ if (!term->priv->changed && -+ term->priv->cursor_col == term->priv->cursor_col_old && -+ term->priv->cursor_row == term->priv->cursor_row_old) -+ goto out; -+ -+ if (term->priv->changed) -+ { -+ changed = term->priv->changed; -+ term->priv->changed = NULL; -+ } -+ else -+ { -+ changed = gdk_region_new (); -+ } -+ -+ if (term->priv->cursor_col != term->priv->cursor_col_old || -+ term->priv->cursor_row != term->priv->cursor_row_old) -+ { -+ int row; -+ -+ row = scrollback + term->priv->cursor_row - top_line; -+ if (term->priv->cursor_col < term->priv->width && -+ row >= 0 && row < (int) term->priv->height) -+ { -+ GdkRectangle rect = {term->priv->cursor_col, row, 1, 1}; -+ gdk_region_union_with_rect (changed, &rect); -+ } -+ -+ row = scrollback + term->priv->cursor_row_old - top_line; -+ if (term->priv->cursor_col_old < term->priv->width && -+ row >= 0 && row < (int) term->priv->height) -+ { -+ GdkRectangle rect = {term->priv->cursor_col_old, row, 1, 1}; -+ gdk_region_union_with_rect (changed, &rect); -+ } -+ } -+ -+ clip_region = gdk_region_rectangle (&clip); -+ gdk_region_intersect (changed, clip_region); -+ gdk_region_destroy (clip_region); -+ -+ if (gdk_region_empty (changed)) -+ { -+ gdk_region_destroy (changed); -+ goto out; -+ } -+ -+ gdk_region_get_rectangles (changed, &rectangles, &n_rectangles); -+ g_return_val_if_fail (n_rectangles > 0, TRUE); -+ -+ for (i = 0; i < n_rectangles; ++i) -+ { -+ rect_screen_to_window (term, &rectangles[i], &rectangles[i]); -+ } -+ -+ region = gdk_region_rectangle (&rectangles[0]); -+ -+ for (i = 1; i < n_rectangles; ++i) -+ gdk_region_union_with_rect (region, &rectangles[i]); -+ -+ gdk_window_invalidate_region (window, region, FALSE); -+ need_redraw = TRUE; -+ -+ g_free (rectangles); -+ gdk_region_destroy (region); -+ gdk_region_destroy (changed); -+ -+out: -+ term->priv->cursor_col_old = term->priv->cursor_col; -+ term->priv->cursor_row_old = term->priv->cursor_row; -+ -+ return need_redraw; -+} -+ -+static gboolean -+vte_update_delay_timeout (MooTerm *term) -+{ -+ /* We only stop the timer if no update request was received in this -+ * past cycle. -+ */ -+ if (vte_invalidate_region (term)) -+ return TRUE; -+ -+ term->priv->update_timer = 0; -+ return FALSE; -+} -+ -+static gboolean -+vte_update_timeout (MooTerm *term) -+{ -+ vte_invalidate_region (term); -+ -+ /* Set a timer such that we do not invalidate for a while. */ -+ /* This limits the number of times we draw to ~40fps. */ -+ term->priv->update_timer = -+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, -+ VTE_UPDATE_REPEAT_TIMEOUT, -+ (GSourceFunc) vte_update_delay_timeout, -+ term, NULL); -+ -+ return FALSE; -+} -+ -+static void -+add_update_timeout (MooTerm *term) -+{ -+ if (!term->priv->update_timer) -+ term->priv->update_timer = -+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, -+ VTE_UPDATE_TIMEOUT, -+ (GSourceFunc) vte_update_timeout, -+ term, NULL); -+} -+ -+void -+_moo_term_buf_content_changed (MooTerm *term, -+ MooTermBuffer *buf) -+{ -+ GdkRegion *changed; -+ guint top_line, scrollback; -+ int height; -+ -+ if (!GTK_WIDGET_DRAWABLE (term)) -+ return; -+ -+ changed = buf->priv->changed; -+ -+ if (buf != term->priv->buffer || !changed || gdk_region_empty (changed)) -+ return; -+ -+ add_update_timeout (term); -+} -+ -+ - void - _moo_term_buffer_scrolled (MooTermBuffer *buf, - guint lines, -@@ -1065,6 +1216,7 @@ _moo_term_buffer_scrolled (MooTermBuffer - { - GdkRectangle rect = {0, 0, term->priv->width, term->priv->height}; - region_union_with_rect (&term->priv->changed, &rect); -+ add_update_timeout (term); - } - } - -diff -r 6e0a42baf315 moo/mooterm/mooterm-private.h ---- a/moo/mooterm/mooterm-private.h Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mooterm-private.h Thu Jun 08 20:30:03 2006 -0500 -@@ -44,6 +44,11 @@ G_BEGIN_DECLS - #define UPDATE_TIMEOUT 30 - #define REDRAW_INTERVAL 0.6 - -+#define VTE_UPDATE_TIMEOUT 10 -+#define VTE_UPDATE_REPEAT_TIMEOUT 25 -+#define VTE_COALESCE_TIMEOUT 10 -+#define INPUT_CHUNK_SIZE 4096 -+ - #define MIN_TERMINAL_WIDTH 8 - #define MIN_TERMINAL_HEIGHT 4 - #define MAX_TERMINAL_WIDTH 4096 -@@ -81,6 +86,8 @@ struct _MooTermPrivate { - struct _MooTermPrivate { - struct _MooTermPt *pt; - struct _MooTermParser *parser; -+ GString *incoming; -+ guint process_timeout; - - struct _MooTermBuffer *buffer; - struct _MooTermBuffer *primary_buffer; -@@ -115,10 +122,9 @@ struct _MooTermPrivate { - MooTermFont *font; - - GdkRegion *changed; /* screen coordinates */ -- guint update_timeout; -- GTimer *redraw_timer; - guint cursor_row_old; /* cursor has been here, and it's been invalidated */ - guint cursor_col_old; -+ guint update_timer; - - GdkGC *clip; - gboolean font_changed; -@@ -242,6 +248,8 @@ void _moo_term_set_cursor_blinks - void _moo_term_set_cursor_blinks (MooTerm *term, - gboolean blinks); - -+gsize _moo_term_get_input_chunk_len (MooTerm *term); -+ - - /*************************************************************************/ - /* vt commands -diff -r 6e0a42baf315 moo/mooterm/mooterm-text.c ---- a/moo/mooterm/mooterm-text.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mooterm-text.c Thu Jun 08 20:30:03 2006 -0500 -@@ -205,7 +205,8 @@ static int segment_sym_diff (Segment *s1 - } - - --static void invalidate_segment (Segment *segm, guint num) -+static void -+invalidate_segment (Segment *segm, guint num) - { - MooTerm *term; - int top_line; -@@ -223,7 +224,7 @@ static void invalidate_segment (Segment - MooTermIter end = segm[i].end; - GdkRectangle rect; - -- _moo_term_iter_order (&start, &end); -+ _moo_term_iter_order (&start, &end); - - if (ITER_ROW (&start) < ITER_ROW (&end)) - { -diff -r 6e0a42baf315 moo/mooterm/mooterm.c ---- a/moo/mooterm/mooterm.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mooterm.c Thu Jun 08 20:30:03 2006 -0500 -@@ -257,7 +257,7 @@ moo_term_init (MooTerm *term) - term->priv->pt = _moo_term_pt_new (term); - g_signal_connect_swapped (term->priv->pt, "child-died", - G_CALLBACK (child_died), term); -- -+ term->priv->incoming = g_string_new_len (NULL, INPUT_CHUNK_SIZE); - term->priv->parser = _moo_term_parser_new (term); - - _moo_term_init_palette (term); -@@ -270,9 +270,6 @@ moo_term_init (MooTerm *term) - - term->priv->width = 80; - term->priv->height = 24; -- -- term->priv->redraw_timer = g_timer_new (); -- g_timer_stop (term->priv->redraw_timer); - - term->priv->selection = _moo_term_selection_new (term); - -@@ -360,11 +357,16 @@ moo_term_init (MooTerm *term) - - #define OBJECT_UNREF(obj__) if (obj__) g_object_unref (obj__) - --static void moo_term_finalize (GObject *object) -+static void -+moo_term_finalize (GObject *object) - { - guint i, j; - MooTerm *term = MOO_TERM (object); - -+ if (term->priv->process_timeout) -+ g_source_remove (term->priv->process_timeout); -+ g_string_free (term->priv->incoming, TRUE); -+ - if (term->priv->cursor_blink_timeout_id) - g_source_remove (term->priv->cursor_blink_timeout_id); - -@@ -381,8 +383,6 @@ static void moo_term_finalize - - if (term->priv->changed) - gdk_region_destroy (term->priv->changed); -- -- g_timer_destroy (term->priv->redraw_timer); - - OBJECT_UNREF (term->priv->layout); - -@@ -557,9 +557,9 @@ moo_term_unrealize (GtkWidget *widget) - guint i; - MooTerm *term = MOO_TERM (widget); - -- if (term->priv->update_timeout) -- g_source_remove (term->priv->update_timeout); -- term->priv->update_timeout = 0; -+ if (term->priv->update_timer) -+ g_source_remove (term->priv->update_timer); -+ term->priv->update_timer = 0; - - if (term->priv->menu) - g_object_unref (term->priv->menu); -@@ -1070,10 +1070,45 @@ moo_term_paste_clipboard (MooTerm - } - - --void --moo_term_feed (MooTerm *term, -- const char *data, -- int len) -+static gboolean -+process_incoming (MooTerm *term) -+{ -+ gboolean done; -+ -+// if (term->priv->incoming->len > 2*INPUT_CHUNK_SIZE) -+// g_print ("process_incoming: %d chars\n", -+// term->priv->incoming->len); -+ -+ done = !term->priv->incoming->len || -+ _moo_term_parser_parse (term->priv->parser, -+ term->priv->incoming->str, -+ term->priv->incoming->len); -+ -+ if (term->priv->incoming->len > INPUT_CHUNK_SIZE) -+ { -+ g_string_free (term->priv->incoming, TRUE); -+ term->priv->incoming = g_string_new_len (NULL, INPUT_CHUNK_SIZE); -+ } -+ else -+ { -+ g_string_truncate (term->priv->incoming, 0); -+ } -+ -+ term->priv->process_timeout = 0; -+ -+ if (!done) -+ term->priv->process_timeout = -+ g_timeout_add (VTE_COALESCE_TIMEOUT, -+ (GSourceFunc) process_incoming, -+ term); -+ -+ return FALSE; -+} -+ -+void -+moo_term_feed (MooTerm *term, -+ const char *data, -+ int len) - { - if (!len) - return; -@@ -1083,7 +1118,29 @@ moo_term_feed (MooTerm *term, - if (len < 0) - len = strlen (data); - -- _moo_term_parser_parse (term->priv->parser, data, len); -+// g_print ("moo_term_feed: %d chars\n", len); -+ g_string_append_len (term->priv->incoming, data, len); -+ -+ if (!term->priv->process_timeout) -+ term->priv->process_timeout = -+ g_timeout_add (VTE_COALESCE_TIMEOUT, -+ (GSourceFunc) process_incoming, -+ term); -+} -+ -+ -+gsize -+_moo_term_get_input_chunk_len (MooTerm *term) -+{ -+ switch (term->priv->incoming->len / INPUT_CHUNK_SIZE) -+ { -+ case 0: -+ return INPUT_CHUNK_SIZE - term->priv->incoming->len; -+ case 1: -+ return INPUT_CHUNK_SIZE / 2; -+ default: -+ return 0; -+ } - } - - -diff -r 6e0a42baf315 moo/mooterm/mootermparser.c ---- a/moo/mooterm/mootermparser.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mootermparser.c Thu Jun 08 20:30:03 2006 -0500 -@@ -60,7 +60,8 @@ static void exec_dcs (MooTerm - - #define iter_free g_free - --static InputIter *iter_new (MooTermParser *parser) -+static InputIter * -+iter_new (MooTermParser *parser) - { - InputIter *iter = g_new (InputIter, 1); - -@@ -72,14 +73,16 @@ static InputIter *iter_new (MooTermParse - } - - --static gboolean iter_eof (InputIter *iter) -+static gboolean -+iter_eof (InputIter *iter) - { - return !iter->old && iter->offset >= - iter->parser->input.data_len; - } - - --static void iter_forward (InputIter *iter) -+static void -+iter_forward (InputIter *iter) - { - g_assert (!iter_eof (iter)); - -@@ -97,7 +100,8 @@ static void iter_forward (InputIter *ite - } - - --static void iter_backward (InputIter *iter) -+static void -+iter_backward (InputIter *iter) - { - g_assert (iter->offset || - (!iter->old && iter->parser->input.old_data->len)); -@@ -115,14 +119,16 @@ static void iter_backward (InputIter *it - } - - --static void iter_set_eof (InputIter *iter) -+static void -+iter_set_eof (InputIter *iter) - { - iter->old = FALSE; - iter->offset = iter->parser->input.data_len; - } - - --static guchar iter_get_char (InputIter *iter) -+static guchar -+iter_get_char (InputIter *iter) - { - g_assert (!iter_eof (iter)); - -@@ -133,7 +139,8 @@ static guchar iter_get_char (InputIter * - } - - --static void save_cmd (MooTermParser *parser) -+static void -+save_cmd (MooTermParser *parser) - { - GString *old = parser->input.old_data; - guint offset = parser->cmd_start->offset; -@@ -168,7 +175,8 @@ static void save_cmd (MooTermParser *par - } - - --static void save_character (MooTermParser *parser) -+static void -+save_character (MooTermParser *parser) - { - g_string_truncate (parser->input.old_data, 0); - g_string_append_len (parser->input.old_data, -@@ -178,7 +186,9 @@ static void save_character (MooTermParse - } - - --static void one_char_cmd (MooTermParser *parser, guchar c) -+static void -+one_char_cmd (MooTermParser *parser, -+ guchar c) - { - flush_chars (parser); - DEBUG_ONE_CHAR(c); -@@ -276,7 +286,8 @@ static void one_char_cmd (MooTermParser - - - /* returns 0 on end of input */ --static guchar get_char (MooTermParser *parser) -+static guchar -+get_char (MooTermParser *parser) - { - guchar c = 0; - -@@ -304,19 +315,22 @@ static guchar get_char (MooTermParser *p - } - - --static void flush_chars (MooTermParser *parser) -+static void -+flush_chars (MooTermParser *parser) - { - if (parser->character->len) - { -- g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, -- parser->character->str); -+// g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, -+// parser->character->str); - VT_PRINT_CHAR (ERROR_CHAR); - g_string_truncate (parser->character, 0); - } - } - - --static void process_char (MooTermParser *parser, guchar c) -+static void -+process_char (MooTermParser *parser, -+ guchar c) - { - if (parser->character->len || c >= 128) - { -@@ -333,8 +347,8 @@ static void process_char (MooTermParser - break; - - case -1: -- g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, -- parser->character->str); -+// g_warning ("%s: invalid UTF8 '%s'", G_STRLOC, -+// parser->character->str); - VT_PRINT_CHAR (ERROR_CHAR); - g_string_truncate (parser->character, 0); - break; -@@ -352,7 +366,8 @@ static void process_char (MooTermParser - } - - --static void parser_init (MooTermParser *parser) -+static void -+parser_init (MooTermParser *parser) - { - parser->save = FALSE; - -@@ -377,7 +392,8 @@ static void parser_init (MooTermParser - } - - --static void parser_finish (MooTermParser *parser) -+static void -+parser_finish (MooTermParser *parser) - { - if (!parser->save) - g_string_truncate (parser->input.old_data, 0); -@@ -385,7 +401,7 @@ static void parser_finish (MooTermParser - - - MooTermParser* --_moo_term_parser_new (MooTerm *term) -+_moo_term_parser_new (MooTerm *term) - { - MooTermParser *p = g_new0 (MooTermParser, 1); - -@@ -437,10 +453,10 @@ _moo_term_parser_free (MooTermParser *p - } - - --void --_moo_term_parser_parse (MooTermParser *parser, -- const char *string, -- guint len) -+static void -+parser_do_parse (MooTermParser *parser, -+ const char *string, -+ guint len) - { - guchar c; - -@@ -801,12 +817,27 @@ STATE_DCS_ESCAPE_: - } - - -+gboolean -+_moo_term_parser_parse (MooTermParser *parser, -+ const char *string, -+ guint len) -+{ -+ parser_do_parse (parser, string, len); -+ -+// if (parser->save) -+// g_print ("saved %d chars\n", parser->input.old_data->len); -+ -+ return !parser->save; -+} -+ -+ - /***************************************************************************/ - /* Parsing and executing received command sequence - */ - --static void exec_cmd (MooTermParser *parser, -- guchar cmd) -+static void -+exec_cmd (MooTermParser *parser, -+ guchar cmd) - { - switch (cmd) - { -@@ -871,8 +902,9 @@ static void exec_cmd (MooT - } - - --static void init_yyparse (MooTermParser *parser, -- LexType lex_type) -+static void -+init_yyparse (MooTermParser *parser, -+ LexType lex_type) - { - parser->lex.lex = lex_type; - parser->lex.part = PART_START; -@@ -882,7 +914,8 @@ static void init_yyparse (MooTermPars - } - - --int _moo_term_yylex (MooTermParser *parser) -+int -+_moo_term_yylex (MooTermParser *parser) - { - guint offset = parser->lex.offset; - -@@ -1042,7 +1075,8 @@ int _moo_term_yylex (MooTermParser - } - - --char *_moo_term_current_ctl (MooTermParser *parser) -+char * -+_moo_term_current_ctl (MooTermParser *parser) - { - GString *s; - char *nice; -@@ -1087,7 +1121,8 @@ char *_moo_term_current_ctl - } - - --static void exec_escape_sequence (MooTermParser *parser) -+static void -+exec_escape_sequence (MooTermParser *parser) - { - init_yyparse (parser, LEX_ESCAPE); - DEBUG_CONTROL; -@@ -1095,7 +1130,8 @@ static void exec_escape_sequence (MooT - } - - --static void exec_csi (MooTermParser *parser) -+static void -+exec_csi (MooTermParser *parser) - { - init_yyparse (parser, LEX_CONTROL); - DEBUG_CONTROL; -@@ -1103,7 +1139,8 @@ static void exec_csi (MooT - } - - --static void exec_dcs (MooTermParser *parser) -+static void -+exec_dcs (MooTermParser *parser) - { - init_yyparse (parser, LEX_DCS); - DEBUG_CONTROL; -@@ -1111,8 +1148,9 @@ static void exec_dcs (MooT - } - - --void _moo_term_yyerror (MooTermParser *parser, -- G_GNUC_UNUSED const char *string) -+void -+_moo_term_yyerror (MooTermParser *parser, -+ G_GNUC_UNUSED const char *string) - { - char *s = _moo_term_current_ctl (parser); - g_warning ("parse error: '%s'\n", s); -@@ -1120,8 +1158,9 @@ void _moo_term_yyerror - } - - --static void exec_apc (MooTermParser *parser, -- guchar final) -+static void -+exec_apc (MooTermParser *parser, -+ guchar final) - { - char *s = g_strdup_printf ("\237%s%c", parser->data->str, final); - char *nice = _moo_term_nice_bytes (s, -1); -@@ -1131,8 +1170,9 @@ static void exec_apc (MooT - } - - --static void exec_pm (MooTermParser *parser, -- guchar final) -+static void -+exec_pm (MooTermParser *parser, -+ guchar final) - { - char *s = g_strdup_printf ("\236%s%c", parser->data->str, final); - char *nice = _moo_term_nice_bytes (s, -1); -@@ -1142,8 +1182,9 @@ static void exec_pm (MooT - } - - --static void exec_osc (MooTermParser *parser, -- guchar final) -+static void -+exec_osc (MooTermParser *parser, -+ guchar final) - { - if (parser->data->len >= 2 && - parser->data->str[0] >= '0' && -@@ -1178,58 +1219,56 @@ static void exec_osc (MooT - } - - --char *_moo_term_nice_char (guchar c) -+char * -+_moo_term_nice_char (guchar c) - { - if (' ' <= c && c <= '~') -- { - return g_strndup ((char*)&c, 1); -- } -- else -- { -- switch (c) -- { -- case 0x1B: -- return g_strdup (""); -- case 0x84: -- return g_strdup (""); -- case 0x85: -- return g_strdup (""); -- case 0x88: -- return g_strdup (""); -- case 0x8D: -- return g_strdup (""); -- case 0x8E: -- return g_strdup (""); -- case 0x8F: -- return g_strdup (""); -- case 0x90: -- return g_strdup (""); -- case 0x98: -- return g_strdup (""); -- case 0x9A: -- return g_strdup (""); -- case 0x9B: -- return g_strdup (""); -- case 0x9C: -- return g_strdup (""); -- case 0x9D: -- return g_strdup (""); -- case 0x9E: -- return g_strdup (""); -- case 0x9F: -- return g_strdup (""); -- default: -- if ('A' - 64 <= c && c <= ']' - 64) -- return g_strdup_printf ("^%c", c + 64); -- else -- return g_strdup_printf ("<%d>", c); -- } -- } --} -- -- --char *_moo_term_nice_bytes (const char *string, -- int len) -+ -+ switch (c) -+ { -+ case 0x1B: -+ return g_strdup (""); -+ case 0x84: -+ return g_strdup (""); -+ case 0x85: -+ return g_strdup (""); -+ case 0x88: -+ return g_strdup (""); -+ case 0x8D: -+ return g_strdup (""); -+ case 0x8E: -+ return g_strdup (""); -+ case 0x8F: -+ return g_strdup (""); -+ case 0x90: -+ return g_strdup (""); -+ case 0x98: -+ return g_strdup (""); -+ case 0x9A: -+ return g_strdup (""); -+ case 0x9B: -+ return g_strdup (""); -+ case 0x9C: -+ return g_strdup (""); -+ case 0x9D: -+ return g_strdup (""); -+ case 0x9E: -+ return g_strdup (""); -+ case 0x9F: -+ return g_strdup (""); -+ } -+ -+ if ('A' - 64 <= c && c <= ']' - 64) -+ return g_strdup_printf ("^%c", c + 64); -+ else -+ return g_strdup_printf ("<%d>", c); -+} -+ -+ -+char * -+_moo_term_nice_bytes (const char *string, -+ int len) - { - int i; - GString *str; -diff -r 6e0a42baf315 moo/mooterm/mootermparser.h ---- a/moo/mooterm/mootermparser.h Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mootermparser.h Thu Jun 08 20:30:03 2006 -0500 -@@ -90,7 +90,7 @@ MooTermParser *_moo_term_parser_new - MooTermParser *_moo_term_parser_new (MooTerm *term); - void _moo_term_parser_free (MooTermParser *parser); - --void _moo_term_parser_parse (MooTermParser *parser, -+gboolean _moo_term_parser_parse (MooTermParser *parser, - const char *string, - guint len); - void _moo_term_parser_reset (MooTermParser *parser); -diff -r 6e0a42baf315 moo/mooterm/mootermpt-cygwin.c ---- a/moo/mooterm/mootermpt-cygwin.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mootermpt-cygwin.c Thu Jun 08 20:30:03 2006 -0500 -@@ -193,10 +193,11 @@ fork_command (MooTermPt *pt_gen, - pt->out_io = g_io_channel_win32_new_fd (pt->out); - g_io_channel_set_encoding (pt->out_io, NULL, NULL); - g_io_channel_set_buffered (pt->in_io, FALSE); -- pt->out_watch_id = g_io_add_watch (pt->out_io, -- (GIOCondition)(G_IO_IN | G_IO_PRI | G_IO_HUP), -- (GIOFunc) read_helper_out, -- pt); -+ pt->out_watch_id = g_io_add_watch_full (pt->out_io, -+ G_PRIORITY_DEFAULT_IDLE, -+ G_IO_IN | G_IO_PRI | G_IO_HUP, -+ (GIOFunc) read_helper_out, -+ pt, NULL); - - // GSource *src = g_main_context_find_source_by_id (NULL, helper.out_watch_id); - // if (src) g_source_set_priority (src, READ_HELPER_OUT_PRIORITY); -diff -r 6e0a42baf315 moo/mooterm/mootermpt-unix.c ---- a/moo/mooterm/mootermpt-unix.c Thu Jun 08 11:19:52 2006 -0500 -+++ b/moo/mooterm/mootermpt-unix.c Thu Jun 08 20:30:03 2006 -0500 -@@ -37,7 +37,6 @@ - #endif - - #define TERM_EMULATION "xterm" --#define READ_CHUNK_SIZE 1024 - #define WRITE_CHUNK_SIZE 4096 - #define POLL_TIME 5 - #define POLL_NUM 1 -@@ -258,10 +257,11 @@ fork_argv (MooTermPt *pt_gen, - g_io_channel_set_encoding (pt->io, NULL, NULL); - g_io_channel_set_buffered (pt->io, FALSE); - -- pt->io_watch_id = g_io_add_watch (pt->io, -- G_IO_IN | G_IO_PRI | G_IO_HUP, -- (GIOFunc) read_child_out, -- pt); -+ pt->io_watch_id = g_io_add_watch_full (pt->io, -+ G_PRIORITY_DEFAULT_IDLE, -+ G_IO_IN | G_IO_PRI | G_IO_HUP, -+ (GIOFunc) read_child_out, -+ pt, NULL); - - src = g_main_context_find_source_by_id (NULL, pt->io_watch_id); - -@@ -328,28 +328,31 @@ static void kill_child (MooTerm - } - - --static gboolean read_child_out (G_GNUC_UNUSED GIOChannel *source, -- GIOCondition condition, -- MooTermPtUnix *pt) -+static gboolean -+read_child_out (G_GNUC_UNUSED GIOChannel *source, -+ GIOCondition condition, -+ MooTermPtUnix *pt) - { - gboolean error_occured = FALSE; - int error_no = 0; - -- char buf[READ_CHUNK_SIZE]; -- int current = 0; -+ char buf[INPUT_CHUNK_SIZE]; - guint again = POLL_NUM; -- -+ gsize to_read; -+ gsize current = 0; -+ -+ /* try to read leftover from the pipe */ - if (condition & G_IO_HUP) - { -- int r; -+ int bytes; - - g_message ("%s: G_IO_HUP", G_STRLOC); - error_no = errno; - -- r = read (pt->master, buf, READ_CHUNK_SIZE); -- -- if (r > 0) -- feed_buffer (pt, buf, r); -+ bytes = read (pt->master, buf, sizeof (buf)); -+ -+ if (bytes > 0) -+ feed_buffer (pt, buf, bytes); - - goto error; - } -@@ -362,11 +365,22 @@ static gboolean read_child_out (G_GNUC_ - - g_assert (condition & (G_IO_IN | G_IO_PRI)); - -+ to_read = _moo_term_get_input_chunk_len (MOO_TERM_PT(pt)->priv->term); -+ g_assert (to_read <= sizeof (buf)); -+ -+ if (!to_read) -+ { -+// g_print ("read_child_out: skipping\n"); -+ return TRUE; -+ } -+ - if (pt->non_block) - { -- int r = read (pt->master, buf, READ_CHUNK_SIZE); -- -- switch (r) -+ int bytes; -+ -+ bytes = read (pt->master, buf, to_read); -+ -+ switch (bytes) - { - case -1: - if (errno != EAGAIN && errno != EINTR) -@@ -388,14 +402,14 @@ static gboolean read_child_out (G_GNUC_ - g_free (s); - } - #endif -- feed_buffer (pt, buf, r); -+ feed_buffer (pt, buf, bytes); - break; - } - - return TRUE; - } - -- while (again && !error_occured && current < READ_CHUNK_SIZE) -+ while (again && !error_occured && current < to_read) - { - struct pollfd fd = {pt->master, POLLIN | POLLPRI, 0}; - -@@ -492,12 +506,12 @@ error: - } - - --static void feed_buffer (MooTermPtUnix *pt, -- const char *string, -- int len) --{ -- moo_term_feed (MOO_TERM_PT(pt)->priv->term, -- string, len); -+static void -+feed_buffer (MooTermPtUnix *pt, -+ const char *string, -+ int len) -+{ -+ moo_term_feed (MOO_TERM_PT(pt)->priv->term, string, len); - } - -