diff options
author | Nalin Dahyabhai <nalin@src.gnome.org> | 2002-04-25 00:49:15 +0000 |
---|---|---|
committer | Nalin Dahyabhai <nalin@src.gnome.org> | 2002-04-25 00:49:15 +0000 |
commit | b8f6f28089d5e98516b041de3aeebf34982bcb1a (patch) | |
tree | bf10395f567b35b7c90e0bed749b2910aae9083a | |
parent | 75356484dfead6c210c1fe83e912a85169bd71af (diff) |
update to-do list. remove --disable-shared. remove a memory leak. fix a
* README: update to-do list.
* autogen.sh: remove --disable-shared.
* src/pty.c: remove a memory leak.
* src/termcap.c: fix a possible read-before-start-of-buffer.
* src/trie.c: use iconv instead of mbrstowcs, even if it's just ASCII->W_CHAR_T.
* src/vte.c: fix a few memory leaks; only reset the IM context when we're realized, which is the only time we actually have an IM context; don't create a copy of a pixbuf if we don't need to desaturate it, just ref it and use it directly.
-rw-r--r-- | README | 2 | ||||
-rwxr-xr-x | autogen.sh | 2 | ||||
-rw-r--r-- | src/pty.c | 1 | ||||
-rw-r--r-- | src/termcap.c | 2 | ||||
-rw-r--r-- | src/trie.c | 85 | ||||
-rw-r--r-- | src/vte.c | 151 |
6 files changed, 173 insertions, 70 deletions
@@ -34,5 +34,5 @@ things is currently scarce, so some of it's guesswork. - An actual property interface needs to be retrofitted over the various options which are currently hard-coded at startup-time. -- Input method support isn't started yet. +- Accessibility isn't started yet. - Mouse tracking isn't started yet. @@ -9,4 +9,4 @@ autoconf if test -f config.cache ; then rm -f config.cache fi -./configure --disable-shared --enable-maintainer-mode $@ +./configure $@ @@ -196,6 +196,7 @@ vte_pty_open_unix98(pid_t *child, const char **env_add, close(fd); fd = -1; } + g_free(buf); } } return fd; diff --git a/src/termcap.c b/src/termcap.c index e7fcd19..6096f79 100644 --- a/src/termcap.c +++ b/src/termcap.c @@ -112,7 +112,7 @@ nextline_with_continuation(FILE *fp) g_free(s); ret = tmp; rlen += slen; - if (ret[rlen - 1] == '\\') { + if ((rlen > 0) && (ret[rlen - 1] == '\\')) { ret[rlen - 1] = '\0'; rlen--; continuation = TRUE; @@ -21,6 +21,7 @@ #include <sys/types.h> #include <assert.h> #include <ctype.h> +#include <iconv.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -269,6 +270,9 @@ char_class_string_extract(const wchar_t *s, size_t length, 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); @@ -434,9 +438,8 @@ vte_trie_add(struct vte_trie *trie, const char *pattern, size_t length, 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); @@ -447,15 +450,23 @@ vte_trie_add(struct vte_trie *trie, const char *pattern, size_t length, 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 @@ -581,6 +592,9 @@ vte_trie_match(struct vte_trie *trie, wchar_t *pattern, size_t length, const char *ret = NULL; GQuark tmpquark; GValueArray *valuearray; + GValue *value; + gpointer ptr; + int i; valuearray = g_value_array_new(0); if (quark == NULL) { @@ -591,7 +605,18 @@ vte_trie_match(struct vte_trie *trie, wchar_t *pattern, size_t length, 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; @@ -696,11 +721,21 @@ dump_array(GValueArray *array) } 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 @@ -738,7 +773,7 @@ main(int argc, char **argv) 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)); @@ -749,7 +784,7 @@ main(int argc, char **argv) } 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)); @@ -760,7 +795,7 @@ main(int argc, char **argv) } 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)); @@ -771,7 +806,7 @@ main(int argc, char **argv) } 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)); @@ -782,7 +817,7 @@ main(int argc, char **argv) } 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)); @@ -793,7 +828,7 @@ main(int argc, char **argv) } 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)); @@ -804,7 +839,7 @@ main(int argc, char **argv) } 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)); @@ -815,7 +850,7 @@ main(int argc, char **argv) } 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)); @@ -826,7 +861,7 @@ main(int argc, char **argv) } 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)); @@ -837,7 +872,7 @@ main(int argc, char **argv) } 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)); @@ -848,7 +883,7 @@ main(int argc, char **argv) } 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)); @@ -858,7 +893,7 @@ main(int argc, char **argv) } 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)); @@ -100,7 +100,7 @@ struct _VteTerminalPrivate { } 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 */ @@ -3162,10 +3162,12 @@ static void 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; + } } } @@ -3174,17 +3176,19 @@ vte_terminal_im_reset(VteTerminal *terminal) 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); @@ -3308,9 +3312,6 @@ vte_terminal_process_incoming(gpointer data) 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. */ @@ -3329,6 +3330,40 @@ vte_terminal_process_incoming(gpointer data) 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; @@ -3374,6 +3409,7 @@ vte_terminal_process_incoming(gpointer data) terminal->pvt->incoming = NULL; again = FALSE; } + g_free(obufptr); if (inserted) { /* Keep the cursor on-screen if we scroll on output, or if @@ -3481,6 +3517,9 @@ vte_terminal_io_read(GIOChannel *channel, /* 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 { @@ -4550,7 +4589,7 @@ xft_pattern_from_pango_font_description(const PangoFontDescription *font_desc) 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); @@ -4596,9 +4635,9 @@ vte_terminal_setup_font(VteTerminal *terminal, const char *xlfds, 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)); @@ -4698,7 +4737,7 @@ vte_terminal_setup_font(VteTerminal *terminal, const char *xlfds, gdk_x11_get_default_screen(), XFT_FAMILY, XftTypeString, "mono", - XFT_SIZE, XftTypeDouble, 12.0, + XFT_SIZE, XftTypeDouble, 14.0, 0); } if (new_font == NULL) { @@ -4747,7 +4786,7 @@ vte_terminal_setup_font(VteTerminal *terminal, const char *xlfds, 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(), @@ -4854,6 +4893,7 @@ vte_terminal_set_size(VteTerminal *terminal, long columns, long rows) 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. */ @@ -5059,7 +5099,8 @@ vte_terminal_init(VteTerminal *terminal) /* 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; @@ -5093,8 +5134,11 @@ vte_terminal_init(VteTerminal *terminal) 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) { @@ -5232,9 +5276,6 @@ vte_terminal_unrealize(GtkWidget *widget) 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); @@ -5418,6 +5459,7 @@ vte_terminal_realize(GtkWidget *widget) 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, @@ -6337,7 +6379,7 @@ vte_terminal_im_append_menuitems(VteTerminal *terminal, GtkMenuShell *menushell) 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; @@ -6382,6 +6424,7 @@ vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent) (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)) { @@ -6403,7 +6446,7 @@ vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent) 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; @@ -6411,7 +6454,12 @@ vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent) /* 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. */ @@ -6451,20 +6499,26 @@ vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent) 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. */ @@ -6475,16 +6529,23 @@ vte_terminal_setup_background(VteTerminal *terminal, gboolean fresh_transparent) &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; } } @@ -6535,13 +6596,19 @@ vte_terminal_set_background_image_file(VteTerminal *terminal, const char *path) 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); } } |