Making drawing like vte's
parent
bc4bf98bf4
commit
510eff37ce
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ("<ESC>");
|
||||
case 0x84:
|
||||
return g_strdup ("<IND>");
|
||||
case 0x85:
|
||||
return g_strdup ("<NEL>");
|
||||
case 0x88:
|
||||
return g_strdup ("<HTS>");
|
||||
case 0x8D:
|
||||
return g_strdup ("<RI>");
|
||||
case 0x8E:
|
||||
return g_strdup ("<SS2>");
|
||||
case 0x8F:
|
||||
return g_strdup ("<SS3>");
|
||||
case 0x90:
|
||||
return g_strdup ("<DCS>");
|
||||
case 0x98:
|
||||
return g_strdup ("<SOS>");
|
||||
case 0x9A:
|
||||
return g_strdup ("<DECID>");
|
||||
case 0x9B:
|
||||
return g_strdup ("<CSI>");
|
||||
case 0x9C:
|
||||
return g_strdup ("<ST>");
|
||||
case 0x9D:
|
||||
return g_strdup ("<OSC>");
|
||||
case 0x9E:
|
||||
return g_strdup ("<PM>");
|
||||
case 0x9F:
|
||||
return g_strdup ("<APC>");
|
||||
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 ("<ESC>");
|
||||
case 0x84:
|
||||
return g_strdup ("<IND>");
|
||||
case 0x85:
|
||||
return g_strdup ("<NEL>");
|
||||
case 0x88:
|
||||
return g_strdup ("<HTS>");
|
||||
case 0x8D:
|
||||
return g_strdup ("<RI>");
|
||||
case 0x8E:
|
||||
return g_strdup ("<SS2>");
|
||||
case 0x8F:
|
||||
return g_strdup ("<SS3>");
|
||||
case 0x90:
|
||||
return g_strdup ("<DCS>");
|
||||
case 0x98:
|
||||
return g_strdup ("<SOS>");
|
||||
case 0x9A:
|
||||
return g_strdup ("<DECID>");
|
||||
case 0x9B:
|
||||
return g_strdup ("<CSI>");
|
||||
case 0x9C:
|
||||
return g_strdup ("<ST>");
|
||||
case 0x9D:
|
||||
return g_strdup ("<OSC>");
|
||||
case 0x9E:
|
||||
return g_strdup ("<PM>");
|
||||
case 0x9F:
|
||||
return g_strdup ("<APC>");
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue