moo_term_set_fd()

This commit is contained in:
Yevgen Muntyan 2007-01-18 03:21:30 -06:00
parent 2fb0472ab1
commit ed255511ce
10 changed files with 156 additions and 73 deletions

View File

@ -474,6 +474,15 @@
(return-type "none") (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 (define-function set_helper_directory
(c-name "moo_term_set_helper_directory") (c-name "moo_term_set_helper_directory")
(return-type "none") (return-type "none")

View File

@ -91,7 +91,7 @@ moo_term_update_font (MooTerm *term)
font_calculate (term->priv->font); font_calculate (term->priv->font);
if (GTK_WIDGET_REALIZED (term)) if (GTK_WIDGET_REALIZED (term))
_moo_term_size_changed (term); _moo_term_update_size (term, FALSE);
} }

View File

@ -212,7 +212,8 @@ void _moo_term_buffer_scrolled (MooTermBuffer *buf,
guint lines, guint lines,
MooTerm *term); 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_font_stuff (MooTerm *term);
void _moo_term_init_palette (MooTerm *term); void _moo_term_init_palette (MooTerm *term);

View File

@ -493,7 +493,7 @@ static void moo_term_size_allocate (GtkWidget *widget,
old_height / term_char_height(term) != old_height / term_char_height(term) !=
allocation->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_init_font_stuff (term);
_moo_term_update_palette (term); _moo_term_update_palette (term);
_moo_term_size_changed (term); _moo_term_update_size (term, FALSE);
term->priv->im = gtk_im_multicontext_new (); term->priv->im = gtk_im_multicontext_new ();
gtk_im_context_set_client_window (term->priv->im, widget->window); gtk_im_context_set_client_window (term->priv->im, widget->window);
@ -886,7 +886,8 @@ static void scroll_to_bottom (MooTerm *term,
void void
_moo_term_size_changed (MooTerm *term) _moo_term_update_size (MooTerm *term,
gboolean force)
{ {
GtkWidget *widget = GTK_WIDGET (term); GtkWidget *widget = GTK_WIDGET (term);
MooTermFont *font = term->priv->font; MooTermFont *font = term->priv->font;
@ -898,7 +899,7 @@ _moo_term_size_changed (MooTerm *term)
old_width = term->priv->width; old_width = term->priv->width;
old_height = term->priv->height; old_height = term->priv->height;
if (width == old_width && height == old_height) if (!force && width == old_width && height == old_height)
return; return;
width = CLAMP (width, MIN_TERMINAL_WIDTH, MAX_TERMINAL_WIDTH); width = CLAMP (width, MIN_TERMINAL_WIDTH, MAX_TERMINAL_WIDTH);
@ -1002,7 +1003,7 @@ moo_term_feed_child (MooTerm *term,
int len) int len)
{ {
g_return_if_fail (MOO_IS_TERM (term) && string != NULL); 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); _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)); 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); _moo_term_pt_send_intr (term->priv->pt);
} }
@ -1960,10 +1961,10 @@ _moo_term_release_selection (MooTerm *term)
gboolean gboolean
moo_term_child_alive (MooTerm *term) moo_term_child_alive (MooTerm *term)
{ {
g_return_val_if_fail (MOO_IS_TERM (term), FALSE); 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 GType
moo_term_command_get_type (void) moo_term_command_get_type (void)
{ {

View File

@ -131,6 +131,9 @@ void moo_term_set_font_from_string (MooTerm *term,
void moo_term_set_cursor_blink_time (MooTerm *term, void moo_term_set_cursor_blink_time (MooTerm *term,
guint ms); guint ms);
void moo_term_set_fd (MooTerm *term,
int master);
void moo_term_reset (MooTerm *term); void moo_term_reset (MooTerm *term);
void moo_term_soft_reset (MooTerm *term); void moo_term_soft_reset (MooTerm *term);

View File

@ -126,10 +126,8 @@ _moo_term_pt_cyg_class_init (MooTermPtCygClass *klass)
static void 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->pid = (GPid) -1;
pt->process_id = 0; pt->process_id = 0;
pt->watch_id = 0; pt->watch_id = 0;
@ -142,7 +140,7 @@ _moo_term_pt_cyg_init (MooTermPtCyg *pt)
static void static void
moo_term_pt_cyg_finalize (GObject *object) moo_term_pt_cyg_finalize (GObject *object)
{ {
MooTermPtCyg *pt = MOO_TERM_PT_CYG (object); MooTermPtCyg *pt = MOO_TERM_PT_CYG (object);
kill_child (MOO_TERM_PT (pt)); kill_child (MOO_TERM_PT (pt));

View File

@ -27,6 +27,7 @@ G_BEGIN_DECLS
struct _MooTermPtPrivate { struct _MooTermPtPrivate {
struct _MooTerm *term; struct _MooTerm *term;
gboolean child_alive; gboolean child_alive;
gboolean alive;
GQueue *pending_write; /* list->data is GByteArray* */ GQueue *pending_write; /* list->data is GByteArray* */
guint pending_write_id; guint pending_write_id;
}; };

View File

@ -92,6 +92,8 @@ static void pt_write (MooTermPt *pt,
static void kill_child (MooTermPt *pt); static void kill_child (MooTermPt *pt);
static void send_intr (MooTermPt *pt); static void send_intr (MooTermPt *pt);
static char get_erase_char (MooTermPt *pt); static char get_erase_char (MooTermPt *pt);
static gboolean set_fd (MooTermPt *pt,
int master);
static gboolean read_child_out (GIOChannel *source, static gboolean read_child_out (GIOChannel *source,
GIOCondition condition, GIOCondition condition,
@ -122,14 +124,13 @@ _moo_term_pt_unix_class_init (MooTermPtUnixClass *klass)
pt_class->kill_child = kill_child; pt_class->kill_child = kill_child;
pt_class->get_erase_char = get_erase_char; pt_class->get_erase_char = get_erase_char;
pt_class->send_intr = send_intr; pt_class->send_intr = send_intr;
pt_class->set_fd = set_fd;
} }
static void static void
_moo_term_pt_unix_init (MooTermPtUnix *pt) _moo_term_pt_unix_init (MooTermPtUnix *pt)
{ {
MOO_TERM_PT(pt)->priv->child_alive = FALSE;
pt->child_pid = (GPid)-1; pt->child_pid = (GPid)-1;
pt->master = -1; pt->master = -1;
@ -162,7 +163,7 @@ set_size (MooTermPt *pt,
ptu = MOO_TERM_PT_UNIX (pt); ptu = MOO_TERM_PT_UNIX (pt);
if (pt->priv->child_alive) if (pt->priv->alive)
_vte_pty_set_size (ptu->master, width, height); _vte_pty_set_size (ptu->master, width, height);
ptu->width = width; 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 static gboolean
fork_argv (MooTermPt *pt_gen, fork_argv (MooTermPt *pt_gen,
char **argv, char **argv,
@ -180,9 +221,9 @@ fork_argv (MooTermPt *pt_gen,
MooTermPtUnix *pt; MooTermPtUnix *pt;
int env_len = 0; int env_len = 0;
char **new_env; char **new_env;
int status, flags; int status;
int i; int i;
GSource *src; int master;
g_return_val_if_fail (argv != NULL, FALSE); g_return_val_if_fail (argv != NULL, FALSE);
g_return_val_if_fail (MOO_IS_TERM_PT_UNIX (pt_gen), 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] = g_strdup ("TERM=" TERM_EMULATION);
new_env[env_len + 1] = NULL; new_env[env_len + 1] = NULL;
pt->master = _vte_pty_open (&pt->child_pid, new_env, master = _vte_pty_open (&pt->child_pid, new_env,
argv[0], argv[0],
argv, argv,
working_dir, working_dir,
pt->width, pt->height, pt->width, pt->height,
FALSE, FALSE, FALSE); FALSE, FALSE, FALSE);
g_strfreev (new_env); g_strfreev (new_env);
if (pt->master == -1) if (master == -1)
{ {
g_critical ("%s: could not fork child", G_STRLOC); g_critical ("%s: could not fork child", G_STRLOC);
@ -241,45 +282,34 @@ fork_argv (MooTermPt *pt_gen,
{ {
#if 1 #if 1
_moo_message ("%s: forked child pid %d on fd %d", _moo_message ("%s: forked child pid %d on fd %d",
G_STRLOC, pt->child_pid, pt->master); G_STRLOC, pt->child_pid, master);
#endif #endif
pt_gen->priv->child_alive = TRUE;
pt_gen->priv->alive = TRUE;
} }
if (waitpid (-1, &status, WNOHANG) == -1) if (waitpid (-1, &status, WNOHANG) == -1)
g_critical ("%s: error in waitpid", G_STRLOC); g_critical ("%s: error in waitpid", G_STRLOC);
if ((flags = fcntl (pt->master, F_GETFL)) < 0) setup_master_fd (pt, master);
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;
return TRUE; 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 static gboolean
fork_command (MooTermPt *pt_gen, fork_command (MooTermPt *pt_gen,
const MooTermCommand *cmd, const MooTermCommand *cmd,
@ -323,6 +353,7 @@ kill_child (MooTermPt *pt_gen)
pt->non_block = FALSE; pt->non_block = FALSE;
pt->child_pid = (GPid)-1; pt->child_pid = (GPid)-1;
pt_gen->priv->alive = FALSE;
if (pt_gen->priv->child_alive) if (pt_gen->priv->child_alive)
{ {
@ -351,7 +382,6 @@ read_child_out (G_GNUC_UNUSED GIOChannel *source,
int bytes; int bytes;
_moo_message ("%s: G_IO_HUP", G_STRLOC); _moo_message ("%s: G_IO_HUP", G_STRLOC);
error_no = errno;
bytes = read (pt->master, buf, sizeof (buf)); 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, /* writes given data to file, returns TRUE on successful write,
FALSE when could not write al teh data, puts start of leftover 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 */ to string, length of it to len, and fills err in case of error */
static gboolean do_write (MooTermPt *pt_gen, static gboolean
const char **string, do_write (MooTermPt *pt_gen,
guint *plen, const char **string,
int *err) guint *plen,
int *err)
{ {
int written; int written;
@ -569,9 +600,10 @@ static gboolean do_write (MooTermPt *pt_gen,
} }
static void append (MooTermPt *pt, static void
const char *data, append (MooTermPt *pt,
guint len) const char *data,
guint len)
{ {
GByteArray *ar = g_byte_array_sized_new (len); GByteArray *ar = g_byte_array_sized_new (len);
g_byte_array_append (ar, (const guint8*)data, 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); pt_write (pt, NULL, 0);
return TRUE; return TRUE;
} }
static void start_writer (MooTermPt *pt) static void
start_writer (MooTermPt *pt)
{ {
if (!pt->priv->pending_write_id) if (!pt->priv->pending_write_id)
pt->priv->pending_write_id = pt->priv->pending_write_id =
@ -594,7 +628,8 @@ static void start_writer (MooTermPt *pt)
pt, NULL); pt, NULL);
} }
static void stop_writer (MooTermPt *pt) static void
stop_writer (MooTermPt *pt)
{ {
if (pt->priv->pending_write_id) if (pt->priv->pending_write_id)
{ {
@ -604,12 +639,13 @@ static void stop_writer (MooTermPt *pt)
} }
static void pt_write (MooTermPt *pt, static void
const char *data, pt_write (MooTermPt *pt,
gssize data_len) const char *data,
gssize data_len)
{ {
g_return_if_fail (data == NULL || data_len != 0); 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)) while (data || !g_queue_is_empty (pt->priv->pending_write))
{ {
@ -699,7 +735,7 @@ get_erase_char (MooTermPt *pt_gen)
static void static void
send_intr (MooTermPt *pt) 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_discard_pending_write (pt);
pt_write (pt, "\003", 1); pt_write (pt, "\003", 1);
} }

View File

@ -59,6 +59,8 @@ _moo_term_pt_init (MooTermPt *pt)
{ {
pt->priv = g_new0 (MooTermPtPrivate, 1); pt->priv = g_new0 (MooTermPtPrivate, 1);
pt->priv->pending_write = g_queue_new (); 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 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);
} }

View File

@ -61,6 +61,8 @@ struct _MooTermPtClass {
void (*kill_child) (MooTermPt *pt); void (*kill_child) (MooTermPt *pt);
char (*get_erase_char) (MooTermPt *pt); char (*get_erase_char) (MooTermPt *pt);
void (*send_intr) (MooTermPt *pt); void (*send_intr) (MooTermPt *pt);
gboolean (*set_fd) (MooTermPt *pt,
int master);
/* signals */ /* signals */
void (*child_died) (MooTermPt *pt); void (*child_died) (MooTermPt *pt);
@ -87,8 +89,11 @@ gboolean _moo_term_pt_fork_command (MooTermPt *pt,
const struct _MooTermCommand *cmd, const struct _MooTermCommand *cmd,
GError **error); GError **error);
void _moo_term_pt_kill_child (MooTermPt *pt); void _moo_term_pt_kill_child (MooTermPt *pt);
gboolean _moo_term_pt_child_alive (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, void _moo_term_pt_write (MooTermPt *pt,
const char *data, const char *data,