-2002-09-10 Jacob Berkman <jacob@ximian.com>
+2002-09-11 nalin
+ * src/vte.c: Skip lookups for padding information if we're pretty sure
+ we're using a monospaced font.
+
+2002-09-10 nalin
+ * src/vte.c: Fix from Brian Cameron for uninitialized GError in
+ vte_wc_from_unichar().
+ * src/interpret.c, src/iso2022.c, src/pty.c, src/ring.h, src/table.c,
+ src/table.h, src/trie.c, src/vte.c, src/vteaccess.c: Signed/unsigned
+ int/size_t/gsize and pointer typecast warning fixes from Brian Cameron.
+ * src/vte.c: Avoid invalidating the cursor in the cursor blink
+ timeout unless we have focus.
+2002-09-10 Jacob Berkman <jacob@ximian.com>
* configure.in (ALL_LINGUAS: remove es until the file really gets
added. also it wasn't added alphabetically
* configure.in: Added "es" to ALL_LINGUAS
+2002-09-10 nalin
+ * src/pty.c, src/pty.h: Add vte_pty_close() and
+ vte_pty_open_with_logging(), breaking the ABI.
+ * src/vte.c, src/vte.h: Add vte_terminal_fork_logged_command(), breaking
+ the ABI.
+ * gnome-pty-helper/*: Swallow the pty helper bits of gnome-libs,
+ but install into $pkglibdir instead of $sbindir so that existing
+ packages don't suddenly start breaking.
+ * src/termcap.c(_vte_termcap_find_string_length): Fix signature to
+ match the declaration in termcap.h. From patch by Jacob Berkman.
+
+2002-09-06 nalin
+ * configure.in: Add $X_PRE_LIBS to the front of $X_LIBS, -lX11 and
+ $X_EXTRA_LIBS to the end of $X_LIBS. Remove some cruftiness and set
+ CPPFLAGS when checking for Xft. Check for the existence of wchar.h,
+ because it might not exist. Use an automake conditional to make
+ compilation of the Python bindings non-critical. From patch by
+ Jacob Berkman.
+ * src/pty.c: Silence compiler warning when exec() fails. From patch
+ by Jacob Berkman.
+ * src/interpret.c, src/vte.c: Stop including langinfo.h since we don't
+ call nl_langinfo() any more. Adapted from patch by Jacob Berkman.
+ * src/caps.c: Fill in a couple of missing initializers.
+ * src/vte.c, src/vte.h: Add accessor functions for use in language
+ bindings.
+ * python/vte.defs: Add defs for the new accessor functions.
+ * python/vte-demo.py: Add a scrollbar to the sample window, handle
+ more of the options the C version handles. Stop expecting additional
+ arguments with a signal that doesn't include any.
+ * python/Makefile.am: We only have one target, so don't bother with
+ target-specific primaries if we can avoid it (#92252).
+ * vte.pc.in: Note build dependencies on ATK, Pango, and PangoX.
+
2002-09-05 nalin
* src/caps.c, src/caps.h, src/debug.c, src/debug.h, src/interpret.c,
src/iso2022.c, src/iso2022.h, src/pty.c, src/reaper.c, src/ring.c,
-This entire tree is "some highly unsupported crackrock". Please contact me
-directly if you intend to hack on it.
+This entire tree is "some highly unsupported crackrock", yet it seems to have
+reached some degree of stability. Please contact me directly if you intend to
+hack on it.
Thanks,
-SUBDIRS = src python termcaps po doc
+SUBDIRS = src gnome-pty-helper python termcaps po doc
EXTRA_DIST = HACKING vte.spec vte.pc.in
pkgconfigdir = $(libdir)/pkgconfig
+0.9: gnome-pty-helper integration, with lastlog/utmp/wtmp logging
+0.8: iso-2022 substitutions
+0.7: faster rendering
+0.6: faster input parsing
+0.5: internal wchar_t -> gunichar migration
+0.4: (later than should have been) Xft2, python
+0.3: accessibility peer
+prehistory
illustrates more or less what the widget sees after it filters incoming data.
* What's missing?
-- Accessibility isn't completed yet.
+- Accessibility may not work yet.
- Mouse hilite tracking isn't implemented yet.
- Extending the selection using shift+click pays attention to whether or not
the existing selection was done word-at-a-time or line-at-a-time, but
-AC_INIT(configure.in)
+AC_INIT(vte.pc.in)
VERSION=`grep ^Version: $srcdir/vte.spec | awk '{print $NF}'`
AM_INIT_AUTOMAKE(vte,$VERSION)
+
+AC_ISC_POSIX
+AC_PROG_CC
+AC_STDC_HEADERS
+AM_PROG_CC_STDC
+AM_MAINTAINER_MODE
+
AM_PROG_LIBTOOL
ALL_LINGUAS="da de fr nl no pt_BR sv vi"
AM_GLIB_GNU_GETTEXT
#endif
],
AC_DEFINE(_GNU_SOURCE,1,[Use all features.]))
-# AC_SYS_LARGEFILE
+
+# On some OSs, AC_PATH_XTRA doesn't work right(?), so let the user specify
+# X_PRE_LIBS and X_EXTRA_LIBS to add even more libraries, and add -lX11 to
+# the list of libraries for grins.
AC_PATH_XTRA
-PKG_CHECK_MODULES(GLIB,[glib-2.0 gobject-2.0])
-PKG_CHECK_MODULES(GTK, [glib-2.0 gobject-2.0 gdk-pixbuf-2.0 gtk+-2.0 pangox])
+X_LIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS"
+PKG_CHECK_MODULES(GOBJECT,[glib-2.0 gobject-2.0])
+savelibs="$LIBS"
+LIBS="$X_LIBS $LIBS"
if pkg-config --exists pangoxft '>=' 1.1.0 ; then
- havexft=1
AC_DEFINE(HAVE_XFT2,1,[Whether we have Xft version 2])
- PKG_CHECK_MODULES(XFT,[xft])
+ PKG_CHECK_MODULES(VTE,[glib-2.0 gobject-2.0 gdk-pixbuf-2.0 gtk+-2.0 pangox fontconfig xft])
else
- savelibs="$LIBS"
- LIBS="$GTK_LIBS"
- AC_CHECK_FUNC(XftDrawString32,
- [AC_CHECK_HEADER(X11/Xft/Xft.h, havexft=1)])
- LIBS="$savelibs"
+ PKG_CHECK_MODULES(VTE,[glib-2.0 gobject-2.0 gdk-pixbuf-2.0 gtk+-2.0 pangox])
fi
+LIBS="$savelibs"
+# Check whether the combination of X and GLib/Pango/GTK+ libraries includes
+# Xft somewhere.
+savecppflags="$CPPFLAGS"
+savelibs="$LIBS"
+CPPFLAGS="$VTE_CFLAGS $X_CFLAGS $CPPFLAGS"
+LIBS="$VTE_LIBS $X_LIBS"
+AC_CHECK_FUNC(XftDrawString32,[AC_DEFINE(HAVE_XFT,1,[Whether or not Xft is available.])])
+CPPFLAGS="$savecppflags"
+LIBS="$savelibs"
+
+# Define macros to disable accidental use of deprecated functionality.
AC_DEFINE(G_DISABLE_DEPRECATED,1,[Disable deprecated glib features.])
AC_DEFINE(GDK_DISABLE_DEPRECATED,1,[Disable deprecated gdk features.])
AC_DEFINE(GDK_PIXBUF_DISABLE_DEPRECATED,1,[Disable deprecated gdk-pixbuf features.])
AC_DEFINE(GTK_DISABLE_DEPRECATED,1,[Disable deprecated gtk features.])
AC_DEFINE(PANGO_DISABLE_DEPRECATED,1,[Disable deprecated pango features.])
+
AC_DEFINE(VTE_UTF8_BPC,6,[Maximum number of bytes used per UTF-8 character.])
AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE",[Package name.])
AC_CHECK_FUNCS(getpt grantpt unlockpt ptsname ptsname_r)
-AC_CHECK_HEADERS(termios.h)
-AC_CHECK_HEADERS(stropts.h)
-
-# Double-check that the GTK libraries pulled in Xft functionality, then use
-# the GTK CFLAGS to find the Xft headers.
-savelibs="$LIBS"
-LIBS="$GTK_LIBS"
-havexft=0
-AC_CHECK_FUNC(XftDrawString32,havexft=1)
-LIBS="$savelibs"
-if test x$havexft = x1 ; then
- AC_DEFINE(HAVE_XFT, 1, [Whether not Xft is available.])
-fi
-
-AM_MAINTAINER_MODE
+AC_CHECK_HEADERS(sys/un.h stropts.h termios.h wchar.h)
if test x$USE_MAINTAINER_MODE != x ; then
if test x$USE_MAINTAINER_MODE != xno ; then
if test x$GCC = xyes ; then
CFLAGS="${CFLAGS} -std=c99"
CFLAGS="${CFLAGS} -Wall"
- CFLAGS="${CFLAGS} -Wunused"
- CFLAGS="${CFLAGS} -Wuninitialized"
+ CFLAGS="${CFLAGS} -Waggregate-return"
+ CFLAGS="${CFLAGS} -Wcast-align"
CFLAGS="${CFLAGS} -Wimplicit"
- CFLAGS="${CFLAGS} -Wstrict-prototypes"
- CFLAGS="${CFLAGS} -Wmissing-prototypes"
CFLAGS="${CFLAGS} -Wmissing-declarations"
- CFLAGS="${CFLAGS} -Wcast-align"
+ CFLAGS="${CFLAGS} -Wmissing-prototypes"
+ CFLAGS="${CFLAGS} -Wpointer-arith"
+ CFLAGS="${CFLAGS} -Wstrict-prototypes"
+ CFLAGS="${CFLAGS} -Wuninitialized"
+ #CFLAGS="${CFLAGS} −Wsign−compare"
+ #CFLAGS="${CFLAGS} −Wunused-value"
fi
VTE_DEBUG=1
fi
fi
AC_SUBST(PYTHONREV)
AC_SUBST(PYTHONMODULES)
+AM_CONDITIONAL(BUILD_PYTHON_BINDINGS, test "x$PYTHONMODULES" '!=' "x")
+mylibdir=`eval echo $libdir`
mydatadir=`eval echo $datadir`
+if test x$exec_prefix = xNONE ; then
+ if test x$prefix = xNONE ; then
+ mylibdir=` echo $mylibdir | sed s,NONE,$ac_default_prefix,g`
+ else
+ mylibdir=` echo $mylibdir | sed s,NONE,$prefix,g`
+ fi
+fi
if test x$prefix = xNONE ; then
mydatadir=`echo $mydatadir | sed s,NONE,$ac_default_prefix,g`
fi
+AC_DEFINE_UNQUOTED(PKGLIBDIR,"$mylibdir/$PACKAGE",
+ [The location where package-specific helpers can be found.])
AC_DEFINE_UNQUOTED(DATADIR,"$mydatadir",
[The location where arch-independent package-specific data can be found.])
AC_DEFINE_UNQUOTED(LOCALEDIR,"$mydatadir/locale",
GETTEXT_PACKAGE=vte
AC_SUBST(GETTEXT_PACKAGE)
+AC_ARG_ENABLE(gnome-pty-helper, [ --enable-gnome-pty-helper Build a setuid helper for opening ptys [default=yes]], enable_gnome_pty_helper="$enableval", enable_gnome_pty_helper=yes)
+if test "$enable_gnome_pty_helper" != no; then
+ AC_CONFIG_SUBDIRS(gnome-pty-helper)
+fi
+
################################################################################
# This is a check for gtk-doc which you can insert into your configure.in.
################################################################################
AM_CONFIG_HEADER(config.h)
+
AC_OUTPUT([
Makefile
src/Makefile
## Process this file with automake to produce Makefile.in
-# This is a blank Makefile.am for using gtk-doc.
-# Copy this to your project's API docs directory and modify the variables to
-# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
-# of using the various options.
+MAINTAINERCLEANFILES = html/*
+
+# This file was adapted from the sample Makefile.am included with gtk-doc.
+# See the GTK+ Makefiles in gtk+/docs/reference for examples of using the
+# various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=vte
# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib
# contains GtkObjects/GObjects and you want to document signals and properties.
-GTKDOC_CFLAGS = @GTK_CFLAGS@ -I$(srcdir)/../../src
-GTKDOC_LIBS = @GTK_LIBS@ ../../src/libvte.la
+GTKDOC_CFLAGS = @VTE_CFLAGS@ -I$(srcdir)/../../src
+GTKDOC_LIBS = @VTE_LIBS@ ../../src/libvte.la
GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC)
GTKDOC_LD=$(LIBTOOL) --mode=link $(CC)
-<!-- ##### SECTION ./tmpl/caps.sgml:Long_Description ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/caps.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/caps.sgml:Short_Description ##### -->
-Global structures which contain terminal capability names and Xterm control
-sequence definitions.
-
-
-<!-- ##### SECTION ./tmpl/caps.sgml:Title ##### -->
-caps
-
-
-<!-- ##### SECTION ./tmpl/debug.sgml:Long_Description ##### -->
-<para>
-Functions in libvte will only output debugging information if the library was
-configured with --enable-maintainer-mode.
-</para>
-
-
-<!-- ##### SECTION ./tmpl/debug.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/debug.sgml:Short_Description ##### -->
-Facilities for enabling debugging message output from libvte.
-
-
-<!-- ##### SECTION ./tmpl/debug.sgml:Title ##### -->
-debug
-
-
-<!-- ##### SECTION ./tmpl/iso2022.sgml:Long_Description ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/iso2022.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/iso2022.sgml:Short_Description ##### -->
-A state machine for converting #gunichar strings with embedded ISO-2022 control
-sequences into plain #gunichar strings.
-
-
-<!-- ##### SECTION ./tmpl/iso2022.sgml:Title ##### -->
-iso2022
-
-
-<!-- ##### SECTION ./tmpl/marshal.sgml:Long_Description ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/marshal.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/marshal.sgml:Short_Description ##### -->
-Signal marshalers.
-
-
-<!-- ##### SECTION ./tmpl/marshal.sgml:Title ##### -->
-marshal
-
-
-<!-- ##### SECTION ./tmpl/ring.sgml:Long_Description ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/ring.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/ring.sgml:Short_Description ##### -->
-
-
-
-<!-- ##### SECTION ./tmpl/ring.sgml:Title ##### -->
-ring
-
-
-<!-- ##### SECTION ./tmpl/table.sgml:Long_Description ##### -->
-<para>
-This control sequence parser uses a tree of tables, similar in design to that
-used by Xterm, but generated dynamically at run-time using data from the system
-termcap database.
-</para>
-
-
-<!-- ##### SECTION ./tmpl/table.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/table.sgml:Short_Description ##### -->
-The tree-of-tables sequence parser.
-
-
-<!-- ##### SECTION ./tmpl/table.sgml:Title ##### -->
-table
-
-
-<!-- ##### SECTION ./tmpl/termcap.sgml:Long_Description ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/termcap.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/termcap.sgml:Short_Description ##### -->
-A set of functions for parsing the system termcap database.
-
-
-<!-- ##### SECTION ./tmpl/termcap.sgml:Title ##### -->
-termcap
-
-
-<!-- ##### SECTION ./tmpl/trie.sgml:Long_Description ##### -->
-<para>
-This control sequence parser uses a tree of nodes and attempts to find the
-control sequence which best matches a given chunk of data.
-</para>
-
-
-<!-- ##### SECTION ./tmpl/trie.sgml:See_Also ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### SECTION ./tmpl/trie.sgml:Short_Description ##### -->
-The trie sequence parser.
-
-
-<!-- ##### SECTION ./tmpl/trie.sgml:Title ##### -->
-trie
-
-
-<!-- ##### MACRO VTE_CAP_APC ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_CAP_CSI ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_CAP_ESC ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_CAP_OSC ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_CAP_PM ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_CAP_ST ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### MACRO VTE_IS_TERMINAL_ERASE_BINDING ##### -->
-<para>
-
-</para>
-
-@obj:
-
-<!-- ##### MACRO VTE_TYPE_TERMINAL_ERASE_BINDING ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### ENUM VteDebugFlags ##### -->
-<para>
-
-</para>
-
-@VTE_DEBUG_MISC:
-@VTE_DEBUG_PARSE:
-@VTE_DEBUG_IO:
-@VTE_DEBUG_UPDATES:
-@VTE_DEBUG_EVENTS:
-@VTE_DEBUG_SIGNALS:
-@VTE_DEBUG_SELECTION:
-@VTE_DEBUG_SUBSTITUTION:
-@VTE_DEBUG_RING:
-@VTE_DEBUG_PTY:
-
-<!-- ##### STRUCT VteRing ##### -->
-<para>
-
-</para>
-
-@free:
-@user_data:
-@array:
-@delta:
-@length:
-@max:
-
-<!-- ##### USER_FUNCTION VteRingFreeFunc ##### -->
-<para>
-
-</para>
-
-@freeing:
-@data:
-
-<!-- ##### FUNCTION vte_capability_init ##### -->
-<para>
-
-</para>
-
-
-<!-- ##### FUNCTION vte_debug_on ##### -->
-<para>
-
-</para>
-
-@flags:
-@Returns:
-
-<!-- ##### FUNCTION vte_debug_parse_string ##### -->
-<para>
-
-</para>
-
-@string:
-
-<!-- ##### FUNCTION vte_iso2022_free ##### -->
-<para>
-
-</para>
-
-@p:
-
-<!-- ##### FUNCTION vte_iso2022_substitute ##### -->
-<para>
-
-</para>
-
-@state:
-@instring:
-@length:
-@outstring:
-@specials:
-@Returns:
-
-<!-- ##### FUNCTION vte_ring_append ##### -->
-<para>
-
-</para>
-
-@ring:
-@data:
-
-<!-- ##### FUNCTION vte_ring_at ##### -->
-<para>
-
-</para>
-
-@ring:
-@Param2:
-@Returns:
-@__ring:
-@__position:
-
-<!-- ##### FUNCTION vte_ring_contains ##### -->
-<para>
-
-</para>
-
-@ring:
-@Param2:
-@Returns:
-@__ring:
-@__position:
-
-<!-- ##### FUNCTION vte_ring_delta ##### -->
-<para>
-
-</para>
-
-@ring:
-@Returns:
-@__ring:
-
-<!-- ##### FUNCTION vte_ring_free ##### -->
-<para>
-
-</para>
-
-@ring:
-@free_elements:
-
-<!-- ##### MACRO vte_ring_index ##### -->
-<para>
-
-</para>
-
-@ring:
-@cast:
-@position:
-@__ring:
-@__cast:
-@__position:
-
-<!-- ##### FUNCTION vte_ring_insert ##### -->
-<para>
-
-</para>
-
-@ring:
-@Param2:
-@data:
-@position:
-
-<!-- ##### FUNCTION vte_ring_length ##### -->
-<para>
-
-</para>
-
-@ring:
-@Returns:
-@__ring:
-
-<!-- ##### FUNCTION vte_ring_new ##### -->
-<para>
-
-</para>
-
-@Param1:
-@free:
-@data:
-@Returns:
-@max_elements:
-
-<!-- ##### FUNCTION vte_ring_next ##### -->
-<para>
-
-</para>
-
-@ring:
-@Returns:
-@__ring:
-
-<!-- ##### FUNCTION vte_ring_remove ##### -->
-<para>
-
-</para>
-
-@ring:
-@Param2:
-@free_element:
-@position:
-
-<!-- ##### FUNCTION vte_table_add ##### -->
-<para>
-
-</para>
-
-@table:
-@pattern:
-@length:
-@result:
-@quark:
-
-<!-- ##### FUNCTION vte_table_free ##### -->
-<para>
-
-</para>
-
-@table:
-
-<!-- ##### FUNCTION vte_table_match ##### -->
-<para>
-
-</para>
-
-@table:
-@pattern:
-@length:
-@res:
-@consumed:
-@quark:
-@array:
-@Returns:
-
-<!-- ##### FUNCTION vte_table_narrow_encoding ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-<!-- ##### FUNCTION vte_table_print ##### -->
-<para>
-
-</para>
-
-@table:
-
-<!-- ##### FUNCTION vte_table_wide_encoding ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_find_boolean ##### -->
-<para>
-
-</para>
-
-@termcap:
-@tname:
-@cap:
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_find_numeric ##### -->
-<para>
-
-</para>
-
-@termcap:
-@tname:
-@cap:
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_find_string ##### -->
-<para>
-
-</para>
-
-@termcap:
-@tname:
-@cap:
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_find_string_length ##### -->
-<para>
-
-</para>
-
-@termcap:
-@tname:
-@cap:
-@length:
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_free ##### -->
-<para>
-
-</para>
-
-@termcap:
-
-<!-- ##### FUNCTION vte_termcap_new ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-<!-- ##### FUNCTION vte_termcap_strip ##### -->
-<para>
-
-</para>
-
-@termcap:
-@stripped:
-@len:
-
-<!-- ##### FUNCTION vte_terminal_erase_binding_get_type ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-<!-- ##### FUNCTION vte_trie_add ##### -->
-<para>
-
-</para>
-
-@trie:
-@pattern:
-@length:
-@result:
-@quark:
-
-<!-- ##### FUNCTION vte_trie_free ##### -->
-<para>
-
-</para>
-
-@trie:
-
-<!-- ##### FUNCTION vte_trie_match ##### -->
-<para>
-
-</para>
-
-@trie:
-@pattern:
-@length:
-@res:
-@consumed:
-@quark:
-@array:
-@Returns:
-
-<!-- ##### FUNCTION vte_trie_narrow_encoding ##### -->
-<para>
-
-</para>
-
-@Returns:
-
-<!-- ##### FUNCTION vte_trie_print ##### -->
-<para>
-
-</para>
-
-@trie:
-
-<!-- ##### FUNCTION vte_trie_wide_encoding ##### -->
-<para>
-
-</para>
-
-@Returns:
-
@ypad:
+<!-- ##### FUNCTION vte_terminal_get_adjustment ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_char_ascent ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_char_descent ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_char_height ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_char_width ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_column_count ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_icon_title ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_row_count ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
+<!-- ##### FUNCTION vte_terminal_get_window_title ##### -->
+<para>
+
+</para>
+
+@terminal:
+@Returns:
+
+
<!-- ##### SIGNAL VteTerminal::char-size-changed ##### -->
<para>
Emitted whenever selection of a new font causes the values of the
VTE_TERMINAL_CLASS
VTE_IS_TERMINAL_CLASS
VTE_TERMINAL_GET_CLASS
+<SUBSECTION Binding Accessors>
+vte_terminal_get_adjustment
+vte_terminal_get_char_ascent
+vte_terminal_get_char_descent
+vte_terminal_get_char_height
+vte_terminal_get_char_width
+vte_terminal_get_column_count
+vte_terminal_get_icon_title
+vte_terminal_get_row_count
+vte_terminal_get_window_title
</SECTION>
<SECTION>
--- /dev/null
+Michael Zucchi <zucchi@helixcode.com>
+Dugan Porter
+Miguel de Icaza <miguel@gnu.org>
+Timur Bakeyev <timur@gnu.org>
--- /dev/null
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+vtelibdir = $(libdir)/vte
+vtelib_PROGRAMS = gnome-pty-helper
+
+gnome_pty_helper_SOURCES = \
+ gnome-pty.h \
+ gnome-login-support.c \
+ gnome-login-support.h \
+ gnome-pty-helper.c \
+ gnome-utmp.c
+
+install-exec-hook:
+ chown root.utmp $(DESTDIR)/$(vtelibdir)/gnome-pty-helper || true
+ chmod g+s $(DESTDIR)/$(vtelibdir)/gnome-pty-helper || true
--- /dev/null
+This is some bits from gnome-libs CVS extracted to make a more-or-less
+standalone gnome-pty-helper kit (except for the default installation directory
+being hard-coded to ${libdir}/vte). Like the rest of gnome-libs, its license
+is the LGPL.
--- /dev/null
+# Checks for availability of various utmp fields
+#
+# Original code by Bernhard Rosenkraenzer (bero@linux.net.eu.org), 1998.
+# Modifications by Timur Bakeyev (timur@gnu.org), 1999.
+#
+
+dnl GPH_CHECK_UTMP()
+dnl Test for presence of the field and define HAVE_UT_UT_field macro
+dnl
+
+AC_DEFUN(GPH_CHECK_UTMP,[
+
+AC_CHECK_HEADERS(sys/time.h utmp.h utmpx.h)
+AC_HEADER_TIME
+
+if test "$ac_cv_header_utmpx_h" = "yes"; then
+ AC_DEFINE(UTMP,[struct utmpx],[Define to the name of a structure which holds utmp data.])
+else
+ AC_DEFINE(UTMP,[struct utmp],[Define to the name of a structure which holds utmp data.])
+fi
+
+dnl some systems (BSD4.4-like) require time.h to be included before utmp.h :/
+AC_MSG_CHECKING(for ut_host field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; char *p; p=ut.ut_host;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_HOST,1,[Define if your utmp struct contains a ut_host field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_pid field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; int i; i=ut.ut_pid;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_PID,1,[Define if your utmp struct contains a ut_pid field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_id field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; char *p; p=ut.ut_id;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_ID,1,[Define if your utmp struct contains a ut_id field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_name field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; char *p; p=ut.ut_name;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_NAME,1,[Define if your utmp struct contains a ut_name field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_type field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; int i; i=(int) ut.ut_type;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_TYPE,1,[Define if your utmp struct contains a ut_type field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_exit.e_termination field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; ut.ut_exit.e_termination=0;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_EXIT_E_TERMINATION,1,[Define if your utmp struct contains a ut_exit.e_termination field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_user field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; char *p; p=ut.ut_user;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_USER,1,[Define if your utmp struct contains a ut_user field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_time field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; ut.ut_time=0;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_TIME,1,[Define if your utmp struct contains a ut_time field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_tv field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; ut.ut_tv={0, 0};],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_TV,1,[Define if your utmp struct contains a ut_tv field.])
+fi
+AC_MSG_RESULT($result)
+
+AC_MSG_CHECKING(for ut_syslen field in the utmp structure)
+AC_TRY_COMPILE([#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif],[UTMP ut; ut.ut_syslen=0;],result=yes,result=no)
+if test "$result" = "yes"; then
+ AC_DEFINE(HAVE_UT_UT_SYSLEN,1,[Define if your utmp struct contains a ut_syslen field.])
+fi
+AC_MSG_RESULT($result)
+
+])
--- /dev/null
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+PROJECT=gnome-pty-helper
+TEST_TYPE=-f
+
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $PROJECT."
+ echo "libtool the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+have_automake=false
+if automake --version < /dev/null > /dev/null 2>&1 ; then
+ automake_version=`automake --version | grep 'automake (GNU automake.*)' | sed 's/^[^0-9]*\(.*\)/\1/'`
+ case $automake_version in
+ 1.2*|1.3*|1.4*)
+ ;;
+ *)
+ have_automake=true
+ ;;
+ esac
+fi
+if $have_automake ; then : ; else
+ echo
+ echo "You must have automake 1.5 installed to compile $PROJECT."
+ echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.5.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+fi
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$AUTOGEN_SUBDIR_MODE"; then
+ if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+ fi
+fi
+
+case $CC in
+*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;;
+esac
+
+touch config.h.in
+aclocal $ACLOCAL_FLAGS
+
+# optionally feature autoheader
+(autoheader --version) < /dev/null > /dev/null 2>&1 && autoheader
+
+automake -a -c $am_opt
+autoconf
+cd $ORIGDIR
+
+if test -z "$AUTOGEN_SUBDIR_MODE"; then
+ $srcdir/configure --enable-maintainer-mode "$@"
+ chmod -Rf u+w $srcdir
+ echo
+ echo "Now type 'make' to compile $PROJECT."
+fi
--- /dev/null
+AC_INIT(gnome-pty.h)
+
+AM_INIT_AUTOMAKE(gnome-pty-helper,1.95.0)
+
+AC_ISC_POSIX
+AC_PROG_CC
+AC_STDC_HEADERS
+AM_PROG_CC_STDC
+
+AM_MAINTAINER_MODE
+
+AC_CHECK_HEADERS(sys/syslimits.h sys/time.h sys/types.h sys/un.h alloca.h lastlog.h libutil.h paths.h pty.h stropts.h termios.h ttyent.h util.h utmp.h utmpx.h)
+AC_CHECK_FUNCS(endutent fcntl forkpty getttyent getutent getutmpx grantpt flock login_tty openpty revoke sendmsg seteuid setreuid setutent strrchr updwtmp updwtmpx utmpname utmpxname)
+GPH_CHECK_UTMP
+
+AM_CONFIG_HEADER(config.h)
+AC_OUTPUT(Makefile)
--- /dev/null
+/*
+ * gnome-login-support.c:
+ * Replacement for systems that lack login_tty, open_pty and forkpty
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ *
+ */
+#include <config.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <grp.h>
+#include <sys/types.h>
+#include "gnome-login-support.h"
+
+/*
+ * HAVE_OPENPTY => HAVE_FORKPTY
+ */
+
+#ifndef HAVE_LOGIN_TTY
+int
+login_tty (int fd)
+{
+ pid_t pid = getpid ();
+
+ /* Create the session */
+ setsid ();
+
+#ifdef TIOCSCTTY
+ if (ioctl (fd, TIOCSCTTY, 0) == -1)
+ return -1;
+#else /* !TIOCSTTY */
+ /* Hackery to set controlling tty on SVR4 -
+ on SVR4 the first terminal we open after sesid()
+ becomes our controlling terminal, thus we must
+ find the name of, open, and re-close the tty
+ since we already have it open at this point. */
+ {
+ char *ctty;
+ int ct_fdes;
+
+ ctty = ttyname(fd);
+ ct_fdes = open(ctty, O_RDWR);
+ close(ct_fdes);
+ }
+#endif /* !TIOCSTTY */
+
+#if defined (_POSIX_VERSION) || defined (__svr4__)
+ tcsetpgrp (0, pid);
+#elif defined (TIOCSPGRP)
+ ioctl (0, TIOCSPGRP, &pid);
+#endif
+
+ dup2 (fd, 0);
+ dup2 (fd, 1);
+ dup2 (fd, 2);
+ if (fd > 2)
+ close (fd);
+
+ return 0;
+}
+#endif
+
+#ifndef HAVE_OPENPTY
+static int
+pty_open_master_bsd (char *pty_name, int *used_bsd)
+{
+ int pty_master;
+ char *ptr1, *ptr2;
+
+ *used_bsd = 1;
+
+ strcpy (pty_name, "/dev/ptyXX");
+ for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1; ++ptr1)
+ {
+ pty_name [8] = *ptr1;
+ for (ptr2 = "0123456789abcdef"; *ptr2; ++ptr2)
+ {
+ pty_name [9] = *ptr2;
+
+ /* Try to open master */
+ if ((pty_master = open (pty_name, O_RDWR)) == -1) {
+ if (errno == ENOENT) /* Different from EIO */
+ return -1; /* Out of pty devices */
+ else
+ continue; /* Try next pty device */
+ }
+ pty_name [5] = 't'; /* Change "pty" to "tty" */
+ if (access (pty_name, 6)){
+ close (pty_master);
+ pty_name [5] = 'p';
+ continue;
+ }
+ return pty_master;
+ }
+ }
+ return -1; /* Ran out of pty devices */
+}
+
+static int
+pty_open_slave_bsd (const char *pty_name)
+{
+ int pty_slave;
+ struct group *group_info = getgrnam ("tty");
+
+ if (group_info != NULL)
+ {
+ /* The following two calls will only succeed if we are root */
+
+ chown (pty_name, getuid (), group_info->gr_gid);
+ chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP);
+ }
+ else
+ {
+ chown (pty_name, getuid (), -1);
+ chmod (pty_name, S_IRUSR | S_IWUSR | S_IWGRP);
+ }
+
+#ifdef HAVE_REVOKE
+ revoke (pty_name);
+#endif
+
+ if ((pty_slave = open (pty_name, O_RDWR)) == -1){
+ return -1;
+ }
+
+ return pty_slave;
+}
+
+/* SystemVish pty opening */
+#if defined (HAVE_GRANTPT)
+
+#ifdef HAVE_STROPTS_H
+# include <stropts.h>
+#endif
+
+static int
+pty_open_slave (const char *pty_name)
+{
+ int pty_slave = open (pty_name, O_RDWR);
+
+ if (pty_slave == -1)
+ return -1;
+
+#ifdef HAVE_STROPTS_H
+#if !defined(__osf__)
+ if (!ioctl (pty_slave, I_FIND, "ptem"))
+ if (ioctl (pty_slave, I_PUSH, "ptem") == -1){
+ close (pty_slave);
+ return -1;
+ }
+
+ if (!ioctl (pty_slave, I_FIND, "ldterm"))
+ if (ioctl (pty_slave, I_PUSH, "ldterm") == -1){
+ close (pty_slave);
+ return -1;
+ }
+
+#if !defined(sgi) && !defined(__sgi)
+ if (!ioctl (pty_slave, I_FIND, "ttcompat"))
+ if (ioctl (pty_slave, I_PUSH, "ttcompat") == -1)
+ {
+ perror ("ioctl (pty_slave, I_PUSH, \"ttcompat\")");
+ close (pty_slave);
+ return -1;
+ }
+#endif /* sgi || __sgi */
+#endif /* __osf__ */
+#endif /* HAVE_STROPTS_H */
+
+ return pty_slave;
+}
+
+static int
+pty_open_master (char *pty_name, int *used_bsd)
+{
+ int pty_master;
+ char *slave_name;
+
+ strcpy (pty_name, "/dev/ptmx");
+
+ pty_master = open (pty_name, O_RDWR);
+
+ /*
+ * Try BSD open, this is needed for Linux which
+ * might have Unix98 devices but no kernel support
+ * for those.
+ */
+ if (pty_master == -1){
+ *used_bsd = 1;
+ return pty_open_master_bsd (pty_name, used_bsd);
+ }
+ *used_bsd = 0;
+
+ if (grantpt (pty_master) == -1 || unlockpt (pty_master) == -1){
+ close (pty_master);
+ return -1;
+ }
+ if ((slave_name = ptsname (pty_master)) == NULL){
+ close (pty_master);
+ return -1;
+ }
+ strcpy (pty_name, slave_name);
+ return pty_master;
+}
+#else
+# define pty_open_master pty_open_master_bsd
+# define pty_open_slave pty_open_slave_bsd
+#endif
+
+int
+openpty (int *master_fd, int *slave_fd, char *name, struct termios *termp, struct winsize *winp)
+{
+ int pty_master, pty_slave, used_bsd = 0;
+ struct group *group_info;
+ char line [256];
+
+ pty_master = pty_open_master (line, &used_bsd);
+ fcntl (pty_master, F_SETFD, FD_CLOEXEC);
+
+ if (pty_master == -1)
+ return -1;
+
+ group_info = getgrnam ("tty");
+
+ if (group_info != NULL){
+ chown (line, getuid (), group_info->gr_gid);
+ chmod (line, S_IRUSR | S_IWUSR | S_IWGRP);
+ }
+ else
+ {
+ chown (line, getuid (), -1);
+ chmod (line, S_IRUSR | S_IWUSR | S_IWGRP);
+ }
+
+#ifdef HAVE_REVOKE
+ revoke (line);
+#endif
+
+ /* Open slave side */
+ if (used_bsd)
+ pty_slave = pty_open_slave_bsd (line);
+ else
+ pty_slave = pty_open_slave (line);
+
+ if (pty_slave == -1){
+ close (pty_master);
+
+ errno = ENOENT;
+ return -1;
+ }
+ fcntl (pty_slave, F_SETFD, FD_CLOEXEC);
+
+ *master_fd = pty_master;
+ *slave_fd = pty_slave;
+
+ if (termp)
+ tcsetattr (pty_slave, TCSAFLUSH, termp);
+
+ if (winp)
+ ioctl (pty_slave, TIOCSWINSZ, winp);
+
+ if (name)
+ strcpy (name, line);
+
+ return 0;
+}
+
+pid_t
+forkpty (int *master_fd, char *name, struct termios *termp, struct winsize *winp)
+{
+ int master, slave;
+ pid_t pid;
+
+ if (openpty (&master, &slave, name, termp, winp) == -1)
+ return -1;
+
+ pid = fork ();
+
+ if (pid == -1)
+ return -1;
+
+ /* Child */
+ if (pid == 0){
+ close (master);
+ login_tty (slave);
+ } else {
+ *master_fd = master;
+ close (slave);
+ }
+
+ return pid;
+}
+#endif /* HAVE_OPENPTY */
+
+int
+n_read (int fd, void *buffer, int n)
+{
+ int left, nread;
+ char *ptr;
+
+ ptr = buffer;
+ left = n;
+ while (left > 0){
+ if ((nread = read (fd, ptr, left)) < 0){
+ if (errno == EINTR)
+ nread = 0;
+ else
+ return -1;
+ } else if (nread == 0)
+ break; /* EOF */
+
+ left -= nread;
+ ptr += nread;
+ }
+
+ return n - left;
+}
+
--- /dev/null
+#ifndef _GNOME_LOGIN_SUPPORT_H
+#define _GNOME_LOGIN_SUPPORT_H
+
+#ifdef HAVE_OPENPTY
+#if defined(HAVE_PTY_H)
+# include <pty.h>
+#elif defined(HAVE_UTIL_H) /* OpenBSD */
+# include <util.h>
+#elif defined(HAVE_LIBUTIL_H) /* FreeBSD */
+# include <libutil.h>
+#elif defined(HAVE_LIBUTIL) /* BSDI has libutil, but no libutil.h */
+/* Avoid pulling in all the include files for no need */
+struct termios;
+struct winsize;
+struct utmp;
+
+void login (struct utmp *ut);
+int login_tty (int fd);
+int logout (char *line);
+void logwtmp (const char *line, const char *name, const char *host);
+int openpty (int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp);
+int forkpty (int *amaster, char *name, struct termios *termp, struct winsize *winp);
+#endif
+#else
+int openpty (int *master_fd, int *slavefd, char *name, struct termios *termp, struct winsize *winp);
+pid_t forkpty (int *master_fd, char *name, struct termios *termp, struct winsize *winp);
+#endif
+
+#ifndef HAVE_LOGIN_TTY
+int login_tty (int fd);
+#elif defined(HAVE_UTMP_H)
+/* Get the prototype from utmp.h */
+#include <utmp.h>
+#endif
+
+int n_read (int fd, void *buffer, int size);
+
+#endif /* _GNOME_LOGIN_SUPPORT_H */
--- /dev/null
+/*
+ * gnome-pty.c: Helper setuid application used to open a pseudo-
+ * terminal, set the permissions, ownership and record user login
+ * information
+ *
+ * Author:
+ * Miguel de Icaza (miguel@gnu.org)
+ *
+ * Parent application talks to us via a couple of sockets that are strategically
+ * placed on file descriptors 0 and 1 (STDIN_FILENO and STDOUT_FILENO).
+ *
+ * We use the STDIN_FILENO to read and write the protocol information and we use
+ * the STDOUT_FILENO to pass the file descriptors (we need two different file
+ * descriptors as using a socket for both data transfers and file descriptor
+ * passing crashes some BSD kernels according to Theo de Raadt)
+ *
+ * A simple protocol is used:
+ *
+ * OPEN_PTY => 1 <tag> <master-pty-fd> <slave-pty-fd>
+ * => 0
+ *
+ * CLOSE_PTY <tag> => void
+ *
+ * <tag> is a pointer. If tag is NULL, then the ptys were not allocated.
+ * ptys are passed using file descriptor passing on the stdin file descriptor
+ *
+ * We use as little as possible external libraries.
+ */
+#include <config.h>
+
+/* Use this to pull SCM_RIGHTS definition on IRIX */
+#if defined(irix) || defined (__irix__) || defined(sgi) || defined (__sgi__)
+# define _XOPEN_SOURCE 1
+extern char *strdup(const char *);
+#endif
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <errno.h>
+#include <malloc.h>
+#include <termios.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <utmp.h>
+#include <grp.h>
+#include "gnome-pty.h"
+#include "gnome-login-support.h"
+
+
+/* GNU autoconf alloca incantation */
+/* AIX requires this to be the first thing in the file. */
+#ifdef __GNUC__
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+/* For PATH_MAX on BSD-like systems. */
+#ifdef HAVE_SYS_SYSLIMITS_H
+#include <sys/syslimits.h>
+#endif
+
+static struct passwd *pwent;
+static char login_name_buffer [48];
+static char *login_name, *display_name;
+
+struct pty_info {
+ struct pty_info *next;
+ int master_fd, slave_fd;
+ char *line;
+ void *data;
+ char utmp, wtmp;
+};
+
+typedef struct pty_info pty_info;
+
+static pty_info *pty_list;
+
+#ifdef HAVE_SENDMSG
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#ifdef HAVE_SYS_UN_H /* Linux libc5 */
+#include <sys/un.h>
+#endif
+
+#ifndef CMSG_DATA /* Linux libc5 */
+/* Ancillary data object manipulation macros. */
+#if !defined __STRICT_ANSI__ && defined __GNUC__ && __GNUC__ >= 2
+# define CMSG_DATA(cmsg) ((cmsg)->cmsg_data)
+#else
+# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
+#endif
+#endif /* CMSG_DATA */
+
+#define CONTROLLEN (sizeof (struct cmsghdr) + sizeof (int))
+
+static struct cmsghdr *cmptr;
+
+static int
+init_msg_pass ()
+{
+ cmptr = malloc (CONTROLLEN);
+
+ if (cmptr)
+ return 0;
+
+ return -1;
+}
+
+static int
+pass_fd (int client_fd, int fd)
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+ char buf [1];
+
+ iov [0].iov_base = buf;
+ iov [0].iov_len = 1;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = (caddr_t) cmptr;
+ msg.msg_controllen = CONTROLLEN;
+
+ cmptr->cmsg_level = SOL_SOCKET;
+ cmptr->cmsg_type = SCM_RIGHTS;
+ cmptr->cmsg_len = CONTROLLEN;
+ *(int *)CMSG_DATA (cmptr) = fd;
+
+ if (sendmsg (client_fd, &msg, 0) != 1)
+ return -1;
+
+ return 0;
+}
+
+#elif defined(__sgi) && !defined(HAVE_SENDMSG)
+
+/*
+ * IRIX 6.2 is like 4.3BSD; it will not have HAVE_SENDMSG set,
+ * because msghdr used msg_accrights and msg_accrightslen rather
+ * than the newer msg_control and msg_controllen fields configure
+ * checks. The SVR4 code below doesn't work because pipe()
+ * semantics are controlled by the svr3pipe systune variable,
+ * which defaults to uni-directional pipes. Also sending
+ * file descriptors through pipes isn't implemented.
+ */
+
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+static int
+init_msg_pass ()
+{
+ return 0;
+}
+
+static int
+pass_fd (int client_fd, int fd)
+{
+ struct iovec iov[1];
+ struct msghdr msg;
+ char buf [1];
+
+ iov [0].iov_base = buf;
+ iov [0].iov_len = 1;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_accrights = (caddr_t) &fd;
+ msg.msg_accrightslen = sizeof(fd);
+
+ if (sendmsg (client_fd, &msg, 0) != 1)
+ return -1;
+
+ return 0;
+}
+
+#else
+#include <stropts.h>
+static int
+init_msg_pass ()
+{
+ /* nothing */
+ return 0;
+}
+
+int
+pass_fd (int client_fd, int fd)
+{
+ if (ioctl (client_fd, I_SENDFD, fd) < 0)
+ return -1;
+ return 0;
+}
+#endif
+
+static void
+pty_free (pty_info *pi)
+{
+ free (pi);
+}
+
+static void
+pty_remove (pty_info *pi)
+{
+ pty_info *l, *last;
+
+ last = (void *) 0;
+
+ for (l = pty_list; l; l = l->next){
+ if (l == pi){
+ if (last == (void *) 0)
+ pty_list = pi->next;
+ else
+ last->next = pi->next;
+ free (pi->line);
+ pty_free (pi);
+ return;
+ }
+ last = l;
+ }
+
+ exit (1);
+}
+
+static void
+shutdown_pty (pty_info *pi)
+{
+ if (pi->utmp || pi->wtmp)
+ if (pi->data)
+ write_logout_record (pi->data, pi->utmp, pi->wtmp);
+
+ close (pi->master_fd);
+ close (pi->slave_fd);
+
+ pty_remove (pi);
+}
+
+static void
+shutdown_helper (void)
+{
+ pty_info *pi;
+
+ for (pi = pty_list; pi; pi = pty_list)
+ shutdown_pty (pi);
+}
+
+static pty_info *
+pty_add (int utmp, int wtmp, int master_fd, int slave_fd, char *line)
+{
+ pty_info *pi = malloc (sizeof (pty_info));
+
+ if (pi == NULL){
+ shutdown_helper ();
+ exit (1);
+ }
+
+ memset (pi, 0, sizeof (pty_info));
+
+ if (strncmp (line, "/dev/", 5))
+ pi->line = strdup (line);
+ else
+ pi->line = strdup (line+5);
+
+ if (pi->line == NULL){
+ shutdown_helper ();
+ exit (1);
+ }
+
+ pi->master_fd = master_fd;
+ pi->slave_fd = slave_fd;
+ pi->next = pty_list;
+ pi->utmp = utmp;
+ pi->wtmp = wtmp;
+
+ pty_list = pi;
+
+ return pi;
+}
+
+static int
+path_max (void)
+{
+#ifdef _PC_PATH_MAX
+ return pathconf ("/", _PC_PATH_MAX);
+#else
+# ifdef PATH_MAX
+ return PATH_MAX;
+# else
+ return 1024;
+# endif
+#endif
+}
+
+static struct termios*
+init_term_with_defaults(struct termios* term)
+{
+ /*
+ * openpty assumes POSIX termios so this should be portable.
+ * Don't change this to a structure init - POSIX doesn't say
+ * anything about field order.
+ */
+ memset(term, 0, sizeof(struct termios));
+
+ term->c_iflag = 0
+#ifdef BRKINT
+ | BRKINT
+#endif
+#ifdef ICRNL
+ | ICRNL
+#endif
+#ifdef IMAXBEL
+ | IMAXBEL
+#endif
+#ifdef IXON
+ | IXON
+#endif
+#ifdef IXANY
+ | IXANY
+#endif
+ ;
+ term->c_oflag = 0
+#ifdef OPOST
+ | OPOST
+#endif
+#ifdef ONLCR
+ | ONLCR
+#endif
+#ifdef NL0
+ | NL0
+#endif
+#ifdef CR0
+ | CR0
+#endif
+#ifdef TAB0
+ | TAB0
+#endif
+#ifdef BS0
+ | BS0
+#endif
+#ifdef VT0
+ | VT0
+#endif
+#ifdef FF0
+ | FF0
+#endif
+ ;
+ term->c_cflag = 0
+#ifdef CREAD
+ | CREAD
+#endif
+#ifdef CS8
+ | CS8
+#endif
+#ifdef HUPCL
+ | HUPCL
+#endif
+ ;
+#ifdef EXTB
+ cfsetispeed(term, EXTB);
+ cfsetospeed(term, EXTB);
+#else
+# ifdef B38400
+ cfsetispeed(term, B38400);
+ cfsetospeed(term, B38400);
+# else
+# ifdef B9600
+ cfsetispeed(term, B9600);
+ cfsetospeed(term, B9600);
+# endif
+# endif
+#endif /* EXTB */
+
+ term->c_lflag = 0
+#ifdef ECHO
+ | ECHO
+#endif
+#ifdef ICANON
+ | ICANON
+#endif
+#ifdef ISIG
+ | ISIG
+#endif
+#ifdef IEXTEN
+ | IEXTEN
+#endif
+#ifdef ECHOE
+ | ECHOE
+#endif
+#ifdef ECHOKE
+ | ECHOKE
+#endif
+#ifdef ECHOCTL
+ | ECHOCTL
+#endif
+ ;
+
+#ifdef N_TTY
+ /* should really be a check for c_line, but maybe this is good enough */
+ term->c_line = N_TTY;
+#endif
+
+ /* These two may overlap so set them first */
+ /* That setup means, that read() will be blocked untill */
+ /* at least 1 symbol will be read. */
+ term->c_cc[VMIN] = 1;
+ term->c_cc[VTIME] = 0;
+
+ /*
+ * Now set the characters. This is of course a religious matter
+ * but we use the defaults, with erase bound to the key gnome-terminal
+ * maps.
+ *
+ * These are the ones set by "stty sane".
+ */
+
+ term->c_cc[VINTR] = 'C'-64;
+ term->c_cc[VQUIT] = '\\'-64;
+ term->c_cc[VERASE] = 127;
+ term->c_cc[VKILL] = 'U'-64;
+ term->c_cc[VEOF] = 'D'-64;
+#ifdef VSWTC
+ term->c_cc[VSWTC] = 255;
+#endif
+ term->c_cc[VSTART] = 'Q'-64;
+ term->c_cc[VSTOP] = 'S'-64;
+ term->c_cc[VSUSP] = 'Z'-64;
+ term->c_cc[VEOL] = 255;
+
+ /*
+ * Extended stuff.
+ */
+
+#ifdef VREPRINT
+ term->c_cc[VREPRINT] = 'R'-64;
+#endif
+#ifdef VSTATUS
+ term->c_cc[VSTATUS] = 'T'-64;
+#endif
+#ifdef VDISCARD
+ term->c_cc[VDISCARD] = 'O'-64;
+#endif
+#ifdef VWERASE
+ term->c_cc[VWERASE] = 'W'-64;
+#endif
+#ifdef VLNEXT
+ term->c_cc[VLNEXT] = 'V'-64;
+#endif
+#ifdef VDSUSP
+ term->c_cc[VDSUSP] = 'Y'-64;
+#endif
+#ifdef VEOL2
+ term->c_cc[VEOL2] = 255;
+#endif
+ return(term);
+}
+
+static int
+open_ptys (int utmp, int wtmp, int lastlog)
+{
+ char *term_name;
+ int status, master_pty, slave_pty;
+ pty_info *p;
+ int result;
+ uid_t savedUid;
+ gid_t savedGid;
+ struct group *group_info;
+ struct termios term;
+
+ term_name = ((char *) alloca (path_max())) + 1;
+
+ if (term_name == NULL){
+ exit (1);
+ }
+ /* Initialize term */
+ init_term_with_defaults(&term);
+
+ /* root privileges */
+ savedUid = geteuid();
+ savedGid = getegid();
+
+ /* drop privileges to the user level */
+#if defined(HAVE_SETEUID)
+ seteuid (pwent->pw_uid);
+ setegid (pwent->pw_gid);
+#elif defined(HAVE_SETREUID)
+ setreuid (savedUid, pwent->pw_uid);
+ setregid (savedGid, pwent->pw_gid);
+#else
+#error "No means to drop privileges! Huge security risk! Won't compile."
+#endif
+ /* Open pty with privileges of the user */
+ status = openpty (&master_pty, &slave_pty, term_name, &term, NULL);
+
+ /* Restore saved privileges to root */
+#ifdef HAVE_SETEUID
+ seteuid (savedUid);
+ setegid (savedGid);
+#elif defined(HAVE_SETREUID)
+ setreuid (pwent->pw_uid, savedUid);
+ setregid (pwent->pw_gid, savedGid);
+#else
+#error "No means to raise privileges! Huge security risk! Won't compile."
+#endif
+ /* openpty() failed, reject request */
+ if (status == -1){
+ result = 0;
+ write (STDIN_FILENO, &result, sizeof (result));
+ return 0;
+ }
+
+ /* a bit tricky, we re-do the part of the openpty() */
+ /* that required root privileges, and, hence, failed */
+ group_info = getgrnam ("tty");
+ fchown (slave_pty, getuid (), group_info ? group_info->gr_gid : -1);
+ fchmod (slave_pty, S_IRUSR | S_IWUSR | S_IWGRP);
+ /* It's too late to call revoke at this time... */
+ /* revoke(term_name); */
+
+ /* add pty to the list of allocated by us */
+ p = pty_add (utmp, wtmp, master_pty, slave_pty, term_name);
+ result = 1;
+
+ if (write (STDIN_FILENO, &result, sizeof (result)) == -1 ||
+ write (STDIN_FILENO, &p, sizeof (p)) == -1 ||
+ pass_fd (STDOUT_FILENO, master_pty) == -1 ||
+ pass_fd (STDOUT_FILENO, slave_pty) == -1){
+ exit (0);
+ }
+
+ if (utmp || wtmp || lastlog){
+ p->data = write_login_record (login_name, display_name, term_name, utmp, wtmp, lastlog);
+ }
+
+ return 1;
+}
+
+static void
+close_pty_pair (void *tag)
+{
+ pty_info *pi;
+
+ for (pi = pty_list; pi; pi = pi->next){
+ if (tag == pi){
+ shutdown_pty (pi);
+ break;
+ }
+ }
+}
+
+#define MB (1024*1024)
+
+struct {
+ int limit;
+ int value;
+} sensible_limits [] = {
+ { RLIMIT_CPU, 120 },
+ { RLIMIT_FSIZE, 1 * MB },
+ { RLIMIT_DATA, 1 * MB },
+ { RLIMIT_STACK, 1 * MB },
+#ifdef RLIMIT_AS
+ { RLIMIT_AS, 1 * MB },
+#endif
+ { RLIMIT_NOFILE, 10 },
+#ifdef RLIMIT_NPROC
+ { RLIMIT_NPROC, 5 },
+#endif
+ { -1, -1 }
+};
+
+static void
+sanity_checks (void)
+{
+ int stderr_fd;
+ int i, open_max;
+ int flag;
+
+ /*
+ * Make sure stdin/stdout are open. This is a requirement
+ * for our program to work and closes potential security holes.
+ */
+ if ((fcntl (0, F_GETFL, &flag) == -1 && errno == EBADF) ||
+ (fcntl (1, F_GETFL, &flag) == -1 && errno == EBADF)){
+ exit (1);
+ }
+
+ /*
+ * File descriptors 0 and 1 have been setup by the parent process
+ * to be used for the protocol exchange and for transfering
+ * file descriptors.
+ *
+ * Make stderr point to a terminal.
+ */
+ if (fcntl (2, F_GETFL, &flag) == -1 && errno == EBADF){
+ stderr_fd = open ("/dev/tty", O_RDWR);
+ if (stderr_fd == -1){
+ stderr_fd = open ("/dev/null", O_RDWR);
+ if (stderr_fd == -1)
+ exit (1);
+ }
+
+ if (stderr_fd != 2)
+ while (dup2 (stderr_fd, 2) == -1 && errno == EINTR)
+ ;
+ }
+
+ /* Close any file descriptor we do not use */
+ open_max = sysconf (_SC_OPEN_MAX);
+ for (i = 3; i < open_max; i++){
+ close (i);
+ }
+
+ /* Check sensible resource limits */
+ for (i = 0; sensible_limits [i].value != -1; i++){
+ struct rlimit rlim;
+
+ if (getrlimit (sensible_limits [i].limit, &rlim) != 0)
+ continue;
+
+ if (rlim.rlim_cur != RLIM_INFINITY &&
+ rlim.rlim_cur < sensible_limits [i].value){
+ fprintf (stderr, "Living environment not ok\n");
+ exit (1);
+ }
+ }
+
+ /* Make sure SIGIO/SIGINT is SIG_IGN */
+ {
+ struct sigaction sa;
+ sigset_t sigset;
+
+ sa.sa_handler = SIG_IGN;
+ sigemptyset (&sa.sa_mask);
+ sa.sa_flags = 0;
+
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGIO);
+ sigaddset(&sigset, SIGINT);
+ sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+
+ sigaction (SIGIO, &sa, NULL);
+ sigaction (SIGINT, &sa, NULL);
+ }
+}
+
+int
+main (int argc, char *argv [])
+{
+ int res, n;
+ void *tag;
+ GnomePtyOps op;
+
+ sanity_checks ();
+
+ pwent = getpwuid (getuid ());
+ if (pwent)
+ login_name = pwent->pw_name;
+ else {
+ sprintf (login_name_buffer, "#%u", (unsigned int)getuid ());
+ login_name = login_name_buffer;
+ }
+
+ display_name = getenv ("DISPLAY");
+ if (!display_name)
+ display_name = "localhost";
+
+
+ if (init_msg_pass () == -1)
+ exit (1);
+
+ for (;;){
+ res = n_read (STDIN_FILENO, &op, sizeof (op));
+
+ if (res != sizeof (op) || res == -1){
+ shutdown_helper ();
+ return 1;
+ }
+
+ if (res == 0) {
+ shutdown_helper ();
+ return 1;
+ }
+
+ switch (op){
+ case GNOME_PTY_OPEN_PTY_UTMP:
+ open_ptys (1, 0, 0);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_UWTMP:
+ open_ptys (1, 1, 0);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_WTMP:
+ open_ptys (0, 1, 0);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_LASTLOG:
+ open_ptys (0, 0, 1);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_LASTLOGUTMP:
+ open_ptys (1, 0, 1);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_LASTLOGUWTMP:
+ open_ptys (1, 1, 1);
+ break;
+
+ case GNOME_PTY_OPEN_PTY_LASTLOGWTMP:
+ open_ptys (0, 1, 1);
+ break;
+
+ case GNOME_PTY_OPEN_NO_DB_UPDATE:
+ open_ptys (0, 0, 0);
+ break;
+
+ case GNOME_PTY_RESET_TO_DEFAULTS:
+ break;
+
+ case GNOME_PTY_CLOSE_PTY:
+ n = n_read (STDIN_FILENO, &tag, sizeof (tag));
+ if (n == -1 || n != sizeof (tag)){
+ shutdown_helper ();
+ return 1;
+ }
+ close_pty_pair (tag);
+ break;
+ }
+
+ }
+
+ return 0;
+}
+
--- /dev/null
+#ifndef GNOME_PTY_H
+#define GNOME_PTY_H
+
+typedef enum {
+ GNOME_PTY_OPEN_PTY_UTMP = 1,
+ GNOME_PTY_OPEN_PTY_UWTMP,
+ GNOME_PTY_OPEN_PTY_WTMP,
+ GNOME_PTY_OPEN_PTY_LASTLOG,
+ GNOME_PTY_OPEN_PTY_LASTLOGUTMP,
+ GNOME_PTY_OPEN_PTY_LASTLOGUWTMP,
+ GNOME_PTY_OPEN_PTY_LASTLOGWTMP,
+ GNOME_PTY_OPEN_NO_DB_UPDATE,
+ GNOME_PTY_RESET_TO_DEFAULTS,
+ GNOME_PTY_CLOSE_PTY
+} GnomePtyOps;
+
+void *update_dbs (int utmp, int wtmp, int lastlog, char *login_name, char *display_name, char *term_name);
+void *write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp, int lastlog);
+void write_logout_record (void *data, int utmp, int wtmp);
+
+#endif
--- /dev/null
+/*
+ * utmp/wtmp file updating
+ *
+ * Authors:
+ * Miguel de Icaza (miguel@gnu.org).
+ * Timur I. Bakeyev (timur@gnu.org).
+ *
+ * FIXME: Do we want to register the PID of the process running *under* the subshell
+ * or the PID of the parent process? (we are doing the latter now).
+ *
+ * FIXME: Solaris (utmpx) stuff need to be checked.
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <errno.h>
+
+#if defined(TIME_WITH_SYS_TIME)
+# include <sys/time.h>
+#include <time.h>
+#else
+# if defined(HAVE_SYS_TIME_H)
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include <utmp.h>
+
+#if defined(HAVE_LASTLOG_H)
+# include <lastlog.h>
+#endif
+
+#if defined(HAVE_PATHS_H)
+# include <paths.h>
+#endif
+
+#if defined(HAVE_UTMPX_H)
+# include <utmpx.h>
+#endif
+
+#if defined(HAVE_TTYENT_H)
+# include <ttyent.h>
+#endif
+
+#include "gnome-pty.h"
+#include "gnome-login-support.h"
+
+
+
+#if !defined(UTMP_OUTPUT_FILENAME)
+# if defined(UTMP_FILE)
+# define UTMP_OUTPUT_FILENAME UTMP_FILE
+# elif defined(_PATH_UTMP) /* BSD systems */
+# define UTMP_OUTPUT_FILENAME _PATH_UTMP
+# else
+# define UTMP_OUTPUT_FILENAME "/etc/utmp"
+# endif
+#endif
+
+#if !defined(WTMP_OUTPUT_FILENAME)
+# if defined(WTMPX_FILE)
+# define WTMP_OUTPUT_FILENAME WTMPX_FILE
+# elif defined(_PATH_WTMPX)
+# define WTMP_OUTPUT_FILENAME _PATH_WTMPX
+# elif defined(WTMPX_FILENAME)
+# define WTMP_OUTPUT_FILENAME WTMPX_FILENAME
+# elif defined(WTMP_FILE)
+# define WTMP_OUTPUT_FILENAME WTMP_FILE
+# elif defined(_PATH_WTMP) /* BSD systems */
+# define WTMP_OUTPUT_FILENAME _PATH_WTMP
+# else
+# define WTMP_OUTPUT_FILENAME "/etc/wtmp"
+# endif
+#endif
+
+#if defined(_PATH_LASTLOG) /* BSD systems */
+# define LASTLOG_OUTPUT_FILE _PATH_LASTLOG
+#else
+# define LASTLOG_OUTPUT_FILE "/var/log/lastlog"
+#endif
+
+#if defined(HAVE_UPDWTMPX)
+#define update_wtmp updwtmpx
+#elif defined(HAVE_UPDWTMP)
+#define update_wtmp updwtmp
+#else /* !HAVE_UPDWTMPX && !HAVE_UPDWTMP */
+static void
+update_wtmp (char *file, UTMP *putmp)
+{
+ int fd, times = 3;
+#if defined(HAVE_FCNTL)
+ struct flock lck;
+
+ lck.l_whence = SEEK_END;
+ lck.l_len = 0;
+ lck.l_start = 0;
+ lck.l_type = F_WRLCK;
+#endif
+
+ if ((fd = open (file, O_WRONLY|O_APPEND, 0)) < 0)
+ return;
+
+#if defined(HAVE_FCNTL) || defined(HAVE_FLOCK)
+ while (times--)
+# if defined(HAVE_FCNTL)
+ if ((fcntl (fd, F_SETLK, &lck) < 0)){
+ if (errno != EAGAIN && errno != EACCES){
+# elif defined(HAVE_FLOCK)
+ if (flock(fd, LOCK_EX | LOCK_NB) < 0){
+ if (errno != EWOULDBLOCK){
+# endif
+ close (fd);
+ return;
+ }
+ sleep (1); /*?!*/
+ } else
+ break;
+#endif /* HAVE_FCNTL || HAVE_FLOCK */
+
+ lseek (fd, 0, SEEK_END);
+ write (fd, putmp, sizeof(UTMP));
+
+ /* unlock the file */
+#if defined(HAVE_FCNTL)
+ lck.l_type = F_UNLCK;
+ fcntl (fd, F_SETLK, &lck);
+#elif defined(HAVE_FLOCK)
+ flock (fd, LOCK_UN);
+#endif
+ close (fd);
+}
+#endif /* !HAVE_GETUTMPX */
+
+
+#if defined(HAVE_GETUTMPX)
+static void
+update_utmp (UTMP *ut)
+{
+ setutxent();
+ pututxline (ut);
+}
+#elif defined(HAVE_GETUTENT)
+static void
+update_utmp (UTMP *ut)
+{
+ setutent();
+ pututline (ut);
+}
+#elif defined(HAVE_GETTTYENT)
+/* This variant is sutable for most BSD */
+static void
+update_utmp (UTMP *ut)
+{
+ struct ttyent *ty;
+ int fd, pos = 0;
+
+ if ((fd = open (UTMP_OUTPUT_FILENAME, O_RDWR|O_CREAT, 0644)) < 0)
+ return;
+
+ setttyent ();
+ while ((ty = getttyent ()) != NULL)
+ {
+ ++pos;
+ if (strncmp (ty->ty_name, ut->ut_line, sizeof (ut->ut_line)) == 0)
+ {
+ lseek (fd, (off_t)(pos * sizeof(UTMP)), SEEK_SET);
+ write(fd, ut, sizeof(UTMP));
+ }
+ }
+ endttyent ();
+
+ close(fd);
+}
+#else
+#define update_utmp(ut)
+#endif
+
+#if !defined(HAVE_LASTLOG)
+#define update_lastlog(login_name, ut)
+#else
+static void
+update_lastlog(char* login_name, UTMP *ut)
+{
+ struct passwd *pwd;
+ struct lastlog ll;
+ int fd;
+
+ if ((fd = open(LASTLOG_OUTPUT_FILE, O_WRONLY, 0)) < 0)
+ return;
+
+ if ((pwd=getpwnam(login_name)) == NULL)
+ return;
+
+ memset (&ll, 0, sizeof(ll));
+
+ lseek (fd, (off_t)pwd->pw_uid * sizeof (ll), SEEK_SET);
+
+ time (&ll.ll_time);
+
+ strncpy (ll.ll_line, ut->ut_line, sizeof (ll.ll_line));
+
+#if defined(HAVE_UT_UT_HOST)
+ if (ut->ut_host)
+ strncpy (ll.ll_host, ut->ut_host, sizeof (ll.ll_host));
+#endif
+
+ write (fd, (void *)&ll, sizeof (ll));
+ close (fd);
+}
+#endif /* HAVE_LASTLOG */
+
+void
+write_logout_record (void *data, int utmp, int wtmp)
+{
+ UTMP put, *ut = data;
+
+ memset (&put, 0, sizeof(UTMP));
+
+#if defined(HAVE_UT_UT_TYPE)
+ put.ut_type = DEAD_PROCESS;
+#endif
+#if defined(HAVE_UT_UT_ID)
+ strncpy (put.ut_id, ut->ut_id, sizeof (put.ut_id));
+#endif
+
+ strncpy (put.ut_line, ut->ut_line, sizeof (put.ut_line));
+
+#if defined(HAVE_UT_UT_TV)
+ gettimeofday ((struct timeval*) &put.ut_tv, NULL);
+#elif defined(HAVE_UT_UT_TIME)
+ time (&put.ut_time);
+#endif
+
+ if (utmp)
+ update_utmp (&put);
+
+ if (wtmp)
+ update_wtmp (WTMP_OUTPUT_FILENAME, &put);
+
+ free (ut);
+}
+
+void *
+write_login_record (char *login_name, char *display_name, char *term_name, int utmp, int wtmp, int lastlog)
+{
+ UTMP *ut;
+ char *pty = term_name;
+
+ if((ut=(UTMP *) malloc (sizeof (UTMP))) == NULL)
+ return NULL;
+
+ memset (ut, 0, sizeof (UTMP));
+
+#if defined(HAVE_UT_UT_NAME)
+ strncpy (ut->ut_name, login_name, sizeof (ut->ut_name));
+#elif defined(HAVE_UT_UT_USER)
+ strncpy (ut->ut_user, login_name, sizeof (ut->ut_user));
+#endif
+
+ /* This shouldn't happen */
+ if (strncmp (pty, "/dev/", 5) == 0)
+ pty += 5;
+
+#if defined(HAVE_STRRCHR)
+ {
+ char *p;
+
+ if (strncmp (pty, "pts", 3) &&
+ (p = strrchr (pty, '/')) != NULL)
+ pty = p + 1;
+ }
+#endif
+
+#if defined(HAVE_UT_UT_ID)
+ /* Just a safe-guard */
+ ut->ut_id [0] = '\0';
+
+ /* BSD-like terminal name */
+ if (strncmp (pty, "pts", 3) == 0 ||
+ strncmp (pty, "pty", 3) == 0 ||
+ strncmp (pty, "tty", 3) == 0) {
+ strncpy (ut->ut_id, pty+3, sizeof (ut->ut_id));
+ }
+ else {
+ unsigned int num;
+ char buf[10];
+ /* Try to get device number and convert it to gnome-terminal # */
+ if (sscanf (pty, "%*[^0-9a-f]%x", &num) == 1) {
+ sprintf (buf, "gt%02.2x", num);
+ strncpy (ut->ut_id, buf, sizeof (ut->ut_id));
+ }
+ }
+#endif
+
+ /* For utmpx ut_line should be null terminated */
+ /* We do that for both cases to be sure */
+ strncpy (ut->ut_line, pty, sizeof (ut->ut_line));
+ ut->ut_line[sizeof (ut->ut_line)-1] = '\0';
+
+ /* We want parent's pid, not our own */
+#if defined(HAVE_UT_UT_PID)
+ ut->ut_pid = getppid ();
+#endif
+
+#if defined(HAVE_UT_UT_TYPE)
+ ut->ut_type = USER_PROCESS;
+#endif
+ /* If structure has ut_tv it doesn't need ut_time */
+#if defined(HAVE_UT_UT_TV)
+ gettimeofday ((struct timeval*) &(ut->ut_tv), NULL);
+#elif defined(HAVE_UT_UT_TIME)
+ time (&ut->ut_time);
+#endif
+ /* ut_ host supposed to be null terminated or len should */
+ /* be specifid in additional field. We do both :) */
+#if defined(HAVE_UT_UT_HOST)
+ strncpy (ut->ut_host, display_name, sizeof (ut->ut_host));
+ ut->ut_host [sizeof (ut->ut_host)-1] = '\0';
+# if defined(HAVE_UT_UT_SYSLEN)
+ ut->ut_syslen = strlen (ut->ut_host);
+# endif
+#endif
+ if (utmp)
+ update_utmp (ut);
+
+ if (wtmp)
+ update_wtmp (WTMP_OUTPUT_FILENAME, ut);
+
+ if (lastlog)
+ update_lastlog(login_name, ut);
+
+ return ut;
+}
+
+void *
+update_dbs (int utmp, int wtmp, int lastlog, char *login_name, char *display_name, char *term_name)
+{
+ return write_login_record (login_name, display_name, term_name, utmp, wtmp, lastlog);
+}
msgid ""
msgstr ""
"Project-Id-Version: vte\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-13 22:12+0200\n"
"Last-Translator: Ole Laursen <olau@hardworking.dk>\n"
"Language-Team: Danish <dansk@klid.dk>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Fejl ved tilføjelse af '%s' til miljøet, fortsætter."
msgid "Duplicate (%s/%s)!"
msgstr "Optræder mere end én gang (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Fejl ved oversættelse af regulært udtryk \"%s\"."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Kunne ikke konvertere tegn fra %s til %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Modtog uventet (taste-?) sekvens '%s'."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Tegn 0x%x er ikke defineret, allokerer en kolonne."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Ingen håndtering for kontrolsekvensen '%s' er defineret."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Fejl ved læsning fra underproces: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Fejl (%s) ved konvertering af data for underproces, dropper."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr "Bruger skrifttypesættet \"%s\" som mangler disse tegnsæt: %s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr ""
"Kunne ikke indlæse Xft-skrifttypemønstret \"%s\", falder tilbage til "
"standardskrifttypen."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Kunne ikke indlæse standard-Xft-skrifttypen."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr ""
"Kunne ikke indlæse skrifttypesættet \"%s\", falder tilbage til "
"standardskrifttypen."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Kunne ikke indlæse standardskrifttypen; vil nu gå ned eller udvise anormal "
"adfærd."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Fejl ved indlæsning af PTY-størrelse, bruger standardværdier: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Fejl ved angivelse af PTY-størrelse: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Fejl ved allokering af tegning, deaktiverer Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Fejl ved allokering af kontekst, deaktiverer Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Fejl ved allokering af layout, deaktiverer Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() kunne ikke angive ordtegn"
msgid ""
msgstr ""
"Project-Id-Version: vte HEAD\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-07 18:12+0100\n"
"Last-Translator: Christian Neumair <christian-neumair@web.de>\n"
"Language-Team: German <gnome-de@gnome.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Fehler beim Hinzufügen von »%s« zur Umgebung, fortfahren."
msgid "Duplicate (%s/%s)!"
msgstr "Duplikat (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Fehler beim Kompilieren des regulären Ausdrucks »%s«."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Zeichen konnten nicht von %s nach %s konvertiert werden."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Unerwartete (Schlüssel?)-Sequenz »%s« erhalten."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Zeichen 0x%x ist undefiniert, eine Spalte wird zugewiesen."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Kein Handler für Kontrollsequenz »%s« definiert."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Fehler beim Lesen von Kind: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Fehler (%s) beim Konvertieren der Daten für Kind, wird abgebrochen."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr ""
"Schriftsatz »%s« wird verwendet, welchem folgende Zeichensätze fehlen: %s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr ""
"Laden des Xft-Schriftmusters »%s« fehlgeschlagen, Rückfall zur vorgegebenen "
"Schrift."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Laden der vorgegebenen Xft-Schrift fehlgeschlagen"
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr ""
"Laden des Schriftsatzes »%s« fehlgeschlagen, Rückfall zur vorgegebenen "
"Schrift."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Laden der vorgebenen Schrift fehlgeschlagen, Absturz oder abnormales "
"Verhalten."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Fehler beim Lesen der PTY-Größe, Vorgaben werden verwendet: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Fehler beim Festlegen der PTY-Größe: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Fehler beim Zuweisen der Zeichnung, Xft wird deaktiviert."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Fehler beim Zuweisen des Kontextes, Pango wird deaktiviert."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Fehler beim Zuweisen des Layouts, Pango wird deaktiviert."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() konnte die Zeichen des Wortes nicht festlegen"
msgid ""
msgstr ""
"Project-Id-Version: vte 0.7.0\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-02 12:01+0200\n"
"Last-Translator: Laurent RICHARD <kouran@iespana.es>\n"
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Erreur lors de l'ajout de « %s » à l'environnement, ignore."
msgid "Duplicate (%s/%s)!"
msgstr "Dupliquer (%s/%s) ! "
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Erreur lors de la compilation de l'expression régulière « %s »."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Impossible de convertir les caractères %s en %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Séquence (clé ?) imprévue « %s »."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Caractère 0x%x non défini, attribution d'une colonne."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Pas de manipulation définie pour la séquence de contrôle « %s »."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Erreur lors de la lecture du fils : « %s »."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Erreur (%s) lors de la conversion de données pour le fils, abandon."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, fuzzy, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr ""
"Avertissement : utilisation de la police de caractère « %s » dans lequel ces "
"caractères sont manquants : %s. "
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr ""
"Échec du chargement du modèle de police Xft « %s », utilisation de la police "
"par défaut."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Échec du chargement la police Xft par défaut."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr ""
"Échec du chargement du jeu de police « %s », utilisation de la police par "
"défaut."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Échec du chargement de la police par défaut, crash ou comportement anormal."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr ""
"Erreur lors de la lecture de la taille PTY, utilisation par défaut : %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Erreur lors du paramètrage de la taille PTY : « %s »."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Erreur lors de l'attribution du dessin, désactivation de Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Erreur lors de l'attribution du contexte, désactivation de Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr ""
"Erreur lors de l'attribution de la disposition, désactivation de Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() a échoué dans le paramètrage des caractères."
msgid ""
msgstr ""
"Project-Id-Version: vte\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-08 20:09+0200\n"
"Last-Translator: Taco Witte <T.C.Witte@phys.uu.nl>\n"
"Language-Team: Dutch <vertaling@nl.linux.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Fout bij toevoegen `%s' aan omgeving. Doorgaan.."
msgid "Duplicate (%s/%s)!"
msgstr "Dupliceren (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Fout bij samenstellen reguliere uitdrukking \"%s\"."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Kan tekens niet converteren van %s naar %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, fuzzy, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Ontvangen: onverwachte (toetsenbord?) combinatie `%s'."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Teken 0x%x is ongedefinieerd, wijs één kolom toe."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, fuzzy, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Geen afhandelaar voor controle combinatie `%s' gedefinieerd."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Fout bij lezen van kind: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Fout (%s) bij converteren gegevens voor kind, laat het vallen."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr ""
"Lettertype verzameling \"%s\" wordt gebruikt, maar die mist deze tekensets: %"
"s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr ""
"Laden Xft lettertype patroon \"%s\" mislukt, val terug op standaard "
"lettertype."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Laden standaard Xft lettertype mislukt."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr ""
"Fout bij laden lettertype verzameling \"%s\", val terug op standaard "
"lettertype."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Fout bij laden standaard lettertype, loop vast of gedraag mezelf abnormaal."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Fout bij lezen PTY grootte, gebruik standaardwaarden: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Fout bij instellen PTY grootte: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Fout bij toewijzen tekenen, zet Xft uit."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Fout bij toewijzen context, zet Pango uit."
-#: src/vte.c:12161
+#: src/vte.c:12218
#, fuzzy
msgid "Error allocating layout, disabling Pango."
msgstr "Fout bij toewijzen layout, zet Pango uit."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() niet geslaagd in instellen woordtekens"
msgid ""
msgstr ""
"Project-Id-Version: vte 0.5\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-25 01:11+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian <no@li.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Feil under tillegg av «%s» i miljøet. Fortsetter."
msgid "Duplicate (%s/%s)!"
msgstr "Duplikat (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Feil under sammensetting av regulært uttrykk «%s»."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Kan ikke konvertere tegn fra %s til %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Mottok uventet (nøkkel?) sekvens «%s»."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Tegnet 0x%x er udefinert. Allokerer én kolonne."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Ingen håndterer definert for kontrollsekvens «%s»."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Feil under lesing fra underprosess: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Feil (%s) ved konvertering av data for underprosess. Hopper over."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr "Bruker fontset «%s» som mangler disse tegnsettene: %s"
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr "Feil under lasting av Xft-skriftmønster «%s». Bruker forvalgt skrift."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Feil under lasting av forvalgt Xft-skrift."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr "Feil under lasting av fontset «%s». Bruker forvalgt skrift."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Feil under lasting av forvalgt skrift. Krasj eller abnormal oppførsel kan "
"ventes."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Feil under lesing av PTY-størrelse. Bruker forvalg: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Feil under setting av PTY-størrelse: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Feil under allokering av tegning. Deaktiverer Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Feil under allokering av kontekst. Deaktiverer Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Feil under allokering av «layout». Deaktiverer Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() feilet ved setting av ord-tegn"
msgid ""
msgstr ""
"Project-Id-Version: 2.0\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-28 18:13-0300\n"
"Last-Translator: Alexandre Folle de Menezes <afmenez@terra.com.br>\n"
"Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Erro ao adicionar `%s' ao ambiente, continuando."
msgid "Duplicate (%s/%s)!"
msgstr "Duplicata (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Erro compilando a expressão regular \"%s\"."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Incapaz de converter caracteres de %s para %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Seqüência (chave?) `%s' inesperada."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "O caracter 0x%x é indefinido, alocando uma coluna."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Nenhum manipulador para seqüência de controle `%s' foi definido."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Erro lendo do filho: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Erro (%s) convertendo dados para filho, descartando."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr ""
"Usando conjunto de fontes \"%s\", que não tem os seguintes conhuntos de "
"caracteres: %s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr "Falha ao carregar a fonte Xft \"%s\", voltando para a fonte padrão."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Falha ao carregar a fonte Xft padrão."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr "Falha ao carregar a fonte \"%s\", voltando para a fonte padrão."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr "Falha ao carregar a fonte padrão, pendurando ou agindo anormalmente."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Erro lendo o tamanho PTY, usando padrão: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Erro setando o tamanho PTY: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Erro alocando desenho, desabilitando Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Erro alocando contexto, desabilitando Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Erro alocando layout, desabilitando Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() falhou setando caracteres de palavra"
msgid ""
msgstr ""
"Project-Id-Version: vte\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-07 20:42+0200\n"
"Last-Translator: Christian Rose <menthos@menthos.com>\n"
"Language-Team: Swedish <sv@li.org>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Fel vid tillägg av \"%s\" till miljön, fortsätter."
msgid "Duplicate (%s/%s)!"
msgstr "Dubbel (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Fel vid kompilering av reguljärt uttryck \"%s\"."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Kan inte konvertera tecken från %s till %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Fick oväntad (tangent?)sekvens \"%s\"."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Tecknet 0x%x är odefinierat, allokerar en kolumn."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Ingen hanterare för kontrollsekvensen \"%s\" är angiven."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Fel vid läsning från barn: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Fel (%s) vid konvertering av data för barn, kastar."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr ""
"Använder typsnittssamlingen \"%s\", som saknar dessa teckensamlingar: %s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr ""
"Misslyckades med att läsa in XFt-typsnittsmönstret \"%s\", använder "
"standardtypsnittet."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Misslyckades med att läsa in Xft-standardtypsnittet."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr ""
"Misslyckades med att läsa in typsnittssamlingen \"%s\", använder "
"standardtypsnittet."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr ""
"Misslyckades med att läsa in standardtypsnittet, kraschar eller beter sig "
"onormalt."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Fel vid läsande av PTY-storlek, använder standardvärden: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Fel vid läsande av PTY-storlek: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Fel vid allokering av ritbar yta, deaktiverar Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Fel vid allokering av sammanhang, deaktiverar Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Fel vid allokering av layout, deaktiverar Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() misslyckades med att ställa in ordtecken"
msgid ""
msgstr ""
"Project-Id-Version: VTE for Gnome 2\n"
-"POT-Creation-Date: 2002-09-05 01:51-0400\n"
+"POT-Creation-Date: 2002-09-11 00:56-0400\n"
"PO-Revision-Date: 2002-08-24 19:49+0700\n"
"Last-Translator: Trinh Minh Thanh <tmthanh@linuxmail.org>\n"
"Language-Team: Gnome-Vi Team <Gnomevi-list@lists.sourceforge.net>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: src/pty.c:126
+#: src/pty.c:106
#, c-format
msgid "Error adding `%s' to environment, continuing."
msgstr "Lỗi khi thêm `%s' vào môi trường, tiếp tục."
msgid "Duplicate (%s/%s)!"
msgstr "Nhân đôi (%s/%s)!"
-#: src/vte.c:1167
+#: src/vte.c:1175
#, c-format
msgid "Error compiling regular expression \"%s\"."
msgstr "Lỗi khi biên dịch biểu hiện quy tắc \"%s\"."
-#: src/vte.c:1637 src/vte.c:1646 src/vte.c:1658 src/vte.c:1676 src/vte.c:1681
-#: src/vte.c:1686
+#: src/vte.c:1645 src/vte.c:1654 src/vte.c:1666 src/vte.c:1684 src/vte.c:1689
+#: src/vte.c:1694
#, c-format
msgid "Unable to convert characters from %s to %s."
msgstr "Không thể chuyển đổi các ký tự từ %s thành %s."
-#: src/vte.c:4886
+#: src/vte.c:4893
#, c-format
msgid "Got unexpected (key?) sequence `%s'."
msgstr "Nhận sequence không mong muốn (key?) `%s'."
-#: src/vte.c:5671
+#: src/vte.c:5679
#, c-format
msgid "Character 0x%x is undefined, allocating one column."
msgstr "Ký tự 0x%x không được định nghĩa, dùng một cột."
-#: src/vte.c:5865
+#: src/vte.c:5873
#, c-format
msgid "No handler for control sequence `%s' defined."
msgstr "Không có trình quản lý nào được chỉ định cho sequence `%s'."
-#: src/vte.c:6442
+#: src/vte.c:6483
#, c-format
msgid "Error reading from child: %s."
msgstr "Lỗi khi đọc từ child: %s."
-#: src/vte.c:6628
+#: src/vte.c:6673
#, c-format
msgid "Error (%s) converting data for child, dropping."
msgstr "Lỗi (%s) khi chuyển đổi dữ liệu cho child, bỏ."
-#: src/vte.c:8698
+#: src/vte.c:8745
#, c-format
msgid "Using fontset \"%s\", which is missing these character sets: %s."
msgstr "Dùng bộ phông \"%s\" thiếu các bảng mã này: %s."
-#: src/vte.c:9238
+#: src/vte.c:9285
#, c-format
msgid "Failed to load Xft font pattern \"%s\", falling back to default font."
msgstr "Không nạp được mẫu phông Xft \"%s\", trở lại với phông mặc định."
-#: src/vte.c:9250
+#: src/vte.c:9297
msgid "Failed to load default Xft font."
msgstr "Không nạp được phông Xft mặc định."
-#: src/vte.c:9343
+#: src/vte.c:9390
#, c-format
msgid "Failed to load font set \"%s\", falling back to default font."
msgstr "Không nạp được bộ phông \"%s\", trở lại với phông mặc định."
-#: src/vte.c:9355
+#: src/vte.c:9402
msgid "Failed to load default font, crashing or behaving abnormally."
msgstr "Không nạp được phông mặc định, bị crash hay ứng xử bất thường."
-#: src/vte.c:9614
+#: src/vte.c:9664
#, c-format
msgid "Error reading PTY size, using defaults: %s."
msgstr "Lỗi khi đọc kích thước PTY, sử dụng mặc định: %s."
-#: src/vte.c:9650
+#: src/vte.c:9700
#, c-format
msgid "Error setting PTY size: %s."
msgstr "Lỗi khi lập kích thước PTY: %s."
-#: src/vte.c:12148
+#: src/vte.c:12205
msgid "Error allocating draw, disabling Xft."
msgstr "Lỗi khi cấp phát draw, tắt Xft."
-#: src/vte.c:12155
+#: src/vte.c:12212
msgid "Error allocating context, disabling Pango."
msgstr "Lỗi khi cấp phát ngữ cảnh (context), tắt Pango."
-#: src/vte.c:12161
+#: src/vte.c:12218
msgid "Error allocating layout, disabling Pango."
msgstr "Lỗi khi cấp phát layout, tắt Pango."
#. Aaargh. We're screwed.
-#: src/vte.c:13608
+#: src/vte.c:13669
msgid "g_iconv_open() failed setting word characters"
msgstr "g_iconv_open() không lập được các ký tự cho word"
-EXTRA_PROGRAMS = vtemodule.so
EXTRA_DIST = vte.defs vte.override
-pythonsiteexecdir = $(pyexecdir)
+
+EXTRA_PROGRAMS = vtemodule.so
+
+if BUILD_PYTHON_BINDINGS
+pythonsiteexecdir = $(pyexecdir)/gtk-2.0
pythonsiteexec_PROGRAMS = @PYTHONMODULES@
+endif
-CFLAGS = @CFLAGS@ @XFT_CFLAGS@ @GTK_CFLAGS@ @X_CFLAGS@ @PYTHON_INCLUDES@
+INCLUDES = @VTE_CFLAGS@ @X_CFLAGS@ @PYTHON_INCLUDES@ @PYGTK_CFLAGS@
CLEANFILES = vte.c
vtemodule_so_SOURCES = vtemodule.c vte.c
-vtemodule_so_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ @PYGTK_CFLAGS@ -I$(includedir)/python@PYTHONREV@ -fPIC
-vtemodule_so_LDFLAGS = -shared
-vtemodule_so_LDADD = $(top_builddir)/src/libvte.la @LIBS@ @PYGTK_LIBS@ @XFT_LIBS@ @GTK_LIBS@ @X_LIBS@
+LDFLAGS = -shared -module -avoid-version -export-symbols-regex initvte
+LDADD = $(top_builddir)/src/libvte.la @LIBS@ @PYGTK_LIBS@ @VTE_LIBS@ @X_LIBS@
vte.c: vte.defs vte.override
pygtk-codegen-2.0 -p py$(PACKAGE) -o vte.override --register @PYGTK_DATADIR@/pygtk/2.0/defs/gtk-types.defs --register @PYGTK_DATADIR@/pygtk/2.0/defs/gdk-types.defs --register @PYGTK_DATADIR@/pygtk/2.0/defs/pango-types.defs $< > $@
import gtk
import vte
-# FIXME: figure out why we don't get a PID here.
-def exited_cb(terminal):
+def child_exited_cb(terminal):
gtk.mainquit()
if __name__ == '__main__':
child_pid = -1;
# Defaults.
+ audible = 0
+ background = None
+ blink = 0
+ command = None
emulation = "xterm"
font = "fixed 12"
- command = None
+ transparent = 0
+ visible = 0
# Let the user override them.
- (shorts, longs) = getopt.getopt(sys.argv[1:], "c:t:f:", ["command=", "terminal=", "font="])
+ (shorts, longs) = getopt.getopt(sys.argv[1:], "B:Tabc:f:t:v", ["background", "transparent", "audible", "blink", "command=", "font=", "terminal=", "visible"])
for argpair in (shorts + longs):
+ if ((argpair[0] == '-B') or (argpair[0] == '--background')):
+ print "Setting background image to `" + argpair[1] + "'."
+ background = argpair[1]
+ if ((argpair[0] == '-T') or (argpair[0] == '--transparent')):
+ print "Setting transparency."
+ transparent = not transparent
+ if ((argpair[0] == '-a') or (argpair[0] == '--audible')):
+ print "Setting audible bell."
+ audible = not audible
+ if ((argpair[0] == '-b') or (argpair[0] == '--blink')):
+ print "Setting blinking cursor."
+ blink = not blink
if ((argpair[0] == '-c') or (argpair[0] == '--command')):
print "Running command `" + argpair[1] + "'."
command = argpair[1]
if ((argpair[0] == '-t') or (argpair[0] == '--terminal')):
print "Setting terminal type to `" + argpair[1] + "'."
emulation = argpair[1]
+ if ((argpair[0] == '-v') or (argpair[0] == '--visible')):
+ print "Setting visible bell."
+ visible = not visible
window = gtk.Window()
terminal = vte.Terminal()
+ if (background):
+ terminal.set_background_image(background)
+ if (transparent):
+ terminal.set_background_transparent(gtk.TRUE)
+ terminal.set_cursor_blinks(blink)
terminal.set_emulation(emulation)
terminal.set_font_from_string(font)
- terminal.connect("child-exited", exited_cb)
+ terminal.set_audible_bell(audible)
+ terminal.set_visible_bell(visible)
+ terminal.connect("child-exited", child_exited_cb)
if (command):
# Start up the specified command.
child_pid = terminal.fork_command(command)
# Start up the default command, the user's shell.
child_pid = terminal.fork_command()
terminal.show()
- window.add(terminal)
- window.show()
+
+ scrollbar = gtk.VScrollbar()
+ scrollbar.set_adjustment(terminal.get_adjustment())
+
+ box = gtk.HBox()
+ box.pack_start(terminal)
+ box.pack_start(scrollbar)
+
+ window.add(box)
+ window.show_all()
gtk.main()
;; -*- scheme -*-
; object definitions ...
-
(define-object Terminal
(in-module "Vte")
(parent "GtkWidget")
)
-;; From vte.h
+;; From ../src/vte.h
(define-function vte_terminal_get_type
(c-name "vte_terminal_get_type")
(c-name "vte_terminal_set_size")
(return-type "none")
(parameters
- '("long" "columns")
- '("long" "rows")
+ '("glong" "columns")
+ '("glong" "rows")
)
)
(c-name "vte_terminal_set_scrollback_lines")
(return-type "none")
(parameters
- '("long" "lines")
+ '("glong" "lines")
)
)
(c-name "vte_terminal_get_cursor_position")
(return-type "none")
(parameters
- '("long*" "column")
- '("long*" "row")
+ '("glong*" "column")
+ '("glong*" "row")
)
)
(c-name "vte_terminal_match_check")
(return-type "char*")
(parameters
- '("long" "column")
- '("long" "row")
+ '("glong" "column")
+ '("glong" "row")
'("int*" "tag")
)
)
(c-name "vte_terminal_set_encoding")
(return-type "none")
(parameters
- '("const-char*" "encoding")
+ '("const-char*" "codeset")
)
)
)
)
+(define-method get_adjustment
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_adjustment")
+ (return-type "GtkAdjustment*")
+)
+
+(define-method get_char_width
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_char_width")
+ (return-type "glong")
+)
+
+(define-method get_char_height
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_char_height")
+ (return-type "glong")
+)
+
+(define-method get_char_descent
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_char_descent")
+ (return-type "glong")
+)
+
+(define-method get_char_ascent
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_char_ascent")
+ (return-type "glong")
+)
+
+(define-method get_row_count
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_row_count")
+ (return-type "glong")
+)
+
+(define-method get_column_count
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_column_count")
+ (return-type "glong")
+)
+
+(define-method get_window_title
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_window_title")
+ (return-type "const-char*")
+)
+
+(define-method get_icon_title
+ (of-object "VteTerminal")
+ (c-name "vte_terminal_get_icon_title")
+ (return-type "const-char*")
+)
+
unitable.JIS0212 \
unitable.KSC5601
-CFLAGS = @CFLAGS@ @XFT_CFLAGS@ @GTK_CFLAGS@ @X_CFLAGS@
+CFLAGS = @CFLAGS@ @VTE_CFLAGS@ @X_CFLAGS@
libvte_la_SOURCES = \
caps.c \
vteaccess.c \
vteaccess.h
-libvte_la_LIBADD = @LIBS@ @XFT_LIBS@ @GTK_LIBS@ @X_LIBS@
-libvte_la_LDFLAGS = -version-info 8:0:6
+libvte_la_LIBADD = @LIBS@ @VTE_LIBS@ @X_LIBS@
+libvte_la_LDFLAGS = -version-info 3:0:0
CLEANFILES = marshal.c marshal.h
vte_SOURCES = \
vteapp.c
-vte_LDADD = libvte.la @LIBS@ @XFT_LIBS@ @GTK_LIBS@ @X_LIBS@
+vte_LDADD = libvte.la @LIBS@ @VTE_LIBS@ @X_LIBS@
-interpret_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DINTERPRET_MAIN
+interpret_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DINTERPRET_MAIN
interpret_SOURCES = \
caps.c \
caps.h \
termcap.c \
termcap.h \
interpret.c
-interpret_LDADD = @GLIB_LIBS@
+interpret_LDADD = @GOBJECT_LIBS@
-iso2022_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DISO2022_MAIN
+iso2022_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DISO2022_MAIN
iso2022_SOURCES = \
debug.c \
debug.h \
iso2022.h \
table.c \
table.h
-iso2022_LDADD = @LIBS@ @GLIB_LIBS@
+iso2022_LDADD = @LIBS@ @GOBJECT_LIBS@
-utf8echo_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DUTF8ECHO_MAIN
+utf8echo_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DUTF8ECHO_MAIN
utf8echo_SOURCES = \
debug.c \
debug.h \
table.c \
table.h \
utf8echo.c
-utf8echo_LDADD = @LIBS@ @GLIB_LIBS@
+utf8echo_LDADD = @LIBS@ @GOBJECT_LIBS@
-ring_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DRING_MAIN
+ring_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DRING_MAIN
ring_SOURCES = \
debug.c \
debug.h \
ring.c \
ring.h
-ring_LDADD = @LIBS@ @GLIB_LIBS@
+ring_LDADD = @LIBS@ @GOBJECT_LIBS@
slowcat_SOURCES = \
slowcat.c
-slowcat_LDADD = @LIBS@ @GLIB_LIBS@
+slowcat_LDADD = @LIBS@ @GOBJECT_LIBS@
-table_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DTABLE_MAIN
+table_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DTABLE_MAIN
table_SOURCES = \
debug.c \
debug.h \
table.c \
table.h
-table_LDADD = @LIBS@ @GLIB_LIBS@
+table_LDADD = @LIBS@ @GOBJECT_LIBS@
-trie_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DTRIE_MAIN
+trie_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DTRIE_MAIN
trie_SOURCES = \
debug.c \
debug.h \
termcap.h \
trie.c \
trie.h
-trie_LDADD = @LIBS@ @GLIB_LIBS@
+trie_LDADD = @LIBS@ @GOBJECT_LIBS@
-termcap_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DTERMCAP_MAIN
+termcap_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DTERMCAP_MAIN
termcap_SOURCES = \
debug.c \
debug.h \
termcap.c \
termcap.h
-termcap_LDADD = @LIBS@ @GLIB_LIBS@
+termcap_LDADD = @LIBS@ @GOBJECT_LIBS@
-pty_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DPTY_MAIN
+pty_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DPTY_MAIN
pty_SOURCES = \
debug.c \
debug.h \
pty.c \
pty.h
-pty_LDADD = @LIBS@ @GLIB_LIBS@
+pty_LDADD = @LIBS@ @GOBJECT_LIBS@
-reaper_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@ -DREAPER_MAIN
+reaper_CFLAGS = @CFLAGS@ @GOBJECT_CFLAGS@ -DREAPER_MAIN
reaper_SOURCES = \
debug.c \
debug.h \
marshal.h \
reaper.c \
reaper.h
-reaper_LDADD = @LIBS@ @GLIB_LIBS@
+reaper_LDADD = @LIBS@ @GOBJECT_LIBS@
{"us", FALSE, 0},
{"vb", FALSE, 0},
- /* {"ve", 0}, */
- {"vi", 0},
- /* {"vsFALSE, ", 0}, */
+ /* {"ve", FALSE, 0}, */
+ {"vi", FALSE, 0},
+ /* {"vs", FALSE, 0}, */
{"wi", FALSE, 0},
#include <assert.h>
#include <ctype.h>
#include <errno.h>
-#include <langinfo.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
GValueArray *values;
GError *error = NULL;
gunichar *ubuf;
- gssize ubuflen, substlen;
+ gssize substlen;
+ gsize ubuflen;
_vte_debug_parse_string(getenv("VTE_DEBUG_FLAGS"));
substitutions = _vte_iso2022_new();
while (fread(&c, 1, 1, infile) == 1) {
- g_byte_array_append(array, &c, 1);
+ g_byte_array_append(array, (guint8*) &c, 1);
for (i = 1; i <= array->len; i++) {
- ubuf = (gunichar*) g_convert(array->data, i,
+ ubuf = (gunichar*) g_convert((const gchar*)array->data,
+ i,
_vte_table_wide_encoding(),
"UTF-8",
NULL, &ubuflen, &error);
};
struct _vte_iso2022 {
- int current, override;
+ unsigned int current, override;
gboolean ss2, ss3;
gunichar g[4];
};
#ifdef ISO2022_MAIN
static void
-debug_print(FILE *fp, const unsigned char *string)
+debug_print(FILE *fp, const char *string)
{
int i;
for (i = 0; string[i] != '\0'; i++) {
- if (string[i] < 32) {
+ if (((guint8)string[i]) < 32) {
fprintf(fp, "^%c", string[i] + 64);
} else
- if (string[i] < 128) {
+ if (((guint8)string[i]) < 128) {
fprintf(fp, "%c", string[i]);
} else {
fprintf(fp, "{0x%02x}", string[i]);
if (argc > 1) {
putc('\e', stdout);
- switch(argv[1][0]) {
+ switch (argv[1][0]) {
case '0':
case 'A':
case 'B':
putc(argv[1][0], stdout);
break;
case '-':
- switch(argv[1][1]) {
+ switch (argv[1][1]) {
case '@':
case 'B':
putc('$', stdout);
#ident "$Id$"
#include "../config.h"
#include <sys/ioctl.h>
+#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
#include "debug.h"
#include "pty.h"
+#include "../gnome-pty-helper/gnome-pty.h"
+
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) dgettext(PACKAGE, String)
#define _(String) String
#endif
-/* Open the named PTY slave, fork off a child (storing its PID in child),
- * and exec the named command in its own session as a process group leader */
+static gboolean _vte_pty_helper_started = FALSE;
+static pid_t _vte_pty_helper_pid = -1;
+static int _vte_pty_helper_tunnel = -1;
+static GTree *_vte_pty_helper_map = NULL;
+
+/* Run the given command, using the given descriptor as the controlling
+ * terminal. */
static int
-vte_pty_fork_on_pty(const char *path, char **env_add,
- const char *command, char **argv, pid_t *child)
+_vte_pty_run_on_pty(int fd, char **env_add, const char *command, char **argv)
{
- int fd, i;
- pid_t pid;
+ int i;
char **args, *arg;
-
- /* Start up a child. */
- pid = fork();
- if (pid == -1) {
- /* Error fork()ing. Bail. */
- *child = -1;
- return -1;
- }
- if (pid != 0) {
- /* Parent. Close our connection to the slave and return the
- * new child's PID. */
- *child = pid;
- return 0;
- }
-
- /* Child. Start a new session and become process-group leader. */
- setsid();
- setpgid(0, 0);
-
- /* Close all descriptors. */
- for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
- close(i);
- }
-
- /* Open the slave PTY, acquiring it as the controlling terminal for
- * this process and its children. */
- fd = open(path, O_RDWR);
- if (fd == -1) {
- return -1;
- }
if (fd != STDIN_FILENO) {
dup2(fd, STDIN_FILENO);
}
/* Avoid calling any atexit() code. */
_exit(0);
+ g_assert_not_reached();
+ return 0;
+}
+
+/* Open the named PTY slave, fork off a child (storing its PID in child),
+ * and exec the named command in its own session as a process group leader */
+static int
+_vte_pty_fork_on_pty_name(const char *path, char **env_add,
+ const char *command, char **argv, pid_t *child)
+{
+ int fd, i;
+ pid_t pid;
+
+ /* Start up a child. */
+ pid = fork();
+ if (pid == -1) {
+ /* Error fork()ing. Bail. */
+ *child = -1;
+ return -1;
+ }
+ if (pid != 0) {
+ /* Parent. Close our connection to the slave and return the
+ * new child's PID. */
+ *child = pid;
+ return 0;
+ }
+
+ /* Child. Start a new session and become process-group leader. */
+ setsid();
+ setpgid(0, 0);
+
+ /* Close all descriptors. */
+ for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
+ close(i);
+ }
+
+ /* Open the slave PTY, acquiring it as the controlling terminal for
+ * this process and its children. */
+ fd = open(path, O_RDWR);
+ if (fd == -1) {
+ return -1;
+ }
+ return _vte_pty_run_on_pty(fd, env_add, command, argv);
+}
+
+/* Fork off a child (storing its PID in child), and exec the named command
+ * in its own session as a process group leader using the given terminal. */
+static int
+_vte_pty_fork_on_pty_fd(int fd, char **env_add,
+ const char *command, char **argv, pid_t *child)
+{
+ int i;
+ char *tty;
+ pid_t pid;
+
+ /* Start up a child. */
+ pid = fork();
+ if (pid == -1) {
+ /* Error fork()ing. Bail. */
+ *child = -1;
+ return -1;
+ }
+ if (pid != 0) {
+ /* Parent. Close our connection to the slave and return the
+ * new child's PID. */
+ *child = pid;
+ return 0;
+ }
+
+ /* Save the name of the pty -- we'll need it later to acquire it as
+ * our controlling terminal. */
+ tty = ttyname(fd);
+
+ /* Child. Start a new session and become process-group leader. */
+ setsid();
+ setpgid(0, 0);
+
+ /* Close all other descriptors. */
+ for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
+ if (i != fd) {
+ close(i);
+ }
+ }
+
+ /* Try to reopen the pty to acquire it as our controlling terminal. */
+ if (tty != NULL) {
+ i = open(tty, O_RDWR);
+ if (i != -1) {
+ close(fd);
+ fd = i;
+ }
+ }
+
+ return _vte_pty_run_on_pty(fd, env_add, command, argv);
}
/**
}
static char *
-vte_pty_ptsname(int master)
+_vte_pty_ptsname(int master)
{
#if defined(HAVE_PTSNAME_R)
char buf[PATH_MAX];
}
static int
-vte_pty_getpt(void)
+_vte_pty_getpt(void)
{
#ifdef HAVE_GETPT
return getpt();
}
static int
-vte_pty_grantpt(int master)
+_vte_pty_grantpt(int master)
{
#ifdef HAVE_GRANTPT
return grantpt(master);
}
static int
-vte_pty_unlockpt(int fd)
+_vte_pty_unlockpt(int fd)
{
#ifdef HAVE_UNLOCKPT
return unlockpt(fd);
#elif defined(TIOCSPTLCK)
int zero = 0;
return ioctl(fd, TIOCSPTLCK, &zero);
-#endif
+#else
return -1;
+#endif
}
static int
-vte_pty_open_unix98(pid_t *child, char **env_add,
+_vte_pty_open_unix98(pid_t *child, char **env_add,
const char *command, char **argv,
int columns, int rows)
{
char *buf;
/* Attempt to open the master. */
- fd = vte_pty_getpt();
+ fd = _vte_pty_getpt();
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_PTY)) {
fprintf(stderr, "Allocated pty on fd %d.\n", fd);
#endif
if (fd != -1) {
/* Read the slave number and unlock it. */
- if (((buf = vte_pty_ptsname(fd)) == NULL) ||
- (vte_pty_grantpt(fd) != 0) ||
- (vte_pty_unlockpt(fd) != 0)) {
+ if (((buf = _vte_pty_ptsname(fd)) == NULL) ||
+ (_vte_pty_grantpt(fd) != 0) ||
+ (_vte_pty_unlockpt(fd) != 0)) {
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_PTY)) {
fprintf(stderr, "PTY setup failed, bailing.\n");
/* Set the window size. */
vte_pty_set_size(fd, columns, rows);
/* Start up a child process with the given command. */
- if (vte_pty_fork_on_pty(buf, env_add, command, argv,
- child) != 0) {
+ if (_vte_pty_fork_on_pty_name(buf, env_add, command,
+ argv, child) != 0) {
close(fd);
fd = -1;
}
}
static int
-vte_pty_open_old_school(pid_t *child, char **env_add,
- const char *command, char **argv,
- int columns, int rows)
+_vte_pty_pipe_open(int *a, int *b)
{
- /* FIXME */
+ int p[2], ret = -1;
+#ifdef PF_UNIX
+#ifdef SOCK_STREAM
+ ret = socketpair(PF_UNIX, SOCK_STREAM, 0, p);
+#else
+#ifdef SOCK_DGRAM
+ ret = socketpair(PF_UNIX, SOCK_DGRAM, 0, p);
+#endif
+#endif
+ if (ret == 0) {
+ *a = p[0];
+ *b = p[1];
+ return 0;
+ }
+#endif
+ return ret;
+}
+
+static void
+_vte_pty_stop_helper(void)
+{
+ if (_vte_pty_helper_started) {
+ g_tree_destroy(_vte_pty_helper_map);
+ _vte_pty_helper_map = NULL;
+ close(_vte_pty_helper_tunnel);
+ _vte_pty_helper_tunnel = -1;
+ kill(_vte_pty_helper_pid, SIGTERM);
+ _vte_pty_helper_pid = -1;
+ _vte_pty_helper_started = FALSE;
+ }
+}
+
+static gint
+_vte_direct_compare(gconstpointer a, gconstpointer b)
+{
+ return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
+}
+
+static gboolean
+_vte_pty_start_helper(void)
+{
+ int i, tmp[2], tunnel;
+ /* Create a communication link for use with the helper. */
+ tmp[0] = open("/dev/null", O_RDONLY);
+ if (tmp[0] == -1) {
+ return FALSE;
+ }
+ tmp[1] = open("/dev/null", O_RDONLY);
+ if (tmp[1] == -1) {
+ close(tmp[0]);
+ return FALSE;
+ }
+ if (_vte_pty_pipe_open(&_vte_pty_helper_tunnel, &tunnel) == -1) {
+ return FALSE;
+ }
+ close(tmp[0]);
+ close(tmp[1]);
+ /* Now fork and start the helper. */
+ _vte_pty_helper_pid = fork();
+ if (_vte_pty_helper_pid == -1) {
+ return FALSE;
+ }
+ if (_vte_pty_helper_pid == 0) {
+ /* Child. Close all descriptors. */
+ for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) {
+ if (i != tunnel) {
+ close(i);
+ }
+ }
+ /* Reassign the socket pair to stdio. */
+ dup2(tunnel, STDIN_FILENO);
+ dup2(tunnel, STDOUT_FILENO);
+ close(tunnel);
+ close(_vte_pty_helper_tunnel);
+ /* Exec our helper. */
+ execl(PKGLIBDIR "/gnome-pty-helper",
+ "gnome-pty-helper", NULL);
+ /* Bail. */
+ _exit(1);
+ }
+ close(tunnel);
+ _vte_pty_helper_map = g_tree_new(_vte_direct_compare);
+ atexit(_vte_pty_stop_helper);
+ return TRUE;
+}
+
+#ifdef SCM_RIGHTS
+static void
+_vte_pty_read_ptypair(int tunnel, int *parentfd, int *childfd)
+{
+ int i, ret;
+ char control[LINE_MAX], iobuf[LINE_MAX];
+ struct cmsghdr *cmsg;
+ struct msghdr msg;
+ struct iovec vec;
+
+ for (i = 0; i < 2; i++) {
+ vec.iov_base = iobuf;
+ vec.iov_len = sizeof(iobuf);
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+ ret = recvmsg(tunnel, &msg, MSG_NOSIGNAL);
+ if (ret == -1) {
+ return;
+ }
+ for (cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_type == SCM_RIGHTS) {
+ memcpy(&ret, CMSG_DATA(cmsg), sizeof(ret));
+ switch (i) {
+ case 0:
+ *parentfd = ret;
+ break;
+ case 1:
+ *childfd = ret;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ }
+ }
+ }
+}
+#else
+#ifdef I_RECVFD
+static void
+_vte_pty_read_ptypair(int tunnel, int *parentfd, int *childfd)
+{
+ int i;
+ if (ioctl(tunnel, I_RECVFD, &i) == -1) {
+ return;
+ }
+ *parentfd = i;
+ if (ioctl(tunnel, I_RECVFD, &i) == -1) {
+ return;
+ }
+ *childfd = i;
+}
+#endif
+#endif
+
+static int
+_vte_pty_open_old_school(pid_t *child, char **env_add,
+ const char *command, char **argv,
+ int columns, int rows, int op)
+{
+ GnomePtyOps ops;
+ int ret;
+ int parentfd = -1, childfd = -1;
+ gpointer tag;
+ /* We have to use the pty helper here. */
+ if (!_vte_pty_helper_started) {
+ _vte_pty_helper_started = _vte_pty_start_helper();
+ }
+ /* Try to open a new descriptor. */
+ if (_vte_pty_helper_started) {
+ ops = op;
+ /* Send our request. */
+ if (write(_vte_pty_helper_tunnel,
+ &ops, sizeof(ops)) != sizeof(ops)) {
+ return -1;
+ }
+ /* Read back the response. */
+ if (read(_vte_pty_helper_tunnel,
+ &ret, sizeof(ret)) != sizeof(ret)) {
+ return -1;
+ }
+ if (ret == 0) {
+ return -1;
+ }
+ /* Read back a tag. */
+ if (read(_vte_pty_helper_tunnel,
+ &tag, sizeof(tag)) != sizeof(tag)) {
+ return -1;
+ }
+ /* Receive the master and slave ptys. */
+ _vte_pty_read_ptypair(_vte_pty_helper_tunnel,
+ &parentfd, &childfd);
+ if ((parentfd == -1) || (childfd == -1)) {
+ close(parentfd);
+ close(childfd);
+ return -1;
+ }
+ /* Add the parent and the tag to our map. */
+ g_tree_insert(_vte_pty_helper_map,
+ GINT_TO_POINTER(parentfd),
+ tag);
+ /* Set the window size. */
+ vte_pty_set_size(parentfd, columns, rows);
+ /* Start up a child process with the given command. */
+ if (_vte_pty_fork_on_pty_fd(childfd, env_add, command,
+ argv, child) != 0) {
+ close(parentfd);
+ close(childfd);
+ return -1;
+ }
+ close(childfd);
+ return parentfd;
+ }
return -1;
}
/**
- * vte_pty_open:
+ * vte_pty_open_with_logging:
* @child: location to store the new process's ID
* @env_add: a list of environment variables to add to the child's environment
* @command: name of the binary to run
* @argv: arguments to pass to @command
* @columns: desired window columns
* @rows: desired window rows
+ * @lastlog: TRUE if the lastlog should be updated
+ * @utmp: TRUE if the utmp or utmpx log should be updated
+ * @wtmp: TRUE if the wtmp or wtmpx log should be updated
*
* Starts a new copy of @command running under a psuedo-terminal, with window
* size set to @rows x @columns and variables in @env_add added to its
- * environment.
+ * environment. If any combination of @lastlog, @utmp, and @wtmp is set,
+ * then the session is logged in the appropriate system log.
*
* Returns: an open file descriptor for the pty master, -1 on failure
*/
int
-vte_pty_open(pid_t *child, char **env_add,
- const char *command, char **argv,
- int columns, int rows)
+vte_pty_open_with_logging(pid_t *child, char **env_add,
+ const char *command, char **argv,
+ int columns, int rows,
+ gboolean lastlog, gboolean utmp, gboolean wtmp)
{
int ret = -1;
+ int op = 0;
+ int opmap[8] = {
+ GNOME_PTY_OPEN_NO_DB_UPDATE, /* 0 0 0 */
+ GNOME_PTY_OPEN_PTY_LASTLOG, /* 0 0 1 */
+ GNOME_PTY_OPEN_PTY_UTMP, /* 0 1 0 */
+ GNOME_PTY_OPEN_PTY_LASTLOGUTMP, /* 0 1 1 */
+ GNOME_PTY_OPEN_PTY_WTMP, /* 1 0 0 */
+ GNOME_PTY_OPEN_PTY_LASTLOGWTMP, /* 1 0 1 */
+ GNOME_PTY_OPEN_PTY_UWTMP, /* 1 1 0 */
+ GNOME_PTY_OPEN_PTY_LASTLOGUWTMP, /* 1 1 1 */
+ };
+ if (lastlog) {
+ op += 1;
+ }
+ if (utmp) {
+ op += 2;
+ }
+ if (wtmp) {
+ op += 4;
+ }
+ g_assert(op >= 0);
+ g_assert(op < G_N_ELEMENTS(opmap));
if (ret == -1) {
- ret = vte_pty_open_unix98(child, env_add, command, argv,
- columns, rows);
+ ret = _vte_pty_open_old_school(child, env_add, command, argv,
+ columns, rows, opmap[op]);
}
if (ret == -1) {
- ret = vte_pty_open_old_school(child, env_add, command, argv,
- columns, rows);
+ ret = _vte_pty_open_unix98(child, env_add, command, argv,
+ columns, rows);
}
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_PTY)) {
return ret;
}
+/**
+ * vte_pty_open:
+ * @child: location to store the new process's ID
+ * @env_add: a list of environment variables to add to the child's environment
+ * @command: name of the binary to run
+ * @argv: arguments to pass to @command
+ * @columns: desired window columns
+ * @rows: desired window rows
+ *
+ * Starts a new copy of @command running under a psuedo-terminal, with window
+ * size set to @rows x @columns and variables in @env_add added to its
+ * environment. A convenience wrapper for vte_pty_open_with_logging().
+ *
+ * Returns: an open file descriptor for the pty master, -1 on failure
+ */
+int
+vte_pty_open(pid_t *child, char **env_add,
+ const char *command, char **argv,
+ int columns, int rows)
+{
+ return vte_pty_open_with_logging(child, env_add, command, argv,
+ columns, rows,
+ FALSE, FALSE, FALSE);
+}
+
+
+/**
+ * vte_pty_close:
+ * @pty: the pty master descriptor.
+ *
+ * Cleans up the PTY associated with the descriptor, specifically any logging
+ * performed for the session. The descriptor itself remains open.
+ */
+void
+vte_pty_close(int pty)
+{
+ gpointer tag;
+ GnomePtyOps ops;
+ if (g_tree_lookup(_vte_pty_helper_map, GINT_TO_POINTER(pty))) {
+ /* Signal the helper that it needs to close its connection. */
+ ops = GNOME_PTY_CLOSE_PTY;
+ tag = g_tree_lookup(_vte_pty_helper_map, GINT_TO_POINTER(pty));
+ if (write(_vte_pty_helper_tunnel,
+ &ops, sizeof(ops)) != sizeof(ops)) {
+ return;
+ }
+ if (write(_vte_pty_helper_tunnel,
+ &tag, sizeof(tag)) != sizeof(tag)) {
+ return;
+ }
+ /* Remove the item from the map. */
+ g_tree_remove(_vte_pty_helper_map, GINT_TO_POINTER(pty));
+ }
+}
+
#ifdef PTY_MAIN
+int fd;
+
+static void
+sigchld_handler(int signum)
+{
+ /* This is very unsafe. Never do it in production code. */
+ vte_pty_close(fd);
+}
+
int
main(int argc, char **argv)
{
pid_t child;
- int fd;
char c;
+ int ret;
+ signal(SIGCHLD, sigchld_handler);
_vte_debug_parse_string(getenv("VTE_DEBUG_FLAGS"));
- fd = vte_pty_open(&child, NULL, "/usr/bin/tty", NULL, 0, 0);
+ fd = vte_pty_open(&child, NULL,
+ (argc > 1) ? argv[1] : "/usr/bin/tty",
+ (argc > 1) ? argv + 1 : NULL,
+ 0, 0);
g_print("Child pid is %d.\n", (int)child);
- while(read(fd, &c, 1) == 1) {
+ do {
+ ret = read(fd, &c, 1);
+ if (ret == 0) {
+ break;
+ }
+ if ((ret == -1) && (errno != EAGAIN) && (errno != EINTR)) {
+ break;
+ }
write(STDOUT_FILENO, &c, 1);
- }
+ } while (TRUE);
return 0;
}
#endif
const char *command, char **argv,
int columns, int rows);
+/* As above, but with session logging. */
+int vte_pty_open_with_logging(pid_t *child, char **env_add,
+ const char *command, char **argv,
+ int columns, int rows,
+ gboolean lastlog, gboolean utmp, gboolean wtmp);
+
/* Set or read the size of a terminal. Returns 0 on success, -1 on failure,
* with errno set to defined return codes from ioctl(). */
int vte_pty_get_size(int master, int *columns, int *rows);
int vte_pty_set_size(int master, int columns, int rows);
+/* Close a pty. */
+void vte_pty_close(int pty);
+
G_END_DECLS
#endif
/**
* vte_reaper_get:
*
+ * Finds the address of the global #VteReaper object, creating the object if
+ * necessary.
+ *
* Returns: the global #VteReaper object
*/
VteReaper *
__position, __position % (__ring)->max, \
(__ring)->delta, (__ring)->length, (__ring)->max, \
(__ring)->delta + (__ring)->length, \
- __LINE__), NULL))
+ __LINE__), (gpointer) NULL))
#define _vte_ring_index(__ring, __cast, __position) \
(__cast) _vte_ring_at(__ring, __position)
void
_vte_table_free(struct _vte_table *table)
{
- int i;
+ unsigned int i;
for (i = 0; i < G_N_ELEMENTS(table->table); i++) {
if (table->table[i] != NULL) {
_vte_table_free(table->table[i]);
static void
_vte_table_addi(struct _vte_table *table,
const unsigned char *original, gssize original_length,
- const unsigned char *pattern, gssize length,
+ const char *pattern, gssize length,
const char *result, GQuark quark, int inc)
{
int i;
+ guint8 check;
struct _vte_table *subtable;
/* If this is the terminal node, set the result. */
}
/* A literal (or an unescaped '%', which is also a literal). */
- g_assert(pattern[0] < VTE_TABLE_MAX_LITERAL);
- if (table->table[pattern[0]] == NULL) {
+ check = (guint8) pattern[0];
+ g_assert(check < VTE_TABLE_MAX_LITERAL);
+ if (table->table[check] == NULL) {
subtable = _vte_table_new();
- table->table[pattern[0]] = subtable;
+ table->table[check] = subtable;
} else {
- subtable = table->table[pattern[0]];
+ subtable = table->table[check];
}
/* Add the rest of the string to the subtable. */
_vte_table_addi(subtable, original, original_length,
/* Add a string to the matching tree. */
void
_vte_table_add(struct _vte_table *table,
- const unsigned char *pattern, gssize length,
+ const char *pattern, gssize length,
const char *result, GQuark quark)
{
- unsigned char *pattern_copy, *p;
+ char *pattern_copy, *p;
pattern_copy = g_strndup(pattern, length);
/* Collapse as many numeric parameters as possible into '%m'. */
while ((p = strstr(pattern_copy, "%d")) != NULL) {
#ifdef TABLE_MAIN
/* Return an escaped version of a string suitable for printing. */
static char *
-escape(const unsigned char *p)
+escape(const char *p)
{
char *tmp;
GString *ret;
int i;
+ guint8 check;
ret = g_string_new("");
for (i = 0; p[i] != '\0'; i++) {
tmp = NULL;
- if (p[i] < 32) {
- tmp = g_strdup_printf("^%c", p[i] + 64);
+ check = p[i];
+ if (check < 32) {
+ tmp = g_strdup_printf("^%c", check + 64);
} else
- if (p[i] >= 0x80) {
- tmp = g_strdup_printf("{0x%x}", p[i]);
+ if (check >= 0x80) {
+ tmp = g_strdup_printf("{0x%x}", check);
} else {
- tmp = g_strdup_printf("%c", p[i]);
+ tmp = g_strdup_printf("%c", check);
}
g_string_append(ret, tmp);
g_free(tmp);
/* Spread out a narrow ASCII string into a wide-character string. */
static gunichar *
-make_wide(const unsigned char *p)
+make_wide(const char *p)
{
gunichar *ret;
+ guint8 check;
int i;
ret = g_malloc((strlen(p) + 1) * sizeof(gunichar));
for (i = 0; p[i] != 0; i++) {
- g_assert(p[i] < 0x80);
- ret[i] = p[i];
+ check = (guint8) p[i];
+ g_assert(check < 0x80);
+ ret[i] = check;
}
ret[i] = '\0';
return ret;
/* Add a string to the matching tree. */
void _vte_table_add(struct _vte_table *table,
- const unsigned char *pattern, gssize length,
+ const char *pattern, gssize length,
const char *result, GQuark quark);
/* Check if a string matches something in the tree. */
ret[o++] = termcap[i];
if (termcap[i] == '\\') {
char *p;
- switch(termcap[i + 1]) {
+ switch (termcap[i + 1]) {
case '\n':
while ((termcap[i + 1] == ' ') ||
(termcap[i + 1] == '\t')) {
}
} else
if (termcap[i] == '^') {
- switch(termcap[i + 1]) {
+ switch (termcap[i + 1]) {
case 'A':
case 'B':
case 'C':
{
const char *val;
char *p;
- ssize_t l;
+ gssize l;
long ret;
g_return_val_if_fail(termcap != NULL, 0);
val = _vte_termcap_find(termcap, tname, cap);
const char *cap)
{
const char *val, *p;
- ssize_t l;
+ gssize l;
val = _vte_termcap_find(termcap, tname, cap);
if ((val != NULL) && (val[0] != '\0')) {
l = strlen(cap);
*/
TERMCAP_MAYBE_STATIC char *
_vte_termcap_find_string_length(struct _vte_termcap *termcap, const char *tname,
- const char *cap, ssize_t *length)
+ const char *cap, gssize *length)
{
const char *val, *p;
char *ret;
- ssize_t l;
+ gssize l;
val = _vte_termcap_find(termcap, tname, cap);
if ((val != NULL) && (val[0] != '\0')) {
l = strlen(cap);
vte_termcap_comment(struct vte_termcap *termcap, const char *tname)
{
struct vte_termcap_alias *alias;
- ssize_t len;
+ gssize len;
if ((tname == NULL) || (tname[0] == '\0')) {
return termcap->comment;
}
TERMCAP_MAYBE_STATIC char *
vte_termcap_generate(struct vte_termcap *termcap)
{
- ssize_t size;
+ gssize size;
char *ret = NULL;
struct vte_termcap_entry *entry;
size = strlen(termcap->comment ? termcap->comment: "");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_WCHAR_H
#include <wchar.h>
+#endif
#include <glib.h>
#include <glib-object.h>
#include "debug.h"
default:
return FALSE;
}
- return FALSE;
}
static void
char_class_digit_setup(const gunichar *s, struct char_class_data *data, int inc)
default:
return FALSE;
}
- return FALSE;
}
static void
char_class_multi_setup(const gunichar *s, struct char_class_data *data, int inc)
return length;
}
static void
-unichar_sncpy(gunichar *d, const gunichar *s, size_t length)
+unichar_sncpy(gunichar *d, const gunichar *s, gsize length)
{
- int i;
+ unsigned int i;
for (i = 0; i < length; i++) {
d[i] = s[i];
if (s[i] == 0) {
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
-#include <langinfo.h>
#include <math.h>
#include <pwd.h>
#include <regex.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
+#ifdef HAVE_WCHAR_H
#include <wchar.h>
+#endif
#include <glib.h>
#include <glib-object.h>
#include <gdk/gdk.h>
const char *encoding; /* the pty's encoding */
struct _vte_iso2022 *substitutions;
GIConv incoming_conv; /* narrow/unichar conversion state */
- unsigned char *incoming; /* pending output characters */
- gssize n_incoming;
+ char *incoming; /* pending output characters */
+ gsize n_incoming;
gboolean processing;
gint processing_tag;
/* Output data queue. */
- unsigned char *outgoing; /* pending input characters */
- gssize n_outgoing;
+ char *outgoing; /* pending input characters */
+ gsize n_outgoing;
GIConv outgoing_conv_wide;
GIConv outgoing_conv_utf8;
int ret;
gsize length, bytes_read, bytes_written;
mbstate_t state;
- GError *error;
+ GError *error = NULL;
/* Check the cache. */
if (g_tree_lookup_extended(terminal->pvt->unichar_wc_map,
GINT_TO_POINTER(c),
vte_invalidate_cursor_periodic(gpointer data)
{
VteTerminal *terminal;
+ GtkWidget *widget;
GtkSettings *settings;
gint blink_cycle = 1000;
g_return_val_if_fail(VTE_IS_TERMINAL(data), FALSE);
- if (!GTK_WIDGET_REALIZED(GTK_WIDGET(data))) {
+ widget = GTK_WIDGET(data);
+ if (!GTK_WIDGET_REALIZED(widget)) {
+ return TRUE;
+ }
+ if (!GTK_WIDGET_HAS_FOCUS(widget)) {
return TRUE;
}
- terminal = VTE_TERMINAL(data);
- vte_invalidate_cursor_once(data);
+ terminal = VTE_TERMINAL(widget);
+ if (terminal->pvt->cursor_blinks) {
+ vte_invalidate_cursor_once(terminal);
+ }
settings = gtk_widget_get_settings(GTK_WIDGET(data));
if (G_IS_OBJECT(settings)) {
{
VteTerminal *terminal;
terminal = VTE_TERMINAL(data);
- if (terminal->pvt->adjustment_changed_tag != -1) {
+ if (terminal->pvt->adjustment_changed_tag) {
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_EVENTS)) {
fprintf(stderr, "Emitting adjustment_changed.\n");
}
#endif
- terminal->pvt->adjustment_changed_tag = -1;
+ terminal->pvt->adjustment_changed_tag = 0;
gtk_adjustment_changed(terminal->adjustment);
}
return FALSE;
static void
vte_terminal_queue_adjustment_changed(VteTerminal *terminal)
{
- if (terminal->pvt->adjustment_changed_tag != -1) {
+ if (terminal->pvt->adjustment_changed_tag == 0) {
terminal->pvt->adjustment_changed_tag =
g_idle_add_full(VTE_ADJUSTMENT_PRIORITY,
vte_terminal_emit_adjustment_changed,
int increment,
VteTerminalSequenceHandler handler)
{
- int i;
+ guint i;
long val;
GValue *value;
/* Decrement the parameters and let the _cs handler deal with it. */
GQuark encoding_quark;
GIConv conv, new_iconv, new_oconvw, new_oconvu;
char *ibuf, *obuf, *obufptr;
- gssize icount, ocount;
+ gsize icount, ocount;
old_codeset = terminal->pvt->encoding;
if (codeset == NULL) {
GValue *value;
GIConv conv;
char *inbuf = NULL, *outbuf = NULL, *outbufptr = NULL;
- gssize inbuf_len, outbuf_len;
+ gsize inbuf_len, outbuf_len;
/* Get the string parameter's value. */
value = g_value_array_get_nth(params, 0);
if (value) {
Display *display;
char buf[LINE_MAX];
long param, arg1, arg2;
- guint width, height;
- int i;
+ guint width, height, i;
widget = GTK_WIDGET(terminal);
screen = terminal->pvt->screen;
GdkColor color;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
+ g_return_if_fail(entry >= 0);
g_return_if_fail(entry < G_N_ELEMENTS(terminal->pvt->palette));
/* Save the requested color. */
/* Display the control sequence with its parameters, to
* help me debug this thing. I don't have all of the
* sequences implemented yet. */
- int i;
+ guint i;
long l;
const char *s;
const gunichar *w;
} else
if (G_VALUE_HOLDS_POINTER(value)) {
w = g_value_get_pointer(value);
- fprintf(stderr, "\"%ls\"", (wchar_t*) w);
+ fprintf(stderr, "\"%ls\"", (const wchar_t*) w);
}
}
}
}
/**
- * vte_terminal_fork_command:
+ * vte_terminal_fork_logged_command:
* @terminal: a #VteTerminal
* @command: the name of a binary to run
* @argv: the argument list to be passed to @command
* @envv: a list of environment variables to be added to the environment before
* starting @command
+ * @lastlog: TRUE if the session should be logged to the lastlog
+ * @utmp: TRUE if the session should be logged to the utmp/utmpx log
+ * @wtmp: TRUE if the session should be logged to the wtmp/wtmpx log
*
* Starts the specified command under a newly-alllocated control
* pseudo-terminal. TERM is automatically set to reflect the terminal widget's
- * emulation setting.
+ * emulation setting. If @lastlog, @utmp, or @wtmp are TRUE, logs the session
+ * to the specified system log files.
*
* Returns: the ID of the new process
*/
pid_t
-vte_terminal_fork_command(VteTerminal *terminal, const char *command,
- char **argv, char **envv)
+vte_terminal_fork_logged_command(VteTerminal *terminal, const char *command,
+ char **argv, char **envv,
+ gboolean lastlog, gboolean utmp, gboolean wtmp)
{
char **env_add;
int i;
}
env_add[i + 1] = NULL;
- terminal->pvt->pty_master = vte_pty_open(&pid,
- env_add,
- command,
- argv,
- terminal->column_count,
- terminal->row_count);
+ if (terminal->pvt->pty_master != -1) {
+ vte_pty_close(terminal->pvt->pty_master);
+ }
+ terminal->pvt->pty_master = vte_pty_open_with_logging(&pid,
+ env_add,
+ command,
+ argv,
+ terminal->column_count,
+ terminal->row_count,
+ lastlog,
+ utmp,
+ wtmp);
for (i = 0; env_add[i] != NULL; i++) {
g_free(env_add[i]);
return pid;
}
+/**
+ * vte_terminal_fork_command:
+ * @terminal: a #VteTerminal
+ * @command: the name of a binary to run
+ * @argv: the argument list to be passed to @command
+ * @envv: a list of environment variables to be added to the environment before
+ * starting @command
+ *
+ * Starts the specified command under a newly-alllocated control
+ * pseudo-terminal. TERM is automatically set to reflect the terminal widget's
+ * emulation setting.
+ *
+ * Returns: the ID of the new process
+ */
+pid_t
+vte_terminal_fork_command(VteTerminal *terminal, const char *command,
+ char **argv, char **envv)
+{
+ return vte_terminal_fork_logged_command(terminal, command, argv, envv,
+ FALSE, FALSE, FALSE);
+}
+
/* Handle an EOF from the client. */
static void
vte_terminal_eof(GIOChannel *channel, gpointer data)
static void
free_params_array(GValueArray *params)
{
- int i;
+ guint i;
GValue *value;
gpointer ptr;
if (params != NULL) {
GtkWidget *widget;
GdkRectangle rect;
char *ibuf, *obuf, *obufptr, *ubuf, *ubufptr;
- gssize icount, ocount, ucount;
+ gsize icount, ocount, ucount;
gunichar *wbuf, c;
long wcount, start;
const char *match, *encoding;
}
#endif
terminal->pvt->processing = FALSE;
- terminal->pvt->processing_tag = -1;
+ terminal->pvt->processing_tag = 0;
g_free(obufptr);
return terminal->pvt->processing;
}
* note that our source tag is about to become invalid. */
terminal->pvt->processing = again && (terminal->pvt->n_incoming > 0);
if (terminal->pvt->processing == FALSE) {
- terminal->pvt->processing_tag = -1;
+ terminal->pvt->processing_tag = 0;
}
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_IO)) {
int i;
for (i = 0; i < count; i++) {
fprintf(stderr, "Wrote %c%c\n",
- terminal->pvt->outgoing[i] >= 32 ?
+ ((guint8)terminal->pvt->outgoing[i]) >= 32 ?
' ' : '^',
- terminal->pvt->outgoing[i] >= 32 ?
+ ((guint8)terminal->pvt->outgoing[i]) >= 32 ?
terminal->pvt->outgoing[i] :
- terminal->pvt->outgoing[i] + 64);
+ ((guint8)terminal->pvt->outgoing[i]) + 64);
}
}
#endif
g_source_remove(terminal->pvt->pty_output_source);
terminal->pvt->pty_output_source = -1;
}
+ if (terminal->pvt->outgoing != NULL) {
+ g_free(terminal->pvt->outgoing);
+ terminal->pvt->outgoing = NULL;
+ }
leave_open = FALSE;
} else {
leave_open = TRUE;
gssize icount, ocount;
char *ibuf, *obuf, *obufptr;
char *outgoing;
- gssize n_outgoing;
+ gsize n_outgoing;
GIConv *conv;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
if (GTK_IS_WIDGET(old_toplevel)) {
g_signal_handlers_disconnect_by_func(G_OBJECT(old_toplevel),
- vte_terminal_configure_toplevel,
+ (gpointer)vte_terminal_configure_toplevel,
terminal);
}
static struct {
gulong keyval;
- unsigned char *special;
- unsigned char *vt_ctrl_special;
+ char *special;
+ char *vt_ctrl_special;
} vte_keysym_map[] = {
{GDK_F1, "k1", "F3"},
{GDK_KP_F1, "k1", "F3"},
PangoFontDescription *fontdesc;
struct _vte_termcap *termcap;
const char *tterm;
- unsigned char *normal = NULL;
+ char *normal = NULL;
gssize normal_length = 0;
int i;
- unsigned char *special = NULL, *specialmods = NULL;
+ char *special = NULL, *specialmods = NULL;
struct termios tio;
struct timeval tv;
struct timezone tz;
break;
}
/* If we got normal characters, send them to the child. */
- if (normal != NULL && normal_length > 0) {
+ if (normal != NULL) {
if (terminal->pvt->alt_sends_escape &&
(normal_length > 0) &&
(modifiers & GDK_MOD1_MASK)) {
vte_terminal_feed_child(terminal, "\e", 1);
}
- vte_terminal_feed_child(terminal,
- normal, normal_length);
+ if (normal_length > 0) {
+ vte_terminal_feed_child(terminal,
+ normal, normal_length);
+ }
g_free(normal);
} else
/* If the key maps to characters, send them to the child. */
}
#endif
} else {
- terminal->pvt->mouse_autoscroll_tag = -1;
+ terminal->pvt->mouse_autoscroll_tag = 0;
}
- return (terminal->pvt->mouse_autoscroll_tag != -1);
+ return (terminal->pvt->mouse_autoscroll_tag != 0);
}
/* Read and handle a motion event. */
need_autoscroll = TRUE;
}
if (need_autoscroll &&
- (terminal->pvt->mouse_autoscroll_tag == -1)) {
+ (terminal->pvt->mouse_autoscroll_tag == 0)) {
terminal->pvt->mouse_autoscroll_tag = g_timeout_add_full(G_PRIORITY_LOW,
50,
vte_terminal_autoscroll,
* NULL, characters will only be read if @is_selected returns TRUE after being
* passed the column and row, respectively. A #vte_char_attributes structure
* is added to @attributes for each byte added to the returned string detailing
- * the character's position, colors, and other characteristics. The
+ * the character's position, colors, and other characteristics. The
* entire scrollback buffer is scanned, so it is possible to read the entire
* contents of the buffer using this function.
*
* NULL, characters will only be read if @is_selected returns TRUE after being
* passed the column and row, respectively. A #vte_char_attributes structure
* is added to @attributes for each byte added to the returned string detailing
- * the character's position, colors, and other characteristics.
+ * the character's position, colors, and other characteristics.
*
* Returns: a text string which must be freed by the caller.
*/
}
/* Disconnect from autoscroll requests. */
- if (terminal->pvt->mouse_autoscroll_tag != -1) {
+ if (terminal->pvt->mouse_autoscroll_tag) {
g_source_remove(terminal->pvt->mouse_autoscroll_tag);
- terminal->pvt->mouse_autoscroll_tag = -1;
+ terminal->pvt->mouse_autoscroll_tag = 0;
}
}
double size = 14.0;
if (font_desc != NULL) {
- pango_mask = pango_font_description_get_set_fields (font_desc);
+ pango_mask = pango_font_description_get_set_fields(font_desc);
}
pattern = XftPatternCreate ();
/* Set the family for the pattern, or use a sensible default. */
if (pango_mask & PANGO_FONT_MASK_FAMILY) {
- family = pango_font_description_get_family (font_desc);
+ family = pango_font_description_get_family(font_desc);
}
- XftPatternAddString (pattern, XFT_FAMILY, family);
+ XftPatternAddString(pattern, XFT_FAMILY, family);
/* Set the font size for the pattern, or use a sensible default. */
if (pango_mask & PANGO_FONT_MASK_SIZE) {
- size = (double) pango_font_description_get_size (font_desc);
+ size = (double) pango_font_description_get_size(font_desc);
size /= (double) PANGO_SCALE;
}
- XftPatternAddDouble (pattern, XFT_SIZE, size);
+ XftPatternAddDouble(pattern, XFT_SIZE, size);
/* There aren'ty any fallbacks for these, so just omit them from the
* pattern if they're not set in the pango font. */
if (pango_mask & PANGO_FONT_MASK_WEIGHT) {
- weight = pango_font_description_get_weight (font_desc);
- XftPatternAddInteger (pattern, XFT_WEIGHT,
- xft_weight_from_pango_weight (weight));
+ weight = pango_font_description_get_weight(font_desc);
+ XftPatternAddInteger(pattern, XFT_WEIGHT,
+ xft_weight_from_pango_weight (weight));
}
if (pango_mask & PANGO_FONT_MASK_STYLE) {
- style = pango_font_description_get_style (font_desc);
- XftPatternAddInteger (pattern, XFT_SLANT,
- xft_slant_from_pango_style (style));
+ style = pango_font_description_get_style(font_desc);
+ XftPatternAddInteger(pattern, XFT_SLANT,
+ xft_slant_from_pango_style (style));
}
return pattern;
const PangoFontDescription *font_desc)
{
GtkWidget *widget;
+ PangoFontDescription *desc;
g_return_if_fail(terminal != NULL);
g_return_if_fail(VTE_IS_TERMINAL(terminal));
/* Create an owned font description. */
if (font_desc != NULL) {
- font_desc = pango_font_description_copy(font_desc);
+ desc = pango_font_description_copy(font_desc);
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_MISC)) {
- if (font_desc) {
+ if (desc) {
char *tmp;
- tmp = pango_font_description_to_string(font_desc);
+ tmp = pango_font_description_to_string(desc);
fprintf(stderr, "Using pango font \"%s\".\n", tmp);
g_free (tmp);
}
#endif
} else {
gtk_widget_ensure_style(widget);
- font_desc =
- pango_font_description_copy(widget->style->font_desc);
+ desc = pango_font_description_copy(widget->style->font_desc);
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_MISC)) {
fprintf(stderr, "Using default pango font.\n");
if (terminal->pvt->fontdesc != NULL) {
pango_font_description_free(terminal->pvt->fontdesc);
}
- terminal->pvt->fontdesc = (PangoFontDescription*) font_desc;
+ terminal->pvt->fontdesc = desc;
/* Free the older fonts and load the new ones. */
vte_terminal_close_font(terminal);
* vte_terminal_get_font:
* @terminal: a #VteTerminal
*
+ * Queries the terminal for information about the fonts which will be
+ * used to draw text in the terminal.
+ *
* Returns: a #PangoFontDescription describing the font the terminal is
* currently using to render text.
*/
if (terminal->adjustment != NULL) {
/* Disconnect our signal handlers from this object. */
g_signal_handlers_disconnect_by_func(terminal->adjustment,
- G_CALLBACK(vte_terminal_handle_scroll),
+ (gpointer)vte_terminal_handle_scroll,
terminal);
g_object_unref(terminal->adjustment);
}
* vte_terminal_get_emulation:
* @terminal: a #VteTerminal
*
+ * Queries the terminal for its current emulation, as last set by a call to
+ * vte_terminal_set_emulation().
+ *
* Returns: the name of the terminal type the widget is attempting to emulate
*/
const char *
pvt->incoming = NULL;
pvt->n_incoming = 0;
pvt->processing = FALSE;
- pvt->processing_tag = -1;
+ pvt->processing_tag = 0;
pvt->outgoing = NULL;
pvt->n_outgoing = 0;
pvt->incoming_conv = (GIConv) -1;
/* Cursor blinking. */
pvt->cursor_blinks = FALSE;
- pvt->cursor_blink_tag = -1;
+ pvt->cursor_blink_tag = 0;
pvt->cursor_visible = TRUE;
pvt->cursor_blink_timeout = 1000;
pvt->mouse_last_x = 0;
pvt->mouse_last_y = 0;
pvt->mouse_autohide = FALSE;
- pvt->mouse_autoscroll_tag = -1;
+ pvt->mouse_autoscroll_tag = 0;
/* Matching data. */
pvt->match_contents = NULL;
pvt->connected_settings = NULL;
/* Bookkeeping data for adjustment-changed signals. */
- pvt->adjustment_changed_tag = -1;
+ pvt->adjustment_changed_tag = 0;
/* Set up background information. */
pvt->bg_transparent = FALSE;
pvt->bg_transparent_update_pending = FALSE;
- pvt->bg_transparent_update_tag = -1;
+ pvt->bg_transparent_update_tag = 0;
pvt->bg_transparent_atom = 0;
pvt->bg_transparent_window = NULL;
pvt->bg_transparent_image = NULL;
}
/* Remove the blink timeout function. */
- if (terminal->pvt->cursor_blink_tag != -1) {
+ if (terminal->pvt->cursor_blink_tag) {
g_source_remove(terminal->pvt->cursor_blink_tag);
}
g_object_unref(G_OBJECT(terminal->pvt->bg_transparent_image));
terminal->pvt->bg_transparent_image = NULL;
}
- if (terminal->pvt->bg_transparent_update_tag != -1) {
+ if (terminal->pvt->bg_transparent_update_tag) {
g_source_remove(terminal->pvt->bg_transparent_update_tag);
- terminal->pvt->bg_transparent_update_tag = -1;
+ terminal->pvt->bg_transparent_update_tag = 0;
}
#ifdef HAVE_XFT2
/* Disconnect from settings changes. */
if (terminal->pvt->connected_settings) {
g_signal_handlers_disconnect_by_func(G_OBJECT(terminal->pvt->connected_settings),
- vte_xft_changed_cb,
+ (gpointer)vte_xft_changed_cb,
terminal);
terminal->pvt->connected_settings = NULL;
}
toplevel = gtk_widget_get_toplevel(GTK_WIDGET(object));
if ((toplevel != NULL) && (G_OBJECT(toplevel) != G_OBJECT(object))) {
g_signal_handlers_disconnect_by_func(toplevel,
- vte_terminal_configure_toplevel,
+ (gpointer)vte_terminal_configure_toplevel,
terminal);
}
/* Disconnect from autoscroll requests. */
- if (terminal->pvt->mouse_autoscroll_tag != -1) {
+ if (terminal->pvt->mouse_autoscroll_tag) {
g_source_remove(terminal->pvt->mouse_autoscroll_tag);
- terminal->pvt->mouse_autoscroll_tag = -1;
+ terminal->pvt->mouse_autoscroll_tag = 0;
}
/* Cancel pending adjustment change notifications. */
- if (terminal->pvt->adjustment_changed_tag != -1) {
+ if (terminal->pvt->adjustment_changed_tag) {
g_source_remove(terminal->pvt->adjustment_changed_tag);
- terminal->pvt->adjustment_changed_tag = -1;
+ terminal->pvt->adjustment_changed_tag = 0;
}
/* Tabstop information. */
/* Stop listening for child-exited signals. */
g_signal_handlers_disconnect_by_func(vte_reaper_get(),
- vte_terminal_catch_child_exited,
+ (gpointer)vte_terminal_catch_child_exited,
terminal);
/* Stop processing input. */
- if (terminal->pvt->processing_tag != -1) {
+ if (terminal->pvt->processing_tag != 0) {
g_source_remove(terminal->pvt->processing_tag);
- terminal->pvt->processing_tag = -1;
+ terminal->pvt->processing_tag = 0;
}
/* Discard any pending data. */
g_source_remove(terminal->pvt->pty_output_source);
terminal->pvt->pty_output_source = -1;
}
- close(terminal->pvt->pty_master);
+ vte_pty_close(terminal->pvt->pty_master);
terminal->pvt->pty_master = -1;
/* Clear some of our strings. */
_vte_termcap_free(terminal->pvt->termcap);
terminal->pvt->termcap = NULL;
+ /* Done with our private data. */
+ g_free(terminal->pvt);
+ terminal->pvt = NULL;
+
/* Free public-facing data. */
if (terminal->window_title != NULL) {
g_free(terminal->window_title);
VteTerminal *terminal = NULL;
GdkWindowAttr attributes;
GdkPixmap *pixmap;
- GdkColor black = {0,}, color;
+ GdkColor black = {0,0,0}, color;
int attributes_mask = 0, i;
g_return_if_fail(widget != NULL);
/* Add this cell to the draw list. */
item.c = cell ? cell->c : ' ';
- item.xpad = vte_terminal_get_char_padding(terminal,
- display,
- item.c);
+ if (monospaced) {
+ item.xpad = 0;
+ } else {
+ item.xpad = vte_terminal_get_char_padding(terminal,
+ display,
+ item.c);
+ }
g_array_append_val(items, item);
/* Now find out how many cells have the same attributes. */
}
/* Add this cell to the draw list. */
item.c = cell ? cell->c : ' ';
- item.xpad = vte_terminal_get_char_padding(terminal,
- display,
- item.c);
+ if (monospaced) {
+ item.xpad = 0;
+ } else {
+ item.xpad = vte_terminal_get_char_padding(terminal,
+ display,
+ item.c);
+ }
g_array_append_val(items, item);
}
/* Draw the cells. */
}
/* If we need a new copy of the desktop, get it. */
if (refresh_transparent) {
- guint width, height, pwidth, pheight;
+ gint width, height, pwidth, pheight;
#ifdef VTE_DEBUG
if (_vte_debug_on(VTE_DEBUG_MISC)) {
#endif
vte_terminal_setup_background(terminal, TRUE);
terminal->pvt->bg_transparent_update_pending = FALSE;
- terminal->pvt->bg_transparent_update_tag = -1;
+ terminal->pvt->bg_transparent_update_tag = 0;
}
return FALSE;
}
* vte_terminal_set_background_saturation, the terminal will make its
* in-memory copy of the image darker for its own use.
*
- * This is a convenience function for vte_terminal_set_background_image().
+ * This is a convenience wrapper for vte_terminal_set_background_image().
* If your application intends to create multiple terminal widgets using the
* same background, performing this step yourself and just using
* vte_terminal_set_background_image() will reduce memory consumption.
* vte_terminal_get_has_selection:
* @terminal: a #VteTerminal
*
+ * Checks if the terminal currently contains selected text. Note that this
+ * is different from determining if the terminal is the owner of any
+ * #GtkClipboard items.
+ *
* Returns: TRUE if part of the text in the terminal is selected.
*/
gboolean
GIConv conv;
gunichar *wbuf;
char *ibuf, *ibufptr, *obuf, *obufptr;
- gssize ilen, olen;
+ gsize ilen, olen;
VteWordCharRange range;
int i;
terminal->pvt->n_incoming = 0;
if (terminal->pvt->processing) {
g_source_remove(terminal->pvt->processing_tag);
- terminal->pvt->processing_tag = -1;
+ terminal->pvt->processing_tag = 0;
terminal->pvt->processing = FALSE;
}
/* Reset charset substitution state. */
/* Reset the input and output buffers. */
if (terminal->pvt->n_incoming > 0) {
terminal->pvt->n_incoming = 0;
+ }
+ if (terminal->pvt->incoming != NULL) {
g_free(terminal->pvt->incoming);
terminal->pvt->incoming = NULL;
}
if (terminal->pvt->n_outgoing > 0) {
terminal->pvt->n_outgoing = 0;
+ }
+ if (terminal->pvt->outgoing != NULL) {
g_free(terminal->pvt->outgoing);
terminal->pvt->outgoing = NULL;
}
*xpad = 2 * VTE_PAD_WIDTH;
*ypad = 2 * VTE_PAD_WIDTH;
}
+
+/**
+ * vte_terminal_get_adjustment:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's adjustment field
+ */
+GtkAdjustment *
+vte_terminal_get_adjustment(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
+ return terminal->adjustment;
+}
+
+/**
+ * vte_terminal_get_char_width:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's char_width field
+ */
+glong
+vte_terminal_get_char_width(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->char_width;
+}
+
+/**
+ * vte_terminal_get_char_height:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's char_height field
+ */
+glong
+vte_terminal_get_char_height(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->char_height;
+}
+
+/**
+ * vte_terminal_get_char_descent:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's char_descent field
+ */
+glong
+vte_terminal_get_char_descent(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->char_descent;
+}
+
+/**
+ * vte_terminal_get_char_ascent:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's char_ascent field
+ */
+glong
+vte_terminal_get_char_ascent(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->char_ascent;
+}
+
+/**
+ * vte_terminal_get_row_count:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's row_count field
+ */
+glong
+vte_terminal_get_row_count(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->row_count;
+}
+
+/**
+ * vte_terminal_get_column_count:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's column_count field
+ */
+glong
+vte_terminal_get_column_count(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+ return terminal->column_count;
+}
+
+/**
+ * vte_terminal_get_window_title:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's window_title field
+ */
+const char *
+vte_terminal_get_window_title(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), "");
+ return terminal->window_title;
+}
+
+/**
+ * vte_terminal_get_icon_title:
+ * @terminal: a #VteTerminal
+ *
+ * An accessor function provided for the benefit of language bindings.
+ *
+ * Returns: the contents of @terminal's icon_title field
+ */
+const char *
+vte_terminal_get_icon_title(VteTerminal *terminal)
+{
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), "");
+ return terminal->icon_title;
+}
pid_t vte_terminal_fork_command(VteTerminal *terminal,
const char *command, char **argv, char **envv);
+/* If you need the session logged, try this instead. */
+pid_t vte_terminal_fork_logged_command(VteTerminal *terminal,
+ const char *command, char **argv,
+ char **envv,
+ gboolean lastlog,
+ gboolean utmp,
+ gboolean wtmp);
+
/* Send data to the terminal to display, or to the terminal's forked command
* to handle in some way. If it's 'cat', they should be the same. */
void vte_terminal_feed(VteTerminal *terminal, const char *data, glong length);
/* Get the padding the widget is using. */
void vte_terminal_get_padding(VteTerminal *terminal, int *xpad, int *ypad);
+/* Accessors for bindings. */
+GtkAdjustment *vte_terminal_get_adjustment(VteTerminal *terminal);
+glong vte_terminal_get_char_width(VteTerminal *terminal);
+glong vte_terminal_get_char_height(VteTerminal *terminal);
+glong vte_terminal_get_char_descent(VteTerminal *terminal);
+glong vte_terminal_get_char_ascent(VteTerminal *terminal);
+glong vte_terminal_get_row_count(VteTerminal *terminal);
+glong vte_terminal_get_column_count(VteTerminal *terminal);
+const char *vte_terminal_get_window_title(VteTerminal *terminal);
+const char *vte_terminal_get_icon_title(VteTerminal *terminal);
+
G_END_DECLS
#endif
G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA,
0, 0, NULL,
- vte_terminal_accessible_invalidate_contents,
+ (gpointer)vte_terminal_accessible_invalidate_contents,
object);
g_signal_handlers_disconnect_matched(G_OBJECT(accessible->widget),
G_SIGNAL_MATCH_FUNC |
G_SIGNAL_MATCH_DATA,
0, 0, NULL,
- vte_terminal_accessible_title_changed,
+ (gpointer)vte_terminal_accessible_title_changed,
object);
if (gobject_class->finalize != NULL) {
gobject_class->finalize(object);
"[-t terminaltype]\n";
back.red = back.green = back.blue = 0xffff;
fore.red = fore.green = fore.blue = 0x3000;
+
+ /* Have to do this early. */
+ if (getenv("VTE_PROFILE_MEMORY")) {
+ if (atol(getenv("VTE_PROFILE_MEMORY")) != 0) {
+ g_mem_set_vtable(glib_mem_profiler_table);
+ }
+ }
+
/* Pull out long options for GTK+. */
for (i = j = 1; i < argc; i++) {
if (g_ascii_strncasecmp("--", argv[i], 2) == 0) {
/* Go for it! */
gtk_widget_show_all(window);
+
gtk_main();
return 0;
Name: vte
Description: Vte terminal widget.
Version: @VERSION@
-Requires: glib-2.0 gobject-2.0 gtk+-2.0 gdk-pixbuf-2.0
+Requires: glib-2.0 gobject-2.0 atk pango pangox gtk+-2.0 gdk-pixbuf-2.0
Libs: -L${libdir} -lvte
Cflags: -I${includedir}
Name: vte
-Version: 0.8.19
+Version: 0.9.0
Release: 1
Summary: An experimental terminal emulator.
License: LGPL
%defattr(-,root,root)
%doc ChangeLog COPYING HACKING NEWS README
%{_libdir}/*.so.*.*
+%dir %{_libdir}/%{name}
+%attr(2711,root,utmp) %{_libdir}/%{name}/gnome-pty-helper
%{_datadir}/%{name}
-%{_libdir}/python*/site-packages/*
+%{_libdir}/python*/site-packages/gtk-2.0/*
%files devel
%defattr(-,root,root)
%{_libdir}/pkgconfig/*
%changelog
+* Wed Sep 11 2002 Nalin Dahyabhai <nalin@redhat.com> 0.9.0-1
+- build fixes from Jacob Berkman
+- warning fixes from Brian Cameron
+- gnome-pty-helper integration
+
+* Fri Sep 6 2002 Nalin Dahyabhai <nalin@redhat.com> 0.8.20-1
+- build fixups from Jacob Berkman
+- move the python module into the gtk-2.0 subdirectory, from James Henstridge
+
* Thu Sep 5 2002 Nalin Dahyabhai <nalin@redhat.com> 0.8.19-1
- possible fix for focusing bugs