#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
+#include <iconv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
len = xwcsnlen(s, length);
ret = g_malloc0((len + 1) * sizeof(wchar_t));
wcsncpy(ret, s, len);
+#ifdef VTE_DEBUG
+ fprintf(stderr, "Extracting string `%ls'.\n", ret);
+#endif
memset(&value, 0, sizeof(value));
g_value_init(&value, G_TYPE_POINTER);
const char *result, GQuark quark)
{
mbstate_t state;
- wchar_t *wpattern;
- char *tpattern;
- const char *pat;
+ char *wpattern, *wpattern_end, *tpattern;
+ iconv_t conv;
size_t wlength;
g_return_if_fail(trie != NULL);
quark = g_quark_from_string(result);
}
- wpattern = g_malloc0(sizeof(wchar_t) * (length + 1));
+ wlength = sizeof(wchar_t) * (length + 1);
+ wpattern = wpattern_end = g_malloc0(wlength + 1);
memset(&state, 0, sizeof(state));
- pat = tpattern = g_strndup(pattern, length);
- wlength = mbsrtowcs(wpattern, &pat, length, &state);
- vte_trie_addx(trie, wpattern, wlength, result, quark, 0);
+ conv = iconv_open("WCHAR_T", "UTF-8");
+ if (conv != NULL) {
+ tpattern = (char*)pattern;
+ iconv(conv, &tpattern, &length, &wpattern_end, &wlength);
+ if (length == 0) {
+ wlength = (wpattern_end - wpattern) / sizeof(wchar_t);
+ vte_trie_addx(trie, (wchar_t*)wpattern, wlength,
+ result, quark, 0);
+ }
+ iconv_close(conv);
+ }
g_free(wpattern);
- g_free(tpattern);
}
/* Check if the given pattern matches part of the given trie, returning an
const char *ret = NULL;
GQuark tmpquark;
GValueArray *valuearray;
+ GValue *value;
+ gpointer ptr;
+ int i;
valuearray = g_value_array_new(0);
if (quark == NULL) {
ret = vte_trie_matchx(trie, pattern, length, res, quark, valuearray);
if (((ret == NULL) || (ret[0] == '\0')) || (valuearray->n_values == 0)){
- g_value_array_free(valuearray);
+ if (valuearray != NULL) {
+ for (i = 0; i < valuearray->n_values; i++) {
+ value = g_value_array_get_nth(valuearray, i);
+ if (G_VALUE_HOLDS_POINTER(value)) {
+ ptr = g_value_get_pointer(value);
+ if (ptr != NULL) {
+ g_free(ptr);
+ }
+ }
+ }
+ g_value_array_free(valuearray);
+ }
*array = NULL;
} else {
*array = valuearray;
}
static void
-convert_mbstowcs(const char *i, size_t ilen, wchar_t *o, size_t *olen)
+convert_mbstowcs(const char *i, size_t ilen,
+ wchar_t *o, size_t *olen, size_t max_olen)
{
- mbstate_t state;
- memset(&state, 0, sizeof(state));
- *olen = mbsrtowcs(o, &i, ilen, &state);
+ iconv_t conv;
+ size_t outlen;
+ conv = iconv_open("WCHAR_T", "UTF-8");
+ if (conv != NULL) {
+ memset(o, 0, max_olen);
+ outlen = max_olen;
+ iconv(conv, &i, &ilen, &o, &outlen);
+ iconv_close(conv);
+ }
+ if (olen) {
+ *olen = (max_olen - outlen) / sizeof(wchar_t);
+ }
}
int
vte_trie_print(trie);
quark = 0;
- convert_mbstowcs("abc", 3, buf, &buflen);
+ convert_mbstowcs("abc", 3, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abc",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abcdef", 6, buf, &buflen);
+ convert_mbstowcs("abcdef", 6, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abcdef",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abcde", 5, buf, &buflen);
+ convert_mbstowcs("abcde", 5, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abcde",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abcdeg", 6, buf, &buflen);
+ convert_mbstowcs("abcdeg", 6, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abcdeg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abc%deg", 7, buf, &buflen);
+ convert_mbstowcs("abc%deg", 7, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abc%deg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abc10eg", 7, buf, &buflen);
+ convert_mbstowcs("abc10eg", 7, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abc10eg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abc%eg", 6, buf, &buflen);
+ convert_mbstowcs("abc%eg", 6, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abc%eg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abc%10eg", 8, buf, &buflen);
+ convert_mbstowcs("abc%10eg", 8, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abc%10eg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("abcBeg", 6, buf, &buflen);
+ convert_mbstowcs("abcBeg", 6, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "abcBeg",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("<esc>[25;26H", 12, buf, &buflen);
+ convert_mbstowcs("<esc>[25;26H", 12, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "<esc>[25;26H",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("<esc>[25;26L", 12, buf, &buflen);
+ convert_mbstowcs("<esc>[25;26L", 12, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "<esc>[25;26L",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
}
quark = 0;
- convert_mbstowcs("<esc>]2;WoofWoofh", 17, buf, &buflen);
+ convert_mbstowcs("<esc>]2;WoofWoofh", 17, buf, &buflen, sizeof(buf));
g_print("`%s' = `%s'\n", "<esc>]2;WoofWoofh",
vte_trie_match(trie, buf, buflen, NULL, &quark, &array));
g_print("=> `%s'\n", g_quark_to_string(quark));
} flags;
/* PTY handling data. */
- char *shell; /* shell we started */
+ const char *shell; /* shell we started */
int pty_master; /* pty master descriptor */
GIOChannel *pty_input; /* master input watch */
GIOChannel *pty_output; /* master output watch */
vte_terminal_im_reset(VteTerminal *terminal)
{
g_return_if_fail(VTE_IS_TERMINAL(terminal));
- gtk_im_context_reset(terminal->pvt->im_context);
- if (terminal->pvt->im_preedit != NULL) {
- g_free(terminal->pvt->im_preedit);
- terminal->pvt->im_preedit = NULL;
+ if (GTK_WIDGET_REALIZED(GTK_WIDGET(terminal))) {
+ gtk_im_context_reset(terminal->pvt->im_context);
+ if (terminal->pvt->im_preedit != NULL) {
+ g_free(terminal->pvt->im_preedit);
+ terminal->pvt->im_preedit = NULL;
+ }
}
}
static gboolean
vte_terminal_process_incoming(gpointer data)
{
- GValueArray *params;
+ GValueArray *params = NULL;
VteTerminal *terminal;
GtkWidget *widget;
GdkRectangle rect;
char *ibuf, *obuf, *obufptr, *ubuf, *ubufptr;
size_t icount, ocount, ucount;
wchar_t *wbuf, c;
- int i, j, wcount;
+ int i, j, k, wcount;
const char *match, *encoding;
iconv_t unconv;
GQuark quark;
+ GValue *value;
+ gpointer ptr;
gboolean leftovers, inserted, again, bottom;
g_return_val_if_fail(GTK_IS_WIDGET(data), FALSE);
match,
quark,
params);
- if (params != NULL) {
- g_value_array_free(params);
- }
/* Skip over the proper number of wide chars. */
i = j;
/* Check if the encoding's changed. */
g_warning("Unhandled data.\n");
}
}
+ /* Free any wide-character strings we got. */
+ if (params != NULL) {
+ for (k = 0; k < params->n_values; k++) {
+ value = g_value_array_get_nth(params,
+ k);
+ if (G_VALUE_HOLDS_POINTER(value)) {
+ ptr = g_value_get_pointer(value);
+ if (ptr != NULL) {
+ g_free(ptr);
+ }
+ g_value_set_pointer(value,
+ NULL);
+ }
+ }
+ g_value_array_free(params);
+ params = NULL;
+ }
+ }
+ /* Free any wide-character strings we got if we broke out
+ * of the loop. */
+ if (params != NULL) {
+ for (k = 0; k < params->n_values; k++) {
+ value = g_value_array_get_nth(params,
+ k);
+ if (G_VALUE_HOLDS_POINTER(value)) {
+ ptr = g_value_get_pointer(value);
+ if (ptr != NULL) {
+ g_free(ptr);
+ }
+ g_value_set_pointer(value, NULL);
+ }
+ }
+ g_value_array_free(params);
+ params = NULL;
}
}
again = TRUE;
terminal->pvt->incoming = NULL;
again = FALSE;
}
+ g_free(obufptr);
if (inserted) {
/* Keep the cursor on-screen if we scroll on output, or if
/* If we got data, modify the pending buffer. */
if (bcount >= 0) {
+ if (terminal->pvt->incoming != NULL) {
+ g_free(terminal->pvt->incoming);
+ }
terminal->pvt->incoming = buf;
terminal->pvt->n_incoming += bcount;
} else {
const char *family = "mono";
int pango_mask = 0;
int weight, style;
- double size = 12.0;
+ double size = 14.0;
if (font_desc != NULL) {
pango_mask = pango_font_description_get_set_fields (font_desc);
long width, height, ascent, descent;
GtkWidget *widget;
XFontStruct **font_struct_list, font_struct;
- char **missing_charset_list, *def_string, *tmp;
- int missing_charset_count;
- char **font_name_list;
+ char **missing_charset_list = NULL, *def_string = NULL, *tmp = NULL;
+ int missing_charset_count = 0;
+ char **font_name_list = NULL;
g_return_if_fail(terminal != NULL);
g_return_if_fail(VTE_IS_TERMINAL(terminal));
gdk_x11_get_default_screen(),
XFT_FAMILY, XftTypeString,
"mono",
- XFT_SIZE, XftTypeDouble, 12.0,
+ XFT_SIZE, XftTypeDouble, 14.0,
0);
}
if (new_font == NULL) {
if (!terminal->pvt->use_xft) {
/* Load the font set, freeing another one if we loaded one
* before. */
- if (terminal->pvt->fontset) {
+ if (terminal->pvt->fontset != NULL) {
XFreeFontSet(GDK_DISPLAY(), terminal->pvt->fontset);
}
terminal->pvt->fontset = XCreateFontSet(GDK_DISPLAY(),
struct winsize size;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
if (terminal->pvt->pty_master != -1) {
+ memset(&size, 0, sizeof(size));
size.ws_row = rows;
size.ws_col = columns;
/* Try to set the terminal size. */
/* Initialize data members with settings from the environment and
* structures to use for these. */
pvt = terminal->pvt = g_malloc0(sizeof(*terminal->pvt));
- pvt->shell = g_strdup(getenv("SHELL") ?: "/bin/sh");
+ pvt->shell = getenv("SHELL") ?: "/bin/sh";
+ pvt->shell = g_quark_to_string(g_quark_from_string(pvt->shell));
pvt->pty_master = -1;
pvt->pty_pid = -1;
pvt->incoming = NULL;
pvt->selection_end.x = 0;
pvt->selection_end.y = 0;
+ pvt->fontset = NULL;
+
#ifdef HAVE_XFT
/* Try to use Xft if the user requests it. */
+ pvt->ftfont = NULL;
pvt->use_xft = FALSE;
if (getenv("VTE_USE_XFT") != NULL) {
if (atol(getenv("VTE_USE_XFT")) != 0) {
g_object_unref(G_OBJECT(terminal->pvt->im_context));
terminal->pvt->im_context = NULL;
- /* Free the color palette. */
- ;
-
#ifdef HAVE_XFT
/* Clean up after Xft. */
display = gdk_x11_drawable_get_xdisplay(widget->window);
widget->window = gdk_window_new(gtk_widget_get_parent_window(widget),
&attributes,
attributes_mask);
+ gdk_cursor_unref(attributes.cursor);
gdk_window_move_resize(widget->window,
widget->allocation.x,
widget->allocation.y,
static void
vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent)
{
- long i;
+ long i, pixel_count;
GtkWidget *widget;
guchar *pixels, *oldpixels;
GdkColormap *colormap = NULL;
(guchar**)&prop_data);
/* If we got something, try to create a pixmap. */
+ pixbuf = NULL;
if ((prop_type == GDK_TARGET_PIXMAP) &&
(prop_data != NULL) &&
(prop_data[0] != 0)) {
gdk_error_trap_pop();
/* Save the image. */
- if (terminal->pvt->bg_transparent_image) {
+ if (terminal->pvt->bg_transparent_image != NULL) {
g_object_unref(G_OBJECT(terminal->pvt->bg_transparent_image));
}
terminal->pvt->bg_transparent_image = pixbuf;
/* Get a copy of the root image. */
if (GDK_IS_PIXBUF(terminal->pvt->bg_transparent_image)) {
- pixbuf = gdk_pixbuf_copy(terminal->pvt->bg_transparent_image);
+ if (terminal->pvt->bg_saturation != VTE_SATURATION_MAX) {
+ pixbuf = gdk_pixbuf_copy(terminal->pvt->bg_transparent_image);
+ } else {
+ pixbuf = terminal->pvt->bg_transparent_image;
+ g_object_ref(G_OBJECT(pixbuf));
+ }
}
/* Rotate the copy of the image left or up. */
if (terminal->pvt->bg_image != NULL) {
/* Set up a possibly desaturated background. Start by
* creating a copy we can mess with. */
- pixbuf = gdk_pixbuf_copy(terminal->pvt->bg_image);
+ if (terminal->pvt->bg_saturation != VTE_SATURATION_MAX) {
+ pixbuf = gdk_pixbuf_copy(terminal->pvt->bg_image);
+ } else {
+ pixbuf = terminal->pvt->bg_image;
+ g_object_ref(G_OBJECT(pixbuf));
+ }
width = gdk_pixbuf_get_width(pixbuf);
height = gdk_pixbuf_get_height(pixbuf);
}
if (GDK_IS_PIXBUF(pixbuf)) {
/* Adjust the brightness of the pixbuf. */
- pixels = gdk_pixbuf_get_pixels(pixbuf);
- i = height * gdk_pixbuf_get_rowstride(pixbuf);
- while (i >= 0) {
- pixels[i] = pixels[i]
- * terminal->pvt->bg_saturation
- / VTE_SATURATION_MAX;
- i--;
+ if (terminal->pvt->bg_saturation != VTE_SATURATION_MAX) {
+ pixels = gdk_pixbuf_get_pixels(pixbuf);
+ pixel_count = height * gdk_pixbuf_get_rowstride(pixbuf);
+ for (i = 0; i < pixel_count; i++) {
+ pixels[i] = pixels[i]
+ * terminal->pvt->bg_saturation
+ / VTE_SATURATION_MAX;
+ }
}
/* Render the modified image into a pixmap/bitmap pair. */
&bitmap,
0);
- /* Set the pixmap as the window background. */
- gdk_window_set_back_pixmap(widget->window, pixmap, FALSE);
-
- /* Get rid of the pixbuf and bitmap, which are not useful. */
+ /* Get rid of the pixbuf, which is no longer useful. */
g_object_unref(G_OBJECT(pixbuf));
+ pixbuf = NULL;
+
+ /* Set the pixmap as the window background, and then get rid
+ * of it. */
if (GDK_IS_PIXMAP(pixmap)) {
+ /* Set the pixmap as the window background. */
+ gdk_window_set_back_pixmap(widget->window,
+ pixmap,
+ FALSE);
g_object_unref(G_OBJECT(pixmap));
+ pixmap = NULL;
}
- if (bitmap != NULL) {
+ if (GDK_IS_DRAWABLE(bitmap)) {
g_object_unref(G_OBJECT(bitmap));
+ bitmap = NULL;
}
}
GdkPixbuf *image;
GError *error = NULL;
g_return_if_fail(VTE_IS_TERMINAL(terminal));
- image = gdk_pixbuf_new_from_file(path, &error);
- if ((image != NULL) && (error == NULL)) {
- vte_terminal_set_background_image(terminal, image);
- g_object_unref(G_OBJECT(image));
+ if (path != NULL) {
+ image = gdk_pixbuf_new_from_file(path, &error);
+ if ((image != NULL) && (error == NULL)) {
+ vte_terminal_set_background_image(terminal, image);
+ g_object_unref(G_OBJECT(image));
+ } else {
+ /* FIXME: do something better with the error. */
+ vte_terminal_set_background_image(terminal, NULL);
+ g_error_free(error);
+ }
} else {
- /* FIXME: do something better with the error. */
- g_error_free(error);
+ /* gnome terminal crackrock */
+ vte_terminal_set_background_image(terminal, NULL);
}
}