Commit 25f08488 authored by Nalin Dahyabhai's avatar Nalin Dahyabhai
Browse files

snip off final newlines when we're matching, they're usually not wanted.

* src/vte.c (vte_terminal_match_check_internal): snip off final newlines when
	we're matching, they're usually not wanted.
* src/pty.c, src/pty.h: replace the simpler pty_open() function with a logging
	version, adding the ability to specify a startup directory (Red Hat
	#76529).
* src/vte.c, src/vte.h: replace the simpler fork_command() function with a
	logging version, adding the ability to specify a startup directory (Red
	Hat #76529).
* src/vteapp.c: modify call to handle new fork_command().
* python/vte.defs: update as above.
* python/vte.override: modify call to handle new fork_command(), adding an
	optional "directory" argument.
* src/vte.c: refactor the selection code, cleaning up when selection is
	cleared/started/extended (#95783).  Grab focus whenever we get button
	press or release or motion events.
* src/vte.c: rework how wide characters are stored to allow storing tabs
	(#95958).
* python/vte.override: wrap vte_terminal_get_text() and
	vte_terminal_get_text_range().  Based on patch from ha shao (#96230).
* src/vte.c, src/vte.h: add a user pointer argument to get_text callbacks
	(#96230).
* src/Makefile.am: bump shared library version because we changed a public
	function's signature.  Take the opportunity to replace padding fields
	which had previously been used up.
parent e600d5ea
2002-10-21 jacob berkman <jacob@ximian.com>
2002-10-25 nalin
* src/vte.c (vte_terminal_match_check_internal): snip off final
newlines when we're matching, they're usually not wanted.
2002-10-24 nalin
* src/pty.c, src/pty.h: replace the simpler pty_open() function with
a logging version, adding the ability to specify a startup directory
(Red Hat #76529).
* src/vte.c, src/vte.h: replace the simpler fork_command() function with
a logging version, adding the ability to specify a startup directory
(Red Hat #76529).
* src/vteapp.c: modify call to handle new fork_command().
* python/vte.defs: update as above.
* python/vte.override: modify call to handle new fork_command(), adding
an optional "directory" argument.
2002-10-23 nalin
* src/vte.c: refactor the selection code, cleaning up when selection is
cleared/started/extended (#95783).
2002-10-22 nalin
* src/vte.c: rework how wide characters are stored to allow storing
tabs (#95958).
2002-10-21 nalin
* python/vte.override: wrap vte_terminal_get_text() and
vte_terminal_get_text_range(). Based on patch from ha shao (#96230).
2002-10-21 nalin
* src/vte.c, src/vte.h: add a user pointer argument to get_text
callbacks (#96230).
* src/Makefile.am: bump shared library version because we changed
a public function's signature. Take the opportunity to replace padding
fields which had previously been used up.
2002-10-21 jacob berkman <jacob@ximian.com>
* src/Makefile.am (EXTRA_DIST): include decset, osc, and window
2002-10-18 nalin
......
......@@ -6,9 +6,12 @@ pkgconfig_DATA = vte.pc
CVSTAG=$(shell echo $(PACKAGE)-$(VERSION) | sed 's,[\.\-],_,g')
reallytag:
forcetag:
cvs tag -cFR $(CVSTAG) .
reallytag:
cvs tag -cR $(CVSTAG) .
tag:
$(top_srcdir)/autogen.sh
$(MAKE) reallytag
......
......@@ -16,39 +16,3 @@ pseudo-terminals and to resize psuedo-terminals.
</para>
<!-- ##### FUNCTION vte_pty_open ##### -->
<para>
</para>
@child:
@env_add:
@command:
@argv:
@columns:
@rows:
@Returns:
<!-- ##### FUNCTION vte_pty_get_size ##### -->
<para>
</para>
@master:
@columns:
@rows:
@Returns:
<!-- ##### FUNCTION vte_pty_set_size ##### -->
<para>
</para>
@master:
@columns:
@rows:
@Returns:
<!-- ##### SECTION ./tmpl/pty.sgml:Long_Description ##### -->
<para>
The terminal widget uses these functions to start commands with new controlling
pseudo-terminals and to resize psuedo-terminals.
</para>
<!-- ##### SECTION ./tmpl/pty.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### SECTION ./tmpl/pty.sgml:Short_Description ##### -->
Functions for starting a new process on a new pseudo-terminal and for
manipulating psuedo-terminals.
<!-- ##### SECTION ./tmpl/pty.sgml:Title ##### -->
pty
<!-- ##### FUNCTION vte_pty_get_size ##### -->
<para>
</para>
@master:
@columns:
@rows:
@Returns:
<!-- ##### FUNCTION vte_pty_open ##### -->
<para>
</para>
@child:
@env_add:
@command:
@argv:
@directory:
@columns:
@rows:
@lastlog:
@utmp:
@wtmp:
@Returns:
<!-- ##### FUNCTION vte_pty_set_size ##### -->
<para>
</para>
@master:
@columns:
@rows:
@Returns:
<!-- ##### FUNCTION vte_terminal_fork_logged_command ##### -->
<para>
</para>
@terminal:
@command:
@argv:
@envv:
@lastlog:
@utmp:
@wtmp:
@Returns:
......@@ -72,18 +72,7 @@ A VteTerminal is a terminal emulator implemented as a GTK2 widget.
@command:
@argv:
@envv:
@Returns:
<!-- ##### FUNCTION vte_terminal_fork_logged_command ##### -->
<para>
</para>
@terminal:
@command:
@argv:
@envv:
@directory:
@lastlog:
@utmp:
@wtmp:
......@@ -447,6 +436,7 @@ A VteTerminal is a terminal emulator implemented as a GTK2 widget.
@terminal:
@is_selected:
@data:
@attributes:
@Returns:
......@@ -462,6 +452,7 @@ A VteTerminal is a terminal emulator implemented as a GTK2 widget.
@end_row:
@end_col:
@is_selected:
@data:
@attributes:
@Returns:
......
......@@ -3,7 +3,6 @@
<!ENTITY vte-vteaccess SYSTEM "sgml/vteaccess.sgml">
<!ENTITY vte-VteReaper SYSTEM "sgml/reaper.sgml">
<!ENTITY vte-caps SYSTEM "sgml/caps.sgml">
<!ENTITY vte-pty SYSTEM "sgml/pty.sgml">
<!ENTITY vte-termcap SYSTEM "sgml/termcap.sgml">
<!ENTITY vte-trie SYSTEM "sgml/trie.sgml">
<!ENTITY vte-debug SYSTEM "sgml/debug.sgml">
......@@ -21,6 +20,5 @@
&vte-VteTerminal;
&vte-vteaccess;
&vte-VteReaper;
&vte-pty;
</chapter>
</book>
......@@ -7,7 +7,6 @@ VteTerminal
vte_terminal_new
vte_terminal_im_append_menuitems
vte_terminal_fork_command
vte_terminal_fork_logged_command
vte_terminal_feed
vte_terminal_feed_child
vte_terminal_copy_clipboard
......@@ -110,10 +109,3 @@ VTE_REAPER_CLASS
VTE_IS_REAPER_CLASS
VTE_REAPER_GET_CLASS
</SECTION>
<SECTION>
<FILE>pty</FILE>
vte_pty_open
vte_pty_get_size
vte_pty_set_size
</SECTION>
......@@ -10,9 +10,16 @@ def main_quit(object, *args):
def commit_cb(object, *args):
(text, length) = args
# Echo the text input by the user to stdout.
sys.stdout.write(text)
sys.stdout.flush()
# Echo the text input by the user to stdout. Note that the string's
# length isn't always going to be right.
if (0):
sys.stdout.write(text)
sys.stdout.flush()
else:
# Test the get_text() function.
for line in (string.splitfields(object.get_text(),"\n")):
if (line.__len__() > 0):
print line
# Also display it.
object.feed(text, length)
......
......@@ -48,17 +48,7 @@
'("const-char*" "command")
'("char**" "argv")
'("char**" "envv")
)
)
(define-method fork_logged_command
(of-object "VteTerminal")
(c-name "vte_terminal_fork_logged_command")
(return-type "pid_t")
(parameters
'("const-char*" "command")
'("char**" "argv")
'("char**" "envv")
'("const-char*" "directory")
'("gboolean" "lastlog")
'("gboolean" "utmp")
'("gboolean" "wtmp")
......
......@@ -3,6 +3,7 @@
headers
#include <Python.h>
#include <pygtk/pygtk.h>
#include <pygobject.h>
#include <gtk/gtk.h>
#include "../src/vte.h"
%%
......@@ -10,24 +11,26 @@ import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import gtk.MenuShell as PyGtkMenuShell_Type
import gtk.Widget as PyGtkWidget_Type
%%
ignore vte_terminal_get_text
ignore vte_terminal_get_text_range
%%
override vte_terminal_fork_command kwargs
static PyObject *
_wrap_vte_terminal_fork_command(PyGObject * self, PyObject * args,
PyObject * kwargs)
{
gchar **argv = NULL, **envv = NULL;
gchar *command = NULL;
static char *kwlist[] = { "command", "argv", "envv", NULL };
PyObject *py_argv = NULL, *py_envv = NULL;
gchar *command = NULL, *directory = NULL;
static char *kwlist[] = { "command", "argv", "envv", "directory",
"loglastlog", "logutmp", "logwtmp",
NULL };
PyObject *py_argv = NULL, *py_envv = NULL,
*loglastlog = NULL, *logutmp = NULL, *logwtmp = NULL;
int i, n_args, n_envs;
pid_t pid;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sOO:fork_command",
kwlist, &command, &py_argv,
&py_envv)) {
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sOOsOOO:fork_command",
kwlist, &command, &py_argv, &py_envv,
&directory,
&loglastlog, &logutmp, &logwtmp)) {
return NULL;
}
......@@ -67,7 +70,13 @@ _wrap_vte_terminal_fork_command(PyGObject * self, PyObject * args,
}
pid = vte_terminal_fork_command(VTE_TERMINAL(self->obj),
command, argv, envv);
command, argv, envv, directory,
(loglastlog != NULL) &&
PyObject_IsTrue(loglastlog),
(logutmp != NULL) &&
PyObject_IsTrue(logutmp),
(logwtmp != NULL) &&
PyObject_IsTrue(logwtmp));
if (argv) {
g_free(argv);
......@@ -76,3 +85,222 @@ _wrap_vte_terminal_fork_command(PyGObject * self, PyObject * args,
return PyInt_FromLong(pid);
}
%%
override vte_terminal_get_text kwargs
static gboolean
call_callback(VteTerminal *terminal, glong column, glong row, gpointer data)
{
PyObject *cb, *self, *args, *result;
gboolean ret;
int i;
if (!PyArg_ParseTuple(data, "|O:call_callback", &args)) {
return FALSE;
}
args = PyList_New(0);
cb = PySequence_GetItem(args, 0); /* INCREFs */
Py_DECREF(cb);
self = PySequence_GetItem(args, 1); /* INCREFs */
Py_DECREF(self);
PyList_Append(args, self);
PyList_Append(args, PyInt_FromLong(column));
PyList_Append(args, PyInt_FromLong(row));
for (i = 2; i < PySequence_Length(args); i++) {
PyObject *item = PySequence_GetItem(args, i);
Py_DECREF(item);
PyList_Append(args, item);
}
result = PyObject_CallObject(cb, args);
ret = (result && PyObject_IsTrue(result));
Py_DECREF(args);
Py_DECREF(result);
return ret;
}
static gboolean
always_true(VteTerminal *terminal, glong row, glong column, gpointer data)
{
return TRUE;
}
static PyObject *
_wrap_vte_terminal_get_text(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "callback", "attributes", "data", NULL };
PyObject *callback = NULL, *do_attr = NULL, *data = NULL;
PyObject *callback_and_args = NULL;
GArray *attrs = NULL;
PyObject *text;
PyObject *py_attrs;
int count;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO:terminal_get_text",
kwlist, &callback, &do_attr, &args)) {
return NULL;
}
if (do_attr != NULL && do_attr != Py_None) {
attrs = g_array_new(FALSE, TRUE, sizeof(struct vte_char_attributes));
} else {
attrs = NULL;
}
if ((callback != NULL) && (callback != Py_None)) {
if (!PyCallable_Check(callback)) {
PyErr_SetString(PyExc_TypeError, "1st argument not callable.");
if (attrs) {
g_array_free(attrs, TRUE);
}
return NULL;
}
} else {
callback = NULL;
}
if (callback != NULL) {
callback_and_args = PyList_New(0);
PyList_Append(callback_and_args, callback);
PyList_Append(callback_and_args, (PyObject*) self);
if (PyList_Check(data)) {
for (count = 0; count < PyList_Size(data); count++) {
PyList_Append(callback_and_args, PyList_GetItem(data, count));
}
} else {
PyList_Append(callback_and_args, data);
}
}
text = PyString_FromString(vte_terminal_get_text(VTE_TERMINAL(self->obj),
callback ?
call_callback :
always_true,
callback ?
callback_and_args :
NULL,
attrs));
Py_XDECREF(callback_and_args);
if (attrs) {
py_attrs = PyTuple_New(attrs->len);
for (count = 0; count < attrs->len; count++) {
struct vte_char_attributes *cht;
PyObject *py_char_attr;
PyObject *py_gdkcolor;
cht = &g_array_index(attrs, struct vte_char_attributes, count);
py_char_attr = PyDict_New();
PyDict_SetItemString(py_char_attr, "row", PyInt_FromLong(cht->row));
PyDict_SetItemString(py_char_attr, "column", PyInt_FromLong(cht->column));
py_gdkcolor = pyg_boxed_new(GDK_TYPE_COLOR, &cht->fore, TRUE, TRUE);
PyDict_SetItemString(py_char_attr, "fore", py_gdkcolor);
py_gdkcolor = pyg_boxed_new(GDK_TYPE_COLOR, &cht->back, TRUE, TRUE);
PyDict_SetItemString(py_char_attr, "back", py_gdkcolor);
PyDict_SetItemString(py_char_attr, "underline",
PyInt_FromLong(cht->underline));
PyDict_SetItemString(py_char_attr, "alternate",
PyInt_FromLong(cht->alternate));
PyTuple_SetItem(py_attrs, count, py_char_attr);
}
g_array_free(attrs, TRUE);
return Py_BuildValue("(OO)", text, py_attrs);
} else {
return Py_BuildValue("O", text);
}
}
%%
override vte_terminal_get_text_range kwargs
static PyObject *
_wrap_vte_terminal_get_text_range(PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { "callback", "start_row", "start_col", "end_row",
"end_col", "attributes", "data", NULL };
PyObject *callback = NULL, *do_attr = NULL, *data = NULL;
glong start_row, start_col, end_row, end_col;
PyObject *callback_and_args = NULL;
GArray *attrs = NULL;
PyObject *text;
PyObject *py_attrs;
int count;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|llllOOO:terminal_get_text",
kwlist,
&start_row, &start_col, &end_row, &end_col,
&callback, &do_attr, &args)) {
return NULL;
}
if (do_attr != NULL && do_attr != Py_None) {
attrs = g_array_new(FALSE, TRUE, sizeof(struct vte_char_attributes));
} else {
attrs = NULL;
}
if ((callback != NULL) && (callback != Py_None)) {
if (!PyCallable_Check(callback)) {
PyErr_SetString(PyExc_TypeError, "1st argument not callable.");
if (attrs) {
g_array_free(attrs, TRUE);
}
return NULL;
}
} else {
callback = NULL;
}
if (callback != NULL) {
callback_and_args = PyList_New(0);
PyList_Append(callback_and_args, callback);
PyList_Append(callback_and_args, (PyObject*) self);
if (PyList_Check(data)) {
for (count = 0; count < PyList_Size(data); count++) {
PyList_Append(callback_and_args, PyList_GetItem(data, count));
}
} else {
PyList_Append(callback_and_args, data);
}
}
text = PyString_FromString(vte_terminal_get_text_range(VTE_TERMINAL(self->obj),
start_row, start_col,
end_row, end_col,
callback ?
call_callback :
always_true,
callback ?
callback_and_args :
NULL,
attrs));
Py_XDECREF(callback_and_args);
if (attrs) {
py_attrs = PyTuple_New(attrs->len);
for (count = 0; count < attrs->len; count++) {
struct vte_char_attributes *cht;
PyObject *py_char_attr;
PyObject *py_gdkcolor;
cht = &g_array_index(attrs, struct vte_char_attributes, count);
py_char_attr = PyDict_New();
PyDict_SetItemString(py_char_attr, "row", PyInt_FromLong(cht->row));
PyDict_SetItemString(py_char_attr, "column", PyInt_FromLong(cht->column));
py_gdkcolor = pyg_boxed_new(GDK_TYPE_COLOR, &cht->fore, TRUE, TRUE);
PyDict_SetItemString(py_char_attr, "fore", py_gdkcolor);
py_gdkcolor = pyg_boxed_new(GDK_TYPE_COLOR, &cht->back, TRUE, TRUE);
PyDict_SetItemString(py_char_attr, "back", py_gdkcolor);
PyDict_SetItemString(py_char_attr, "underline",
PyInt_FromLong(cht->underline));
PyDict_SetItemString(py_char_attr, "alternate",
PyInt_FromLong(cht->alternate));
PyTuple_SetItem(py_attrs, count, py_char_attr);
}
g_array_free(attrs, TRUE);
return Py_BuildValue("(OO)", text, py_attrs);
} else {
return Py_BuildValue("O", text);
}
}
%%
......@@ -48,7 +48,7 @@ libvte_la_SOURCES = \
vteaccess.h
libvte_la_LIBADD = @LIBS@ @VTE_LIBS@ @X_LIBS@
libvte_la_LDFLAGS = -version-info 4:0:1
libvte_la_LDFLAGS = -version-info 4:0:0
CLEANFILES = marshal.c marshal.h
......
......@@ -64,6 +64,9 @@ _vte_debug_parse_string(const char *string)
} else
if (g_ascii_strcasecmp(flags[i], "PTY") == 0) {
_vte_debug_flags |= VTE_DEBUG_PTY;
} else
if (g_ascii_strcasecmp(flags[i], "CURSOR") == 0) {
_vte_debug_flags |= VTE_DEBUG_CURSOR;
}
}
g_strfreev(flags);
......
......@@ -35,7 +35,8 @@ typedef enum {
VTE_DEBUG_SELECTION = 1 << 6,
VTE_DEBUG_SUBSTITUTION = 1 << 7,
VTE_DEBUG_RING = 1 << 8,
VTE_DEBUG_PTY = 1 << 9
VTE_DEBUG_PTY = 1 << 9,
VTE_DEBUG_CURSOR = 1 << 10
} VteDebugFlags;
void _vte_debug_parse_string(const char *string);
......
......@@ -201,7 +201,8 @@ _vte_pty_pipe_open_bi(int *a, int *b, int *c, int *d)
* terminal. */
static int
_vte_pty_run_on_pty(int fd, int ready_reader, int ready_writer,
char **env_add, const char *command, char **argv)
char **env_add, const char *command, char **argv,
const char *directory)
{
int i;
char c;
......@@ -261,6 +262,11 @@ _vte_pty_run_on_pty(int fd, int ready_reader, int ready_writer,
* weird things to them. */
_vte_pty_reset_signal_handlers();
/* Change to the requested directory. */
if (directory != NULL) {
chdir(directory);
}
/* Signal to the parent that we've finished setting things up by
* sending an arbitrary byte over the status pipe and waiting for
* a response. This synchronization step ensures that the pty is
......@@ -310,6 +316,7 @@ _vte_pty_run_on_pty(int fd, int ready_reader, int ready_writer,
static int
_vte_pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
const char *command, char **argv,
const char *directory,
int columns, int rows, pid_t *child)
{
int fd, i;
......@@ -353,7 +360,7 @@ _vte_pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
fprintf(stderr, "Parent received child-ready.\n");
}
#endif
vte_pty_set_size(parent_fd, columns, rows);
_vte_pty_set_size(parent_fd, columns, rows);
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_PTY)) {
fprintf(stderr, "Parent sending parent-ready.\n");
......@@ -389,7 +396,7 @@ _vte_pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
return -1;
}
return _vte_pty_run_on_pty(fd, ready_b[0], ready_a[1],
env_add, command, argv);
env_add, command, argv, directory);
}
/* Fork off a child (storing its PID in child), and exec the named command
......@@ -397,6 +404,7 @@ _vte_pty_fork_on_pty_name(const char *path, int parent_fd, char **env_add,
static int
_vte_pty_fork_on_pty_fd(int fd, char **env_add,
const char *command, char **argv,
const char *directory,
int columns,