From ed255511ce08f3053fbe7b1a64ae137c7da17763 Mon Sep 17 00:00:00 2001 From: Yevgen Muntyan <17531749+muntyan@users.noreply.github.com> Date: Thu, 18 Jan 2007 03:21:30 -0600 Subject: [PATCH] moo_term_set_fd() --- moo/moopython/pygtk/mooterm-pygtk.defs | 9 ++ moo/mooterm/mooterm-draw.c | 2 +- moo/mooterm/mooterm-private.h | 3 +- moo/mooterm/mooterm.c | 27 +++-- moo/mooterm/mooterm.h | 3 + moo/mooterm/mootermpt-cygwin.c | 6 +- moo/mooterm/mootermpt-private.h | 1 + moo/mooterm/mootermpt-unix.c | 148 +++++++++++++++---------- moo/mooterm/mootermpt.c | 23 +++- moo/mooterm/mootermpt.h | 7 +- 10 files changed, 156 insertions(+), 73 deletions(-) diff --git a/moo/moopython/pygtk/mooterm-pygtk.defs b/moo/moopython/pygtk/mooterm-pygtk.defs index 8b8460a2..1c64ff1f 100644 --- a/moo/moopython/pygtk/mooterm-pygtk.defs +++ b/moo/moopython/pygtk/mooterm-pygtk.defs @@ -474,6 +474,15 @@ (return-type "none") ) +(define-method set_fd + (of-object "MooTerm") + (c-name "moo_term_set_fd") + (return-type "none") + (parameters + '("int" "fd") + ) +) + (define-function set_helper_directory (c-name "moo_term_set_helper_directory") (return-type "none") diff --git a/moo/mooterm/mooterm-draw.c b/moo/mooterm/mooterm-draw.c index 99c4448e..0484d49a 100644 --- a/moo/mooterm/mooterm-draw.c +++ b/moo/mooterm/mooterm-draw.c @@ -91,7 +91,7 @@ moo_term_update_font (MooTerm *term) font_calculate (term->priv->font); if (GTK_WIDGET_REALIZED (term)) - _moo_term_size_changed (term); + _moo_term_update_size (term, FALSE); } diff --git a/moo/mooterm/mooterm-private.h b/moo/mooterm/mooterm-private.h index 9ed2f8b6..e8d3102f 100644 --- a/moo/mooterm/mooterm-private.h +++ b/moo/mooterm/mooterm-private.h @@ -212,7 +212,8 @@ void _moo_term_buffer_scrolled (MooTermBuffer *buf, guint lines, MooTerm *term); -void _moo_term_size_changed (MooTerm *term); +void _moo_term_update_size (MooTerm *term, + gboolean force); void _moo_term_init_font_stuff (MooTerm *term); void _moo_term_init_palette (MooTerm *term); diff --git a/moo/mooterm/mooterm.c b/moo/mooterm/mooterm.c index 1b05dccf..1951fdde 100644 --- a/moo/mooterm/mooterm.c +++ b/moo/mooterm/mooterm.c @@ -493,7 +493,7 @@ static void moo_term_size_allocate (GtkWidget *widget, old_height / term_char_height(term) != allocation->height / term_char_height(term)) { - _moo_term_size_changed (term); + _moo_term_update_size (term, FALSE); } } } @@ -554,7 +554,7 @@ moo_term_realize (GtkWidget *widget) _moo_term_init_font_stuff (term); _moo_term_update_palette (term); - _moo_term_size_changed (term); + _moo_term_update_size (term, FALSE); term->priv->im = gtk_im_multicontext_new (); gtk_im_context_set_client_window (term->priv->im, widget->window); @@ -886,7 +886,8 @@ static void scroll_to_bottom (MooTerm *term, void -_moo_term_size_changed (MooTerm *term) +_moo_term_update_size (MooTerm *term, + gboolean force) { GtkWidget *widget = GTK_WIDGET (term); MooTermFont *font = term->priv->font; @@ -898,7 +899,7 @@ _moo_term_size_changed (MooTerm *term) old_width = term->priv->width; old_height = term->priv->height; - if (width == old_width && height == old_height) + if (!force && width == old_width && height == old_height) return; width = CLAMP (width, MIN_TERMINAL_WIDTH, MAX_TERMINAL_WIDTH); @@ -1002,7 +1003,7 @@ moo_term_feed_child (MooTerm *term, int len) { g_return_if_fail (MOO_IS_TERM (term) && string != NULL); - if (_moo_term_pt_child_alive (term->priv->pt)) + if (_moo_term_pt_alive (term->priv->pt)) _moo_term_pt_write (term->priv->pt, string, len); } @@ -1012,7 +1013,7 @@ moo_term_send_intr (MooTerm *term) { g_return_if_fail (MOO_IS_TERM (term)); - if (_moo_term_pt_child_alive (term->priv->pt)) + if (_moo_term_pt_alive (term->priv->pt)) _moo_term_pt_send_intr (term->priv->pt); } @@ -1960,10 +1961,10 @@ _moo_term_release_selection (MooTerm *term) gboolean -moo_term_child_alive (MooTerm *term) +moo_term_child_alive (MooTerm *term) { g_return_val_if_fail (MOO_IS_TERM (term), FALSE); - return _moo_term_pt_child_alive (term->priv->pt); + return _moo_term_pt_alive (term->priv->pt); } @@ -1976,6 +1977,16 @@ moo_term_kill_child (MooTerm *term) } +void +moo_term_set_fd (MooTerm *term, + int master) +{ + g_return_if_fail (MOO_IS_TERM (term)); + if (_moo_term_pt_set_fd (term->priv->pt, master) && GTK_WIDGET_REALIZED (term)) + _moo_term_update_size (term, TRUE); +} + + GType moo_term_command_get_type (void) { diff --git a/moo/mooterm/mooterm.h b/moo/mooterm/mooterm.h index 0dfe4130..3783ddb8 100644 --- a/moo/mooterm/mooterm.h +++ b/moo/mooterm/mooterm.h @@ -131,6 +131,9 @@ void moo_term_set_font_from_string (MooTerm *term, void moo_term_set_cursor_blink_time (MooTerm *term, guint ms); +void moo_term_set_fd (MooTerm *term, + int master); + void moo_term_reset (MooTerm *term); void moo_term_soft_reset (MooTerm *term); diff --git a/moo/mooterm/mootermpt-cygwin.c b/moo/mooterm/mootermpt-cygwin.c index 77017197..ce0b7027 100644 --- a/moo/mooterm/mootermpt-cygwin.c +++ b/moo/mooterm/mootermpt-cygwin.c @@ -126,10 +126,8 @@ _moo_term_pt_cyg_class_init (MooTermPtCygClass *klass) static void -_moo_term_pt_cyg_init (MooTermPtCyg *pt) +_moo_term_pt_cyg_init (MooTermPtCyg *pt) { - MOO_TERM_PT(pt)->priv->child_alive = FALSE; - pt->pid = (GPid) -1; pt->process_id = 0; pt->watch_id = 0; @@ -142,7 +140,7 @@ _moo_term_pt_cyg_init (MooTermPtCyg *pt) static void -moo_term_pt_cyg_finalize (GObject *object) +moo_term_pt_cyg_finalize (GObject *object) { MooTermPtCyg *pt = MOO_TERM_PT_CYG (object); kill_child (MOO_TERM_PT (pt)); diff --git a/moo/mooterm/mootermpt-private.h b/moo/mooterm/mootermpt-private.h index f5144e7a..86bbf3fd 100644 --- a/moo/mooterm/mootermpt-private.h +++ b/moo/mooterm/mootermpt-private.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS struct _MooTermPtPrivate { struct _MooTerm *term; gboolean child_alive; + gboolean alive; GQueue *pending_write; /* list->data is GByteArray* */ guint pending_write_id; }; diff --git a/moo/mooterm/mootermpt-unix.c b/moo/mooterm/mootermpt-unix.c index 5b20964f..e95b5ab6 100644 --- a/moo/mooterm/mootermpt-unix.c +++ b/moo/mooterm/mootermpt-unix.c @@ -92,6 +92,8 @@ static void pt_write (MooTermPt *pt, static void kill_child (MooTermPt *pt); static void send_intr (MooTermPt *pt); static char get_erase_char (MooTermPt *pt); +static gboolean set_fd (MooTermPt *pt, + int master); static gboolean read_child_out (GIOChannel *source, GIOCondition condition, @@ -122,14 +124,13 @@ _moo_term_pt_unix_class_init (MooTermPtUnixClass *klass) pt_class->kill_child = kill_child; pt_class->get_erase_char = get_erase_char; pt_class->send_intr = send_intr; + pt_class->set_fd = set_fd; } static void _moo_term_pt_unix_init (MooTermPtUnix *pt) { - MOO_TERM_PT(pt)->priv->child_alive = FALSE; - pt->child_pid = (GPid)-1; pt->master = -1; @@ -162,7 +163,7 @@ set_size (MooTermPt *pt, ptu = MOO_TERM_PT_UNIX (pt); - if (pt->priv->child_alive) + if (pt->priv->alive) _vte_pty_set_size (ptu->master, width, height); ptu->width = width; @@ -170,6 +171,46 @@ set_size (MooTermPt *pt, } +static gboolean +setup_master_fd (MooTermPtUnix *pt, + int master) +{ + int flags; + + g_return_val_if_fail (master >= 0, FALSE); + +#if 1 + _moo_message ("%s: attached to fd %d", + G_STRLOC, pt->master); +#endif + + pt->non_block = FALSE; + if ((flags = fcntl (master, F_GETFL)) < 0) + g_critical ("%s: F_GETFL on master", G_STRLOC); + else if (-1 == fcntl (master, F_SETFL, O_NONBLOCK | flags)) + g_critical ("%s: F_SETFL on master", G_STRLOC); + else + pt->non_block = TRUE; + + pt->io = g_io_channel_unix_new (master); + g_return_val_if_fail (pt->io != NULL, FALSE); + + 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_full (pt->io, + PT_READER_PRIORITY, + G_IO_IN | G_IO_PRI | G_IO_HUP, + (GIOFunc) read_child_out, + pt, NULL); + + pt->master = master; + MOO_TERM_PT(pt)->priv->alive = TRUE; + + return TRUE; +} + + static gboolean fork_argv (MooTermPt *pt_gen, char **argv, @@ -180,9 +221,9 @@ fork_argv (MooTermPt *pt_gen, MooTermPtUnix *pt; int env_len = 0; char **new_env; - int status, flags; + int status; int i; - GSource *src; + int master; g_return_val_if_fail (argv != NULL, FALSE); g_return_val_if_fail (MOO_IS_TERM_PT_UNIX (pt_gen), FALSE); @@ -213,15 +254,15 @@ fork_argv (MooTermPt *pt_gen, new_env[env_len] = g_strdup ("TERM=" TERM_EMULATION); new_env[env_len + 1] = NULL; - pt->master = _vte_pty_open (&pt->child_pid, new_env, - argv[0], - argv, - working_dir, - pt->width, pt->height, - FALSE, FALSE, FALSE); + master = _vte_pty_open (&pt->child_pid, new_env, + argv[0], + argv, + working_dir, + pt->width, pt->height, + FALSE, FALSE, FALSE); g_strfreev (new_env); - if (pt->master == -1) + if (master == -1) { g_critical ("%s: could not fork child", G_STRLOC); @@ -241,45 +282,34 @@ fork_argv (MooTermPt *pt_gen, { #if 1 _moo_message ("%s: forked child pid %d on fd %d", - G_STRLOC, pt->child_pid, pt->master); + G_STRLOC, pt->child_pid, master); #endif + pt_gen->priv->child_alive = TRUE; + pt_gen->priv->alive = TRUE; } if (waitpid (-1, &status, WNOHANG) == -1) g_critical ("%s: error in waitpid", G_STRLOC); - if ((flags = fcntl (pt->master, F_GETFL)) < 0) - g_critical ("%s: F_GETFL on master", G_STRLOC); - else if (-1 == fcntl (pt->master, F_SETFL, O_NONBLOCK | flags)) - g_critical ("%s: F_SETFL on master", G_STRLOC); - else - pt->non_block = TRUE; - - pt->io = g_io_channel_unix_new (pt->master); - g_return_val_if_fail (pt->io != NULL, FALSE); - - 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_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); - - if (src) - g_source_set_priority (src, PT_READER_PRIORITY); - else - g_warning ("%s: could not find io_watch_id source", G_STRLOC); - - pt_gen->priv->child_alive = TRUE; + setup_master_fd (pt, master); return TRUE; } +static gboolean +set_fd (MooTermPt *pt_gen, + int master) +{ + kill_child (pt_gen); + + if (master >= 0) + return setup_master_fd (MOO_TERM_PT_UNIX (pt_gen), master); + else + return TRUE; +} + + static gboolean fork_command (MooTermPt *pt_gen, const MooTermCommand *cmd, @@ -323,6 +353,7 @@ kill_child (MooTermPt *pt_gen) pt->non_block = FALSE; pt->child_pid = (GPid)-1; + pt_gen->priv->alive = FALSE; if (pt_gen->priv->child_alive) { @@ -351,7 +382,6 @@ read_child_out (G_GNUC_UNUSED GIOChannel *source, int bytes; _moo_message ("%s: G_IO_HUP", G_STRLOC); - error_no = errno; bytes = read (pt->master, buf, sizeof (buf)); @@ -527,10 +557,11 @@ feed_buffer (MooTermPtUnix *pt, /* writes given data to file, returns TRUE on successful write, FALSE when could not write al teh data, puts start of leftover to string, length of it to len, and fills err in case of error */ -static gboolean do_write (MooTermPt *pt_gen, - const char **string, - guint *plen, - int *err) +static gboolean +do_write (MooTermPt *pt_gen, + const char **string, + guint *plen, + int *err) { int written; @@ -569,9 +600,10 @@ static gboolean do_write (MooTermPt *pt_gen, } -static void append (MooTermPt *pt, - const char *data, - guint len) +static void +append (MooTermPt *pt, + const char *data, + guint len) { GByteArray *ar = g_byte_array_sized_new (len); g_byte_array_append (ar, (const guint8*)data, len); @@ -579,13 +611,15 @@ static void append (MooTermPt *pt, } -static gboolean write_cb (MooTermPt *pt) +static gboolean +write_cb (MooTermPt *pt) { pt_write (pt, NULL, 0); return TRUE; } -static void start_writer (MooTermPt *pt) +static void +start_writer (MooTermPt *pt) { if (!pt->priv->pending_write_id) pt->priv->pending_write_id = @@ -594,7 +628,8 @@ static void start_writer (MooTermPt *pt) pt, NULL); } -static void stop_writer (MooTermPt *pt) +static void +stop_writer (MooTermPt *pt) { if (pt->priv->pending_write_id) { @@ -604,12 +639,13 @@ static void stop_writer (MooTermPt *pt) } -static void pt_write (MooTermPt *pt, - const char *data, - gssize data_len) +static void +pt_write (MooTermPt *pt, + const char *data, + gssize data_len) { g_return_if_fail (data == NULL || data_len != 0); - g_return_if_fail (pt->priv->child_alive); + g_return_if_fail (pt->priv->alive); while (data || !g_queue_is_empty (pt->priv->pending_write)) { @@ -699,7 +735,7 @@ get_erase_char (MooTermPt *pt_gen) static void send_intr (MooTermPt *pt) { - g_return_if_fail (pt->priv->child_alive); + g_return_if_fail (pt->priv->alive); pt_discard_pending_write (pt); pt_write (pt, "\003", 1); } diff --git a/moo/mooterm/mootermpt.c b/moo/mooterm/mootermpt.c index abfaff69..e54ec134 100644 --- a/moo/mooterm/mootermpt.c +++ b/moo/mooterm/mootermpt.c @@ -59,6 +59,8 @@ _moo_term_pt_init (MooTermPt *pt) { pt->priv = g_new0 (MooTermPtPrivate, 1); pt->priv->pending_write = g_queue_new (); + pt->priv->child_alive = FALSE; + pt->priv->alive = FALSE; } @@ -145,7 +147,24 @@ _moo_term_pt_write (MooTermPt *pt, gboolean -_moo_term_pt_child_alive (MooTermPt *pt) +_moo_term_pt_child_alive (MooTermPt *pt) { - return pt->priv->child_alive; + return pt->priv->child_alive || pt->priv->alive; +} + +gboolean +_moo_term_pt_alive (MooTermPt *pt) +{ + return pt->priv->alive; +} + + +gboolean +_moo_term_pt_set_fd (MooTermPt *pt, + int master) +{ + g_return_val_if_fail (MOO_IS_TERM_PT (pt), FALSE); + g_return_val_if_fail (!pt->priv->child_alive, FALSE); + g_return_val_if_fail (MOO_TERM_PT_GET_CLASS(pt)->set_fd != NULL, FALSE); + return MOO_TERM_PT_GET_CLASS(pt)->set_fd (pt, master); } diff --git a/moo/mooterm/mootermpt.h b/moo/mooterm/mootermpt.h index ac9058c2..78533b1c 100644 --- a/moo/mooterm/mootermpt.h +++ b/moo/mooterm/mootermpt.h @@ -61,6 +61,8 @@ struct _MooTermPtClass { void (*kill_child) (MooTermPt *pt); char (*get_erase_char) (MooTermPt *pt); void (*send_intr) (MooTermPt *pt); + gboolean (*set_fd) (MooTermPt *pt, + int master); /* signals */ void (*child_died) (MooTermPt *pt); @@ -87,8 +89,11 @@ gboolean _moo_term_pt_fork_command (MooTermPt *pt, const struct _MooTermCommand *cmd, GError **error); void _moo_term_pt_kill_child (MooTermPt *pt); - gboolean _moo_term_pt_child_alive (MooTermPt *pt); +gboolean _moo_term_pt_alive (MooTermPt *pt); + +gboolean _moo_term_pt_set_fd (MooTermPt *pt, + int master); void _moo_term_pt_write (MooTermPt *pt, const char *data,