implemented MooTermVt for unix
This commit is contained in:
parent
9985fd84fd
commit
1ca2e621d1
@ -20,6 +20,14 @@ widget_sources = \
|
|||||||
mootermvt.c \
|
mootermvt.c \
|
||||||
mootermvt.h
|
mootermvt.h
|
||||||
|
|
||||||
|
widget_unix_sources = \
|
||||||
|
mootermvt-unix.c \
|
||||||
|
pty.c \
|
||||||
|
pty.h
|
||||||
|
|
||||||
|
widget_win32_sources = \
|
||||||
|
mootermvt-win32.c
|
||||||
|
|
||||||
AM_INCLUDES =
|
AM_INCLUDES =
|
||||||
common_cflags = \
|
common_cflags = \
|
||||||
-I$(top_builddir) \
|
-I$(top_builddir) \
|
||||||
@ -29,9 +37,55 @@ common_cflags = \
|
|||||||
$(PYGTK_CFLAGS) \
|
$(PYGTK_CFLAGS) \
|
||||||
$(GTK_CFLAGS) \
|
$(GTK_CFLAGS) \
|
||||||
-DG_LOG_DOMAIN=\"Moo\"
|
-DG_LOG_DOMAIN=\"Moo\"
|
||||||
|
|
||||||
AM_CFLAGS = $(common_cflags) $(M_CFLAGS) $(CFLAGS)
|
AM_CFLAGS = $(common_cflags) $(M_CFLAGS) $(CFLAGS)
|
||||||
AM_CXXFLAGS = $(common_cflags) $(M_CXXFLAGS) $(CXXFLAGS)
|
AM_CXXFLAGS = $(common_cflags) $(M_CXXFLAGS) $(CXXFLAGS)
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
$(widget_sources) \
|
||||||
|
$(widget_unix_sources) \
|
||||||
|
$(widget_win32_sources)
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# UNIX
|
||||||
|
#
|
||||||
|
if UNIX_BUILD
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libmooterm.la
|
noinst_LTLIBRARIES = libmooterm.la
|
||||||
|
|
||||||
libmooterm_la_SOURCES = $(widget_sources)
|
libmooterm_la_SOURCES = $(widget_sources) $(widget_unix_sources)
|
||||||
|
|
||||||
|
endif UNIX_BUILD
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# MINGW
|
||||||
|
#
|
||||||
|
if MINGW_BUILD
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libmooterm.la
|
||||||
|
|
||||||
|
libmooterm_la_SOURCES = $(widget_sources) $(widget_win32_sources)
|
||||||
|
|
||||||
|
endif MINGW_BUILD
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
# CYGWIN
|
||||||
|
#
|
||||||
|
if CYGWIN_BUILD
|
||||||
|
|
||||||
|
noinst_PROGRAMS = termhelper
|
||||||
|
|
||||||
|
termhelper_CFLAGS = \
|
||||||
|
$(AM_CFLAGS) \
|
||||||
|
$(CYGWIN_CFLAGS)
|
||||||
|
|
||||||
|
termhelper_SOURCES = $(termhelper_sources)
|
||||||
|
termhelper_LDADD = $(CYGWIN_LDFLAGS) termhelper_res.res
|
||||||
|
|
||||||
|
termhelper_res.res: termhelper_res.rc
|
||||||
|
$(WINDRES) -i termhelper_res.rc --input-format=rc -o termhelper_res.res -O coff
|
||||||
|
|
||||||
|
endif CYGWIN_BUILD
|
||||||
|
@ -649,3 +649,15 @@ void moo_term_size_changed (MooTerm *term)
|
|||||||
moo_term_buffer_set_screen_size (term->priv->buffer, width, height);
|
moo_term_buffer_set_screen_size (term->priv->buffer, width, height);
|
||||||
moo_term_vt_set_size (term->priv->vt, width, height);
|
moo_term_vt_set_size (term->priv->vt, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean moo_term_fork_command (MooTerm *term,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MOO_IS_TERM (term), FALSE);
|
||||||
|
|
||||||
|
return moo_term_vt_fork_command (term->priv->vt,
|
||||||
|
cmd, working_dir, envp);
|
||||||
|
}
|
||||||
|
@ -56,6 +56,11 @@ MooTermBuffer *moo_term_get_buffer (MooTerm *term);
|
|||||||
void moo_term_set_adjustment (MooTerm *term,
|
void moo_term_set_adjustment (MooTerm *term,
|
||||||
GtkAdjustment *vadj);
|
GtkAdjustment *vadj);
|
||||||
|
|
||||||
|
gboolean moo_term_fork_command (MooTerm *term,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
499
moo/mooterm/mootermvt-unix.c
Normal file
499
moo/mooterm/mootermvt-unix.c
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
/*
|
||||||
|
* mooterm/mootermvt-unix.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mooterm/mootermvt.h"
|
||||||
|
#include "mooterm/pty.h"
|
||||||
|
#include "mooutils/moomarshals.h"
|
||||||
|
#include "mooutils/moocompat.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#elif HAVE_SYS_POLL_H
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define TERM_EMULATION "xterm"
|
||||||
|
#define READ_BUFSIZE 4096
|
||||||
|
#define POLL_TIME 5
|
||||||
|
#define POLL_NUM 1
|
||||||
|
|
||||||
|
|
||||||
|
#define MOO_TERM_VT_UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOO_TYPE_TERM_VT_UNIX, MooTermVtUnix))
|
||||||
|
#define MOO_TERM_VT_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_TERM_VT_UNIX, MooTermVtUnixClass))
|
||||||
|
#define MOO_IS_TERM_VT_UNIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOO_TYPE_TERM_VT_UNIX))
|
||||||
|
#define MOO_IS_TERM_VT_UNIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_TERM_VT_UNIX))
|
||||||
|
#define MOO_TERM_VT_UNIX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_TERM_VT_UNIX, MooTermVtUnixClass))
|
||||||
|
|
||||||
|
typedef struct _MooTermVtUnix MooTermVtUnix;
|
||||||
|
typedef struct _MooTermVtUnixClass MooTermVtUnixClass;
|
||||||
|
|
||||||
|
|
||||||
|
struct _MooTermVtUnix {
|
||||||
|
MooTermVt parent;
|
||||||
|
|
||||||
|
gboolean child_alive;
|
||||||
|
GPid child_pid;
|
||||||
|
|
||||||
|
int master;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
GIOChannel *io;
|
||||||
|
guint io_watch_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct _MooTermVtUnixClass {
|
||||||
|
MooTermVtClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void moo_term_vt_unix_finalize (GObject *object);
|
||||||
|
|
||||||
|
static void set_size (MooTermVt *vt,
|
||||||
|
gulong width,
|
||||||
|
gulong height);
|
||||||
|
static gboolean fork_command (MooTermVt *vt,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp);
|
||||||
|
static void feed_child (MooTermVt *vt,
|
||||||
|
const char *string,
|
||||||
|
gssize len);
|
||||||
|
static void kill_child (MooTermVt *vt);
|
||||||
|
|
||||||
|
static gboolean read_child_out (GIOChannel *source,
|
||||||
|
GIOCondition condition,
|
||||||
|
MooTermVtUnix *vt);
|
||||||
|
static void feed_parent (MooTermVtUnix *vt,
|
||||||
|
const char *string,
|
||||||
|
gssize len);
|
||||||
|
|
||||||
|
|
||||||
|
/* MOO_TYPE_TERM_VT_UNIX */
|
||||||
|
G_DEFINE_TYPE (MooTermVtUnix, moo_term_vt_unix, MOO_TYPE_TERM_VT)
|
||||||
|
|
||||||
|
|
||||||
|
static void moo_term_vt_unix_class_init (MooTermVtUnixClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
MooTermVtClass *vt_class = MOO_TERM_VT_CLASS (klass);
|
||||||
|
|
||||||
|
gobject_class->finalize = moo_term_vt_unix_finalize;
|
||||||
|
|
||||||
|
vt_class->set_size = set_size;
|
||||||
|
vt_class->fork_command = fork_command;
|
||||||
|
vt_class->feed_child = feed_child;
|
||||||
|
vt_class->kill_child = kill_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void moo_term_vt_unix_init (MooTermVtUnix *vt)
|
||||||
|
{
|
||||||
|
vt->child_alive = FALSE;
|
||||||
|
vt->child_pid = (GPid)-1;
|
||||||
|
|
||||||
|
vt->master = -1;
|
||||||
|
vt->width = 80;
|
||||||
|
vt->height = 24;
|
||||||
|
|
||||||
|
vt->io = NULL;
|
||||||
|
vt->io_watch_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void moo_term_vt_unix_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
MooTermVtUnix *vt = MOO_TERM_VT_UNIX (object);
|
||||||
|
kill_child (MOO_TERM_VT (vt));
|
||||||
|
G_OBJECT_CLASS (moo_term_vt_unix_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void set_size (MooTermVt *vt,
|
||||||
|
gulong width,
|
||||||
|
gulong height)
|
||||||
|
{
|
||||||
|
MooTermVtUnix *vtu;
|
||||||
|
|
||||||
|
g_return_if_fail (MOO_IS_TERM_VT_UNIX (vt));
|
||||||
|
|
||||||
|
vtu = MOO_TERM_VT_UNIX (vt);
|
||||||
|
|
||||||
|
if (vtu->child_alive)
|
||||||
|
_vte_pty_set_size (vtu->master, width, height);
|
||||||
|
|
||||||
|
vtu->width = width;
|
||||||
|
vtu->height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean fork_command (MooTermVt *vt_gen,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp)
|
||||||
|
{
|
||||||
|
MooTermVtUnix *vt;
|
||||||
|
int argv_len;
|
||||||
|
char **argv = NULL;
|
||||||
|
int env_len = 0;
|
||||||
|
char **new_env;
|
||||||
|
GError *err = NULL;
|
||||||
|
int status, flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
g_return_val_if_fail (cmd != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (MOO_IS_TERM_VT_UNIX (vt_gen), FALSE);
|
||||||
|
|
||||||
|
vt = MOO_TERM_VT_UNIX (vt_gen);
|
||||||
|
|
||||||
|
g_return_val_if_fail (!vt->child_alive, FALSE);
|
||||||
|
|
||||||
|
if (!g_shell_parse_argv (cmd, &argv_len, &argv, &err))
|
||||||
|
{
|
||||||
|
g_critical ("%s: could not parse command line", G_STRLOC);
|
||||||
|
|
||||||
|
if (err != NULL)
|
||||||
|
{
|
||||||
|
g_critical ("%s: %s", G_STRLOC, err->message);
|
||||||
|
g_error_free (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argv != NULL)
|
||||||
|
g_strfreev (argv);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (envp)
|
||||||
|
{
|
||||||
|
char **e;
|
||||||
|
for (e = envp; *e != NULL; ++e)
|
||||||
|
++env_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_env = g_new (char*, env_len + 2);
|
||||||
|
|
||||||
|
for (i = 0; i < env_len; ++i)
|
||||||
|
new_env[i] = g_strdup (envp[i]);
|
||||||
|
|
||||||
|
new_env[env_len] = g_strdup ("TERM=" TERM_EMULATION);
|
||||||
|
new_env[env_len + 1] = NULL;
|
||||||
|
|
||||||
|
vt->master = _vte_pty_open (&vt->child_pid, new_env,
|
||||||
|
argv[0],
|
||||||
|
argv,
|
||||||
|
working_dir,
|
||||||
|
vt->width, vt->height,
|
||||||
|
FALSE, FALSE, FALSE);
|
||||||
|
g_strfreev (new_env);
|
||||||
|
|
||||||
|
if (vt->master == -1)
|
||||||
|
{
|
||||||
|
g_critical ("%s: could not fork child", G_STRLOC);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_message ("%s: forked child pid %d", G_STRLOC, vt->child_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitpid (-1, &status, WNOHANG) == -1)
|
||||||
|
g_critical ("%s: error in waitpid", G_STRLOC);
|
||||||
|
|
||||||
|
if ((flags = fcntl (vt->master, F_GETFL)) < 0)
|
||||||
|
g_critical ("%s: F_GETFL on master", G_STRLOC);
|
||||||
|
else if (-1 == fcntl (vt->master, F_SETFL, O_NONBLOCK | flags))
|
||||||
|
g_critical ("%s: F_SETFL on master", G_STRLOC);
|
||||||
|
|
||||||
|
vt->io = g_io_channel_unix_new (vt->master);
|
||||||
|
g_return_val_if_fail (vt->io != NULL, FALSE);
|
||||||
|
|
||||||
|
g_io_channel_set_encoding (vt->io, NULL, NULL);
|
||||||
|
g_io_channel_set_buffered (vt->io, FALSE);
|
||||||
|
|
||||||
|
vt->io_watch_id = g_io_add_watch (vt->io,
|
||||||
|
G_IO_IN | G_IO_PRI | G_IO_HUP,
|
||||||
|
(GIOFunc) read_child_out,
|
||||||
|
vt);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// 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);
|
||||||
|
// else g_warning ("%s: could not find helper_io_watch source", G_STRLOC);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vt->child_alive = TRUE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void kill_child (MooTermVt *vt_gen)
|
||||||
|
{
|
||||||
|
MooTermVtUnix *vt = MOO_TERM_VT_UNIX (vt_gen);
|
||||||
|
|
||||||
|
if (vt->io_watch_id)
|
||||||
|
{
|
||||||
|
g_source_remove (vt->io_watch_id);
|
||||||
|
vt->io_watch_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vt->io)
|
||||||
|
{
|
||||||
|
feed_child (MOO_TERM_VT (vt), "\4", 1);
|
||||||
|
g_io_channel_shutdown (vt->io, TRUE, NULL);
|
||||||
|
g_io_channel_unref (vt->io);
|
||||||
|
vt->io = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vt->master != -1)
|
||||||
|
{
|
||||||
|
_vte_pty_close (vt->master);
|
||||||
|
vt->master = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
vt->child_pid = (GPid)-1;
|
||||||
|
|
||||||
|
if (vt->child_alive)
|
||||||
|
{
|
||||||
|
vt->child_alive = FALSE;
|
||||||
|
g_signal_emit_by_name (vt, "child-died");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean read_child_out (G_GNUC_UNUSED GIOChannel *source,
|
||||||
|
GIOCondition condition,
|
||||||
|
MooTermVtUnix *vt)
|
||||||
|
{
|
||||||
|
gboolean error_occured = FALSE;
|
||||||
|
int error_no = 0;
|
||||||
|
|
||||||
|
char buf[READ_BUFSIZE];
|
||||||
|
int current = 0;
|
||||||
|
guint again = POLL_NUM;
|
||||||
|
|
||||||
|
if (condition & G_IO_HUP)
|
||||||
|
{
|
||||||
|
g_message ("%s: G_IO_HUP", G_STRLOC);
|
||||||
|
error_no = errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
else if (condition & G_IO_ERR)
|
||||||
|
{
|
||||||
|
g_message ("%s: G_IO_ERR", G_STRLOC);
|
||||||
|
error_no = errno;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (condition & (G_IO_IN | G_IO_PRI));
|
||||||
|
|
||||||
|
while (again && !error_occured && current < READ_BUFSIZE)
|
||||||
|
{
|
||||||
|
struct pollfd fd = {vt->master, POLLIN | POLLPRI, 0};
|
||||||
|
|
||||||
|
int res = poll (&fd, 1, POLL_TIME);
|
||||||
|
|
||||||
|
switch (res)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
--again;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (fd.revents & (POLLNVAL | POLLERR | POLLHUP))
|
||||||
|
{
|
||||||
|
again = 0;
|
||||||
|
if (errno != EAGAIN && errno != EINTR)
|
||||||
|
{
|
||||||
|
error_occured = TRUE;
|
||||||
|
error_no = errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fd.revents & (POLLIN | POLLPRI))
|
||||||
|
{
|
||||||
|
int r = read (vt->master, buf + current, 1);
|
||||||
|
|
||||||
|
switch (r)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
error_occured = TRUE;
|
||||||
|
error_no = errno;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
--again;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
++current;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
again = 0;
|
||||||
|
|
||||||
|
if (errno != EAGAIN && errno != EINTR)
|
||||||
|
{
|
||||||
|
error_occured = TRUE;
|
||||||
|
error_no = errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current > 0)
|
||||||
|
feed_parent (vt, buf, current);
|
||||||
|
|
||||||
|
if (error_occured)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (error_occured)
|
||||||
|
g_message ("error in %s", G_STRLOC);
|
||||||
|
|
||||||
|
if (error_no)
|
||||||
|
g_message ("%s: %s", G_STRLOC, g_strerror (error_no));
|
||||||
|
|
||||||
|
if (vt->io)
|
||||||
|
{
|
||||||
|
_vte_pty_close (vt->master);
|
||||||
|
vt->master = -1;
|
||||||
|
|
||||||
|
g_io_channel_shutdown (vt->io, TRUE, NULL);
|
||||||
|
g_io_channel_unref (vt->io);
|
||||||
|
vt->io = NULL;
|
||||||
|
|
||||||
|
vt->io_watch_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_child (MOO_TERM_VT (vt));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void feed_parent (MooTermVtUnix *vt,
|
||||||
|
const char *string,
|
||||||
|
gssize len)
|
||||||
|
{
|
||||||
|
moo_term_buffer_feed (moo_term_vt_get_buffer (MOO_TERM_VT (vt)),
|
||||||
|
string, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define CHUNK_SIZE 1024
|
||||||
|
|
||||||
|
static void feed_child (MooTermVt *vt_gen,
|
||||||
|
const char *string,
|
||||||
|
gssize len)
|
||||||
|
{
|
||||||
|
guint total_written = 0;
|
||||||
|
GError *err = NULL;
|
||||||
|
guint eagain_count = 0;
|
||||||
|
|
||||||
|
MooTermVtUnix *vt = MOO_TERM_VT_UNIX (vt_gen);
|
||||||
|
|
||||||
|
g_return_if_fail (vt->io != NULL);
|
||||||
|
|
||||||
|
if (len < 0)
|
||||||
|
len = strlen (string);
|
||||||
|
|
||||||
|
while (total_written < (guint)len)
|
||||||
|
{
|
||||||
|
gsize written = 0;
|
||||||
|
GIOStatus status;
|
||||||
|
|
||||||
|
status = g_io_channel_write_chars (vt->io, string + total_written,
|
||||||
|
MIN (len - total_written, CHUNK_SIZE),
|
||||||
|
&written, &err);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
g_critical ("%s: %s", G_STRLOC, err->message);
|
||||||
|
g_error_free (err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != G_IO_STATUS_NORMAL)
|
||||||
|
{
|
||||||
|
gboolean stop = FALSE;
|
||||||
|
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case G_IO_STATUS_ERROR:
|
||||||
|
g_critical ("%s: g_io_channel_write_chars returned G_IO_STATUS_ERROR", G_STRLOC);
|
||||||
|
stop = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_IO_STATUS_EOF:
|
||||||
|
g_critical ("%s: g_io_channel_write_chars returned G_IO_STATUS_EOF", G_STRLOC);
|
||||||
|
stop = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case G_IO_STATUS_AGAIN:
|
||||||
|
++eagain_count;
|
||||||
|
|
||||||
|
if (eagain_count > 2)
|
||||||
|
{
|
||||||
|
g_critical ("%s: g_io_channel_write_chars returned G_IO_STATUS_AGAIN 2 times", G_STRLOC);
|
||||||
|
stop = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_usleep (10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stop)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (written <= 0)
|
||||||
|
{
|
||||||
|
g_critical ("%s: error in g_io_channel_write_chars", G_STRLOC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_written += written;
|
||||||
|
}
|
||||||
|
}
|
16
moo/mooterm/mootermvt-win32.c
Normal file
16
moo/mooterm/mootermvt-win32.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* mooterm/mootermvt-win32.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* See COPYING file that comes with this distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mooterm/mootermvt.h"
|
||||||
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mooterm/mootermvt.h"
|
#include "mooterm/mootermvt.h"
|
||||||
|
#include "mooutils/moomarshals.h"
|
||||||
|
#include "mooutils/moocompat.h"
|
||||||
|
|
||||||
|
|
||||||
struct _MooTermVtPrivate {
|
struct _MooTermVtPrivate {
|
||||||
@ -34,6 +36,7 @@ static void moo_term_vt_finalize (GObject *object);
|
|||||||
G_DEFINE_TYPE (MooTermVt, moo_term_vt, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (MooTermVt, moo_term_vt, G_TYPE_OBJECT)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
CHILD_DIED,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ enum {
|
|||||||
PROP_BUFFER
|
PROP_BUFFER
|
||||||
};
|
};
|
||||||
|
|
||||||
// static guint signals[LAST_SIGNAL];
|
static guint signals[LAST_SIGNAL];
|
||||||
|
|
||||||
|
|
||||||
static void moo_term_vt_class_init (MooTermVtClass *klass)
|
static void moo_term_vt_class_init (MooTermVtClass *klass)
|
||||||
@ -53,6 +56,21 @@ static void moo_term_vt_class_init (MooTermVtClass *klass)
|
|||||||
gobject_class->get_property = moo_term_vt_get_property;
|
gobject_class->get_property = moo_term_vt_get_property;
|
||||||
gobject_class->finalize = moo_term_vt_finalize;
|
gobject_class->finalize = moo_term_vt_finalize;
|
||||||
|
|
||||||
|
klass->set_size = NULL;
|
||||||
|
klass->fork_command = NULL;
|
||||||
|
klass->feed_child = NULL;
|
||||||
|
klass->kill_child = NULL;
|
||||||
|
klass->child_died = NULL;
|
||||||
|
|
||||||
|
signals[CHILD_DIED] =
|
||||||
|
g_signal_new ("child-died",
|
||||||
|
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (MooTermVtClass, child_died),
|
||||||
|
NULL, NULL,
|
||||||
|
_moo_marshal_VOID__VOID,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_BUFFER,
|
PROP_BUFFER,
|
||||||
g_param_spec_object ("buffer",
|
g_param_spec_object ("buffer",
|
||||||
@ -143,13 +161,44 @@ MooTermBuffer *moo_term_vt_get_buffer (MooTermVt *vt)
|
|||||||
|
|
||||||
MooTermVt *moo_term_vt_new (void)
|
MooTermVt *moo_term_vt_new (void)
|
||||||
{
|
{
|
||||||
return MOO_TERM_VT (g_object_new (MOO_TYPE_TERM_VT, NULL));
|
#ifdef __WIN32__
|
||||||
|
return g_object_new (MOO_TYPE_TERM_VT_WIN, NULL);
|
||||||
|
#else /* !__WIN32__ */
|
||||||
|
return g_object_new (MOO_TYPE_TERM_VT_UNIX, NULL);
|
||||||
|
#endif /* !__WIN32__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void moo_term_vt_set_size (G_GNUC_UNUSED MooTermVt *vt,
|
void moo_term_vt_set_size (MooTermVt *vt,
|
||||||
G_GNUC_UNUSED gulong width,
|
gulong width,
|
||||||
G_GNUC_UNUSED gulong height)
|
gulong height)
|
||||||
{
|
{
|
||||||
// g_message ("%s: implement me", G_STRLOC);
|
g_return_if_fail (MOO_IS_TERM_VT (vt));
|
||||||
|
MOO_TERM_VT_GET_CLASS(vt)->set_size (vt, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean moo_term_vt_fork_command (MooTermVt *vt,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (MOO_IS_TERM_VT (vt), FALSE);
|
||||||
|
return MOO_TERM_VT_GET_CLASS(vt)->fork_command (vt, cmd, working_dir, envp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void moo_term_vt_kill_child (MooTermVt *vt)
|
||||||
|
{
|
||||||
|
g_return_if_fail (MOO_IS_TERM_VT (vt));
|
||||||
|
MOO_TERM_VT_GET_CLASS(vt)->kill_child (vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void moo_term_vt_feed_child (MooTermVt *vt,
|
||||||
|
const char *data,
|
||||||
|
gssize len)
|
||||||
|
{
|
||||||
|
g_return_if_fail (MOO_IS_TERM_VT (vt));
|
||||||
|
MOO_TERM_VT_GET_CLASS(vt)->feed_child (vt, data, len);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,9 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
|
|
||||||
#define MOO_TYPE_TERM_VT (moo_term_vt_get_type ())
|
#define MOO_TYPE_TERM_VT (moo_term_vt_get_type ())
|
||||||
|
#define MOO_TYPE_TERM_VT_WIN (moo_term_vt_win_get_type ())
|
||||||
|
#define MOO_TYPE_TERM_VT_UNIX (moo_term_vt_unix_get_type ())
|
||||||
|
|
||||||
#define MOO_TERM_VT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOO_TYPE_TERM_VT, MooTermVt))
|
#define MOO_TERM_VT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOO_TYPE_TERM_VT, MooTermVt))
|
||||||
#define MOO_TERM_VT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_TERM_VT, MooTermVtClass))
|
#define MOO_TERM_VT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_TERM_VT, MooTermVtClass))
|
||||||
#define MOO_IS_TERM_VT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOO_TYPE_TERM_VT))
|
#define MOO_IS_TERM_VT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOO_TYPE_TERM_VT))
|
||||||
@ -38,19 +41,49 @@ struct _MooTermVt {
|
|||||||
|
|
||||||
struct _MooTermVtClass {
|
struct _MooTermVtClass {
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
/* virtual methods */
|
||||||
|
void (*set_size) (MooTermVt *vt,
|
||||||
|
gulong width,
|
||||||
|
gulong height);
|
||||||
|
gboolean (*fork_command) (MooTermVt *vt,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp);
|
||||||
|
void (*feed_child) (MooTermVt *vt,
|
||||||
|
const char *data,
|
||||||
|
gssize len);
|
||||||
|
void (*kill_child) (MooTermVt *vt);
|
||||||
|
|
||||||
|
/* signals */
|
||||||
|
void (*child_died) (MooTermVt *vt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType moo_term_vt_get_type (void) G_GNUC_CONST;
|
GType moo_term_vt_get_type (void) G_GNUC_CONST;
|
||||||
|
GType moo_term_vt_unix_get_type (void) G_GNUC_CONST;
|
||||||
|
GType moo_term_vt_win_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
MooTermVt *moo_term_vt_new (void);
|
/* creates MooTermVtWin or MooTermVtUnix instance, depending on platform */
|
||||||
void moo_term_vt_set_size (MooTermVt *vt,
|
MooTermVt *moo_term_vt_new (void);
|
||||||
gulong width,
|
|
||||||
gulong height);
|
|
||||||
|
|
||||||
void moo_term_vt_set_buffer (MooTermVt *vt,
|
void moo_term_vt_set_buffer (MooTermVt *vt,
|
||||||
MooTermBuffer *buffer);
|
MooTermBuffer *buffer);
|
||||||
MooTermBuffer *moo_term_vt_get_buffer (MooTermVt *vt);
|
MooTermBuffer *moo_term_vt_get_buffer (MooTermVt *vt);
|
||||||
|
|
||||||
|
void moo_term_vt_set_size (MooTermVt *vt,
|
||||||
|
gulong width,
|
||||||
|
gulong height);
|
||||||
|
|
||||||
|
gboolean moo_term_vt_fork_command (MooTermVt *vt,
|
||||||
|
const char *cmd,
|
||||||
|
const char *working_dir,
|
||||||
|
char **envp);
|
||||||
|
void moo_term_vt_kill_child (MooTermVt *vt);
|
||||||
|
|
||||||
|
void moo_term_vt_feed_child (MooTermVt *vt,
|
||||||
|
const char *data,
|
||||||
|
gssize len);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# tests/Makefile.am
|
# tests/Makefile.am
|
||||||
#
|
#
|
||||||
|
|
||||||
EXTRA_PROGRAMS = medit mterm markup editor
|
EXTRA_PROGRAMS = medit mterm markup editor termbuffer
|
||||||
noinst_PROGRAMS =
|
noinst_PROGRAMS =
|
||||||
|
|
||||||
EXTRA_DIST = pyapp.py.in
|
EXTRA_DIST = pyapp.py.in
|
||||||
@ -15,7 +15,7 @@ if BUILD_MOOEDIT
|
|||||||
noinst_PROGRAMS += medit
|
noinst_PROGRAMS += medit
|
||||||
endif
|
endif
|
||||||
if BUILD_MOOTERM
|
if BUILD_MOOTERM
|
||||||
noinst_PROGRAMS += mterm
|
noinst_PROGRAMS += mterm termbuffer
|
||||||
endif
|
endif
|
||||||
if BUILD_MOOUTILS
|
if BUILD_MOOUTILS
|
||||||
noinst_PROGRAMS += markup
|
noinst_PROGRAMS += markup
|
||||||
@ -74,14 +74,17 @@ medit_SOURCES = medit.cpp
|
|||||||
##
|
##
|
||||||
mterm_LDFLAGS =
|
mterm_LDFLAGS =
|
||||||
mterm_LDADD = $(MOO_LIBS) ../moo/libmoo.la
|
mterm_LDADD = $(MOO_LIBS) ../moo/libmoo.la
|
||||||
|
termbuffer_LDADD = $(mterm_LDADD)
|
||||||
|
|
||||||
|
|
||||||
if MINGW_BUILD
|
if MINGW_BUILD
|
||||||
mterm_LDFLAGS += -mwindows
|
mterm_LDFLAGS += -mwindows
|
||||||
endif MINGW_BUILD
|
endif MINGW_BUILD
|
||||||
|
|
||||||
mterm_SOURCES = \
|
termbuffer_LDFLAGS = $(mterm_LDFLAGS)
|
||||||
mterm.cpp
|
|
||||||
|
mterm_SOURCES = mterm.cpp
|
||||||
|
termbuffer_SOURCES = termbuffer.cpp
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
103
tests/mterm.cpp
103
tests/mterm.cpp
@ -17,89 +17,26 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef __WIN32__
|
|
||||||
#define CMD "sh"
|
|
||||||
#else
|
|
||||||
#define CMD "gapw95.exe"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CLEAR "\033[H\033[2J"
|
|
||||||
#define HOME "\033[H"
|
|
||||||
#define PARM_RIGHT "\033[%dC"
|
|
||||||
#define PARM_LEFT "\033[%dD"
|
|
||||||
#define ADDRESS "\033[%d;%dH"
|
|
||||||
|
|
||||||
#define GREEN "\033[0;40;32m"
|
|
||||||
#define NORMAL "\033[0m"
|
|
||||||
|
|
||||||
|
|
||||||
bool print (MooTermBuffer *buf)
|
|
||||||
{
|
|
||||||
for (guint i = 0; i < 1000; ++i)
|
|
||||||
moo_term_buffer_feed (buf, "kjhr jerhgjh erkjg hekrjghkerg ", -1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool print_random_hard (MooTerm *term)
|
|
||||||
{
|
|
||||||
MooTermBuffer *buf = term->priv->buffer;
|
|
||||||
guint width = buf_screen_width (buf);
|
|
||||||
guint height = buf_screen_height (buf);
|
|
||||||
guint row, col;
|
|
||||||
gboolean first_time = TRUE;
|
|
||||||
|
|
||||||
for (guint i = 0; i < 10000; ++i)
|
|
||||||
{
|
|
||||||
char r = 32 + (int) (94.0 * rand() / (RAND_MAX+1.0));
|
|
||||||
row = 1 + (int) (((double)height) * rand() / (RAND_MAX+1.0));
|
|
||||||
col = 1 + (int) (((double)width) * rand() / (RAND_MAX+1.0));
|
|
||||||
|
|
||||||
char *s = g_strdup_printf (ADDRESS "%c", row, col, r);
|
|
||||||
moo_term_buffer_feed (buf, s, -1);
|
|
||||||
g_free (s);
|
|
||||||
|
|
||||||
moo_term_force_update (term);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_print ("buffer: %dx%d\nterm: %dx%d\n",
|
|
||||||
buf_total_height (buf), buf_screen_width (buf),
|
|
||||||
term_height (term), term_width (term));
|
|
||||||
|
|
||||||
gtk_main_quit ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool print_random_soft (MooTerm *term)
|
|
||||||
{
|
|
||||||
MooTermBuffer *buf = term->priv->buffer;
|
|
||||||
guint width = buf_screen_width (buf);
|
|
||||||
guint height = buf_screen_height (buf);
|
|
||||||
guint row, col;
|
|
||||||
gboolean first_time = TRUE;
|
|
||||||
|
|
||||||
char r = 32 + (int) (94.0 * rand() / (RAND_MAX+1.0));
|
|
||||||
row = 1 + (int) (((double)height) * rand() / (RAND_MAX+1.0));
|
|
||||||
col = 1 + (int) (((double)width) * rand() / (RAND_MAX+1.0));
|
|
||||||
|
|
||||||
char *s = g_strdup_printf (ADDRESS "%c", row, col, r);
|
|
||||||
moo_term_buffer_feed (buf, s, -1);
|
|
||||||
g_free (s);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
gtk_init (&argc, &argv);
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
const char *cmd = CMD;
|
char *cmd = NULL;
|
||||||
if (argc > 1) cmd = argv[1];
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
cmd = g_strdup (argv[1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *dir = g_getenv ("HOME");
|
||||||
|
if (!dir)
|
||||||
|
dir = "/";
|
||||||
|
cmd = g_strdup_printf ("ls -R %s", dir);
|
||||||
|
}
|
||||||
|
|
||||||
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_widget_set_size_request (win, 400, 400);
|
gtk_window_set_default_size (GTK_WINDOW (win), 400, 400);
|
||||||
GtkWidget *swin = gtk_scrolled_window_new (NULL, NULL);
|
GtkWidget *swin = gtk_scrolled_window_new (NULL, NULL);
|
||||||
gtk_container_add (GTK_CONTAINER (win), swin);
|
gtk_container_add (GTK_CONTAINER (win), swin);
|
||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
||||||
@ -113,17 +50,13 @@ int main (int argc, char *argv[])
|
|||||||
|
|
||||||
MooTermBuffer *buf = moo_term_get_buffer (MOO_TERM (term));
|
MooTermBuffer *buf = moo_term_get_buffer (MOO_TERM (term));
|
||||||
g_object_set (buf,
|
g_object_set (buf,
|
||||||
"am-mode", FALSE,
|
"am-mode", TRUE,
|
||||||
"insert-mode", FALSE,
|
"insert-mode", TRUE,
|
||||||
"cursor-visible", TRUE,
|
"cursor-visible", TRUE,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
// for (guint i = 0; i < 1000; ++i)
|
moo_term_fork_command (MOO_TERM (term), cmd, NULL, NULL);
|
||||||
// moo_term_buffer_feed (buf, "Hello there", -1);
|
g_free (cmd);
|
||||||
// g_print ("%dx%d\n", buf_screen_width (buf), buf_total_height (buf));
|
|
||||||
|
|
||||||
// g_timeout_add (1000, (GSourceFunc) print, buf);
|
|
||||||
g_idle_add ((GSourceFunc) print_random_hard, term);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (win), "destroy", gtk_main_quit, NULL);
|
g_signal_connect (G_OBJECT (win), "destroy", gtk_main_quit, NULL);
|
||||||
gtk_main ();
|
gtk_main ();
|
||||||
|
130
tests/termbuffer.cpp
Normal file
130
tests/termbuffer.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
//
|
||||||
|
// tests/mterm.cpp
|
||||||
|
//
|
||||||
|
// Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation; either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// See COPYING file that comes with this distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#define MOOTERM_COMPILATION
|
||||||
|
#include "mooterm/mooterm-private.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef __WIN32__
|
||||||
|
#define CMD "sh"
|
||||||
|
#else
|
||||||
|
#define CMD "gapw95.exe"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CLEAR "\033[H\033[2J"
|
||||||
|
#define HOME "\033[H"
|
||||||
|
#define PARM_RIGHT "\033[%dC"
|
||||||
|
#define PARM_LEFT "\033[%dD"
|
||||||
|
#define ADDRESS "\033[%d;%dH"
|
||||||
|
|
||||||
|
#define GREEN "\033[0;40;32m"
|
||||||
|
#define NORMAL "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
bool print (MooTermBuffer *buf)
|
||||||
|
{
|
||||||
|
for (guint i = 0; i < 1000; ++i)
|
||||||
|
moo_term_buffer_feed (buf, "kjhr jerhgjh erkjg hekrjghkerg ", -1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool print_random_hard (MooTerm *term)
|
||||||
|
{
|
||||||
|
MooTermBuffer *buf = term->priv->buffer;
|
||||||
|
guint width = buf_screen_width (buf);
|
||||||
|
guint height = buf_screen_height (buf);
|
||||||
|
guint row, col;
|
||||||
|
gboolean first_time = TRUE;
|
||||||
|
|
||||||
|
for (guint i = 0; i < 10000; ++i)
|
||||||
|
{
|
||||||
|
char r = 32 + (int) (94.0 * rand() / (RAND_MAX+1.0));
|
||||||
|
row = 1 + (int) (((double)height) * rand() / (RAND_MAX+1.0));
|
||||||
|
col = 1 + (int) (((double)width) * rand() / (RAND_MAX+1.0));
|
||||||
|
|
||||||
|
char *s = g_strdup_printf (ADDRESS "%c", row, col, r);
|
||||||
|
moo_term_buffer_feed (buf, s, -1);
|
||||||
|
g_free (s);
|
||||||
|
|
||||||
|
moo_term_force_update (term);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_print ("buffer: %dx%d\nterm: %dx%d\n",
|
||||||
|
buf_total_height (buf), buf_screen_width (buf),
|
||||||
|
term_height (term), term_width (term));
|
||||||
|
|
||||||
|
gtk_main_quit ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool print_random_soft (MooTerm *term)
|
||||||
|
{
|
||||||
|
MooTermBuffer *buf = term->priv->buffer;
|
||||||
|
guint width = buf_screen_width (buf);
|
||||||
|
guint height = buf_screen_height (buf);
|
||||||
|
guint row, col;
|
||||||
|
gboolean first_time = TRUE;
|
||||||
|
|
||||||
|
char r = 32 + (int) (94.0 * rand() / (RAND_MAX+1.0));
|
||||||
|
row = 1 + (int) (((double)height) * rand() / (RAND_MAX+1.0));
|
||||||
|
col = 1 + (int) (((double)width) * rand() / (RAND_MAX+1.0));
|
||||||
|
|
||||||
|
char *s = g_strdup_printf (ADDRESS "%c", row, col, r);
|
||||||
|
moo_term_buffer_feed (buf, s, -1);
|
||||||
|
g_free (s);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
gtk_init (&argc, &argv);
|
||||||
|
|
||||||
|
const char *cmd = CMD;
|
||||||
|
if (argc > 1) cmd = argv[1];
|
||||||
|
|
||||||
|
GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||||
|
gtk_widget_set_size_request (win, 400, 400);
|
||||||
|
GtkWidget *swin = gtk_scrolled_window_new (NULL, NULL);
|
||||||
|
gtk_container_add (GTK_CONTAINER (win), swin);
|
||||||
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
||||||
|
GTK_POLICY_NEVER,
|
||||||
|
GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
|
GtkWidget *term = GTK_WIDGET (g_object_new (MOO_TYPE_TERM, NULL));
|
||||||
|
gtk_container_add (GTK_CONTAINER (swin), term);
|
||||||
|
|
||||||
|
gtk_widget_show_all (win);
|
||||||
|
|
||||||
|
MooTermBuffer *buf = moo_term_get_buffer (MOO_TERM (term));
|
||||||
|
g_object_set (buf,
|
||||||
|
"am-mode", FALSE,
|
||||||
|
"insert-mode", FALSE,
|
||||||
|
"cursor-visible", TRUE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// for (guint i = 0; i < 1000; ++i)
|
||||||
|
// moo_term_buffer_feed (buf, "Hello there", -1);
|
||||||
|
// g_print ("%dx%d\n", buf_screen_width (buf), buf_total_height (buf));
|
||||||
|
|
||||||
|
// g_timeout_add (1000, (GSourceFunc) print, buf);
|
||||||
|
g_idle_add ((GSourceFunc) print_random_hard, term);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (win), "destroy", gtk_main_quit, NULL);
|
||||||
|
gtk_main ();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user