* acinclude.m4: add AC_CHECK_CC_OPT from ac-archive.
* configure.in: check for cfmakeraw, sys/select.h, compiler support for -std=
(#99698)
* doc/boxes.txt: change reference to online Docbook reference to the charts at
the Unicode web site.
* src/dumpkeys.c: make a best-effort at making a terminal raw on systems where
cfmakeraw() isn't available, from patch by Brian Cameron. Wait for up
to 1/50 of a second for more bytes we'll consider to be part of a
sequence.
* src/pty.c(getpt): ensure that the new terminal is opened in non-blocking mode.
* src/trie.c: use g_unichar_digit_value() instead of subtracting '0'.
* src/vte.c: don't declare the xft_textitem member on non-Xft2 systems, because
it uses an Xft2-specific type (#99685).
* src/vteapp.c: add $pkgdatadir/fonts to the font path for use when testing.
+2002-12-02 nalin
+ * acinclude.m4: add AC_CHECK_CC_OPT from ac-archive.
+ * configure.in: check for cfmakeraw, sys/select.h, compiler support
+ for -std= (#99698)
+ * doc/boxes.txt: change reference to online Docbook reference to the
+ charts at the Unicode web site.
+ * src/dumpkeys.c: make a best-effort at making a terminal raw on systems
+ where cfmakeraw() isn't available, from patch by Brian Cameron. Wait
+ for up to 1/50 of a second for more bytes we'll consider to be part of
+ a sequence.
+ * src/pty.c(getpt): ensure that the new terminal is opened in non-
+ blocking mode.
+ * src/trie.c: use g_unichar_digit_value() instead of subtracting '0'.
+ * src/vte.c: don't declare the xft_textitem member on non-Xft2 systems,
+ because it uses an Xft2-specific type (#99685).
+ * src/vteapp.c: add $pkgdatadir/fonts to the font path for testing.
+
2002-11-25 nalin
* src/vte.c: fix mapping of Unicode code chars 0x252c and 0x2534 which
incorrectly mixed them up (#99474).
+dnl From msw.
+dnl
dnl a macro to check for ability to create python extensions
dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
dnl function also defines PYTHON_INCLUDES
[AC_MSG_RESULT(not found)
$2])
CPPFLAGS="$save_CPPFLAGS"
-])
\ No newline at end of file
+])
+
+dnl From ac-archive.
+dnl
+dnl @synopsis AC_CHECK_CC_OPT(flag, cachevarname)
+dnl
+dnl AC_CHECK_CC_OPT(-fvomit-frame,vomitframe)
+dnl would show a message as like
+dnl "checking wether gcc accepts -fvomit-frame ... no"
+dnl and sets the shell-variable $vomitframe to either "-fvomit-frame"
+dnl or (in this case) just a simple "". In many cases you would then call
+dnl AC_SUBST(_fvomit_frame_,$vomitframe) to create a substitution that
+dnl could be fed as "CFLAGS = @_funsigned_char_@ @_fvomit_frame_@
+dnl
+dnl in consequence this function is much more general than their
+dnl specific counterparts like ac_cxx_rtti.m4 that will test for
+dnl -fno-rtti -fno-exceptions
+dnl
+dnl @version $Id$
+dml @author Guido Draheim <guidod@gmx.de>
+
+AC_DEFUN(AC_CHECK_CC_OPT,
+[AC_CACHE_CHECK(whether ${CC-cc} accepts [$1], [$2],
+[AC_SUBST($2)
+echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -c $1 conftest.c 2>&1`"; then
+ $2="$1"
+else
+ $2=""
+fi
+rm -f conftest*
+])])
+
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 sendmsg)
+AC_CHECK_FUNCS(cfmakeraw getpt grantpt unlockpt ptsname ptsname_r sendmsg)
AC_CHECK_FUNC(socket,[have_socket=1],AC_CHECK_LIB(socket,socket,[have_socket=1; LIBS="$LIBS -lsocket"]))
AC_CHECK_FUNC(socketpair,[have_socketpair=1],AC_CHECK_LIB(socket,socketpair,[have_socketpair=1; LIBS="$LIBS -lsocket"]))
-AC_CHECK_HEADERS(sys/un.h stropts.h termios.h wchar.h)
+AC_CHECK_HEADERS(sys/select.h sys/un.h stropts.h termios.h wchar.h)
if test x$have_socket = x1 ; then
AC_DEFINE(HAVE_SOCKET,1,[Define if you have the `socket' function.])
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"
+ AC_CHECK_CC_OPT(-std=c99,vte_std_c99)
+ CFLAGS="${CFLAGS} $vte_std_c99"
CFLAGS="${CFLAGS} -Wall"
CFLAGS="${CFLAGS} -Waggregate-return"
CFLAGS="${CFLAGS} -Wcast-align"
CFLAGS="${CFLAGS} -Wpointer-arith"
CFLAGS="${CFLAGS} -Wstrict-prototypes"
CFLAGS="${CFLAGS} -Wuninitialized"
- #CFLAGS="${CFLAGS} −Wsign−compare"
- #CFLAGS="${CFLAGS} −Wunused-value"
+ #CFLAGS="${CFLAGS} -Wsign-compare"
+ #CFLAGS="${CFLAGS} -Wunused-value"
fi
VTE_DEBUG=1
fi
╙╜
VT-102: http://vt100.net/docs/vt102-ug/table5-13.html
-Unicode: http://www.oreilly.com/catalog/docbook/chapter/book/iso-box.html
+Unicode: http://www.unicode.org/charts/PDF/U2500.pdf
#ident "$Id$"
#include "../config.h"
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
xterm_fkeys = FALSE, vt220_fkeys = FALSE;
struct termios original;
+/* Output the DEC private mode set sequence. */
static void
decset(int mode, gboolean value)
{
g_print(ESC "[?%d%c", mode, value ? 'h' : 'l');
}
+/* Move the cursor to the upper left corner of the screen. */
static void
home(void)
{
g_print(ESC "[1;1H");
}
+/* Clear the screen. */
static void
clear(void)
{
home();
}
+/* Print the what-does-this-key-do help messages and current status. */
static void
print_help(void)
{
g_print(ESC "[K" "Q - QUIT\r\n");
}
+/* Reset the scrolling region, so that the entire screen becomes
+ * addressable again. */
static void
reset_scrolling_region(void)
{
g_print(ESC "[r");
}
+/* Set the scrolling region, so that the help/status at the top of the
+ * screen doesn't scroll off. */
static void
set_scrolling_region(void)
{
g_print(ESC "[9;1H");
}
+/* Save the current location of the cursor in the terminal's memory. */
static void
save_cursor(void)
{
g_print(ESC "7");
}
+/* Restore the cursor to the location stored in the terminal's memory. */
static void
restore_cursor(void)
{
g_print(ESC "8");
}
+/* Reset all of the keyboard modes. */
static void
reset(void)
{
restore_cursor();
}
+/* Cleanly exit. */
static void
sigint_handler(int signum)
{
main(int argc, char **argv)
{
char c;
- int flags, i;
+ guint i;
struct termios tcattr;
GByteArray *bytes;
gboolean done = FALSE, saved = FALSE;
+ struct timeval tv;
+ fd_set readset;
+ /* Start up: save the cursor location and put the terminal in
+ * raw mode. */
bytes = g_byte_array_new();
save_cursor();
if (tcgetattr(STDIN_FILENO, &tcattr) != 0) {
}
original = tcattr;
signal(SIGINT, sigint_handler);
+ /* Here we approximate what cfmakeraw() would do, for the benefit
+ * of systems which don't actually provide the function. */
+ tcattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP |
+ INLCR | IGNCR | ICRNL | IXON);
+ tcattr.c_oflag &= ~(OPOST);
+ tcattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ tcattr.c_cflag &= ~(CSIZE | PARENB);
+ tcattr.c_cflag |= CS8;
+#ifdef HAVE_CFMAKERAW
cfmakeraw(&tcattr);
+#endif
if (tcsetattr(STDIN_FILENO, TCSANOW, &tcattr) != 0) {
perror("tcsetattr");
return 1;
}
+ /* Switch to the alternate screen, clear it, and reset the keyboard. */
decset(MODE_ALTERNATE_SCREEN, TRUE);
clear();
reset();
+ /* Main processing loop. */
while (!done) {
print_help();
set_scrolling_region();
restore_cursor();
}
+ /* Read a single byte. */
if (read(STDIN_FILENO, &c, 1) != 1) {
done = TRUE;
}
case 'q':
done = TRUE;
break;
- case 0x0c:
+ case 0x0c: /* ^L */
clear();
if (saved) {
restore_cursor();
}
break;
default:
+ /* We get here if it's not one of the keys we care
+ * about, so it might be a sequence. */
if (saved) {
restore_cursor();
}
g_byte_array_append(bytes, &c, 1);
- flags = fcntl(STDIN_FILENO, F_GETFL);
- fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
- while (read(STDIN_FILENO, &c, 1) == 1) {
- g_byte_array_append(bytes, &c, 1);
+ /* Wait for up to just under 1/50 second. */
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000000 / 50;
+ FD_ZERO(&readset);
+ FD_SET(STDIN_FILENO, &readset);
+ while (select(STDIN_FILENO + 1,
+ &readset, NULL, NULL, &tv) == 1) {
+ if (read(STDIN_FILENO, &c, 1) == 1) {
+ g_byte_array_append(bytes, &c, 1);
+ } else {
+ break;
+ }
+ tv.tv_sec = 0;
+ tv.tv_usec = 1000000 / 50;
+ FD_ZERO(&readset);
+ FD_SET(STDIN_FILENO, &readset);
}
- fcntl(STDIN_FILENO, F_SETFL, flags);
+ /* Clear this line, and print the sequence. */
g_print(ESC "[K");
- for (i = 0; i < bytes->len; i++)
- switch (bytes->data[i]) {
- case 27:
- g_print("<ESC> ");
- break;
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- case 17:
- case 18:
- case 19:
- case 20:
- case 21:
- case 22:
- case 23:
- case 24:
- case 25:
- case 26:
- case 28:
- case 29:
- case 30:
- case 31:
- g_print("<0x%02x> ", bytes->data[i]);
- break;
- default:
- g_print("`%c' ", bytes->data[i]);
- break;
+ for (i = 0; i < bytes->len; i++) {
+ if (bytes->data[i] == 27) {
+ g_print("<ESC> ");
+ } else
+ if ((((guint8)bytes->data[i]) < 32) ||
+ (((guint8)bytes->data[i]) > 126)) {
+ g_print("<0x%02x> ", bytes->data[i]);
+ } else {
+ g_print("`%c' ", bytes->data[i]);
+ }
}
g_print("\r\n");
g_byte_array_set_size(bytes, 0);
static int
_vte_pty_getpt(void)
{
+ int fd, flags;
#ifdef HAVE_GETPT
- return getpt();
+ /* Call the system's function for allocating a pty. */
+ fd = getpt();
#else
- return open("/dev/ptmx", O_RDWR | O_NOCTTY);
+ /* Try to allocate a pty by accessing the pty master multiplex. */
+ fd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
#endif
+ /* Set it to blocking. */
+ flags = fcntl(fd, F_GETFL);
+ flags &= ~(O_NONBLOCK);
+ fcntl(fd, F_SETFL, flags);
+ return fd;
}
static int
}
/**
- * vte_pty_open_with_logging:
+ * _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
}
/**
- * vte_pty_close:
+ * _vte_pty_close:
* @pty: the pty master descriptor.
*
* Cleans up the PTY associated with the descriptor, specifically any logging
{
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;
+ if (_vte_pty_helper_map != NULL) {
+ 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));
}
- /* Remove the item from the map. */
- g_tree_remove(_vte_pty_helper_map, GINT_TO_POINTER(pty));
}
}
GValue value;
for (i = 0; i < length; i++) {
ret *= 10;
- ret += (s[i] - '0');
+ ret += g_unichar_digit_value(s[i]) == -1 ?
+ 0 : g_unichar_digit_value(s[i]);
}
memset(&value, 0, sizeof(value));
g_value_init(&value, G_TYPE_LONG);
} palette[VTE_DIM_FG + 1];
XwcTextItem xlib_textitem[VTE_DRAW_MAX_LENGTH];
wchar_t xlib_wcitem[VTE_DRAW_MAX_LENGTH];
-#ifdef HAVE_XFT
+#ifdef HAVE_XFT2
XftCharSpec xft_textitem[VTE_DRAW_MAX_LENGTH];
#endif
return row;
}
-/* Guess at how many columns a character takes up. */
-static gssize
-vte_unichar_width(gunichar c)
-{
- return g_unichar_isdefined(c) ? (g_unichar_iswide(c) ? 2 : 1) : 1;
-}
-
/* Check how long a string of unichars is. Slow version. */
static gssize
vte_unicode_strlen(gunichar *c)
#endif
}
+/* Guess at how many columns a character takes up. */
+static gssize
+vte_unichar_width(VteTerminal *terminal, gunichar c)
+{
+ gssize width;
+ width = g_unichar_isdefined(c) ? (g_unichar_iswide(c) ? 2 : 1) : -1;
+ width = CLAMP(width, 1, 2);
+ return width;
+}
+
/* Avoid driving myself nuts on the differing semantics of Pango and PangoX. */
static PangoContext *
vte_terminal_get_pango_context(VteTerminal *terminal)
(long)c,
c < 256 ? c : ' ',
screen->defaults.fore, screen->defaults.back,
- vte_unichar_width(c),
+ vte_unichar_width(terminal, c),
(long)screen->insert_delta);
}
#endif
/* Figure out how many columns this character should occupy. */
if (forced_width == -1) {
- columns = vte_unichar_width(c);
- if (columns < 0) {
- g_warning(_("Character 0x%x is undefined, allocating "
- "one column."), c);
- columns = 1;
- }
+ columns = vte_unichar_width(terminal, c);
} else {
columns = forced_width;
}
if (terminal->pvt->pty_master != -1) {
_vte_buffer_append(terminal->pvt->outgoing,
obufptr, obuf - obufptr);
+#ifdef VTE_DEBUG
+ if (_vte_debug_on(VTE_DEBUG_KEYBOARD)) {
+ while (obufptr < obuf) {
+ if ((((guint8) obufptr[0]) < 32) ||
+ (((guint8) obufptr[0]) > 127)) {
+ fprintf(stderr,
+ "Sending <%02x> "
+ "to child.\n",
+ obufptr[0]);
+ } else {
+ fprintf(stderr,
+ "Sending '%c' "
+ "to child.\n",
+ obufptr[0]);
+ }
+ obufptr++;
+ }
+ }
+#endif
/* If we need to start waiting for the child pty to
* become available for writing, set that up here. */
if (terminal->pvt->pty_output == NULL) {
cy = 32 + 1 + (y / terminal->char_height);
/* Send the event to the child. */
- snprintf(buf, sizeof(buf), "%sM%c%c%c", _VTE_CAP_CSI, cb, cx, cy);
+ snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", cb, cx, cy);
vte_terminal_feed_child(terminal, buf, strlen(buf));
}
XSetForeground(display, gc, terminal->pvt->palette[fore].pixel);
switch (c) {
case 0x25ae: /* solid rectangle */
- XFillRectangle(display, drawable, gc, x, y, xright-x, ybottom-y);
+ XFillRectangle(display, drawable, gc, x, y,
+ xright - x, ybottom - y);
break;
case 95:
/* drawing a blank */
draw = ((i - x) & 1) == 0;
for (j = y; j < ybottom; j++) {
if (draw) {
- XDrawPoint(display,
- drawable,
- gc, i, j);
+ XDrawPoint(display, drawable, gc, i, j);
}
draw = !draw;
}
x +
((i - column) * column_width),
y,
- column_width,
+ item.columns * column_width,
row_height,
display,
gdrawable,
if (terminal->pvt->im_preedit != NULL) {
preedit = terminal->pvt->im_preedit;
for (i = 0; i < terminal->pvt->im_preedit_cursor; i++) {
- col += vte_unichar_width(g_utf8_get_char(preedit));
+ col += vte_unichar_width(terminal, g_utf8_get_char(preedit));
preedit = g_utf8_next_char(preedit);
}
}
#include <unistd.h>
#include <gtk/gtk.h>
#include <glib-object.h>
+#ifdef HAVE_XFT2
+#include <fontconfig/fontconfig.h>
+#endif
#include "debug.h"
#include "vte.h"
adjust_font_size(widget, data, -1);
}
+static void
+mess_with_fontconfig(void)
+{
+#ifdef HAVE_XFT2
+ /* Is this even a good idea? Probably not, since this doesn't expose
+ * these fonts to the gnome-font-properties capplet. */
+ FcInit();
+ FcConfigAppFontAddDir(NULL, DATADIR "/" PACKAGE "/fonts");
+#endif
+}
+
int
main(int argc, char **argv)
{
vte_terminal_set_emulation(VTE_TERMINAL(widget), terminal);
}
+ /* Mess with our fontconfig setup. */
+ mess_with_fontconfig();
+
/* Set the default font. */
if (font != NULL) {
vte_terminal_set_font_from_string(VTE_TERMINAL(widget), font);