diff options
Diffstat (limited to 'gui/greeter/greeter_canvas_item.c')
-rw-r--r-- | gui/greeter/greeter_canvas_item.c | 773 |
1 files changed, 0 insertions, 773 deletions
diff --git a/gui/greeter/greeter_canvas_item.c b/gui/greeter/greeter_canvas_item.c deleted file mode 100644 index e038b783..00000000 --- a/gui/greeter/greeter_canvas_item.c +++ /dev/null @@ -1,773 +0,0 @@ -/* GDM - The GNOME Display Manager - * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" - -#include <math.h> -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <librsvg/rsvg.h> - -#include "gdm.h" -#include "gdmcommon.h" -#include "gdmconfig.h" - -#include "gdm-common.h" -#include "gdm-daemon-config-keys.h" - -#include "greeter.h" -#include "greeter_item.h" -#include "greeter_events.h" -#include "greeter_system.h" -#include "greeter_canvas_item.h" -#include "greeter_configuration.h" -#include "greeter_canvas_text.h" -#include "greeter_parser.h" - -/* Keep track of buttons so they can be set sensitive/insensitive */ -GtkButton *gtk_ok_button = NULL; -GtkButton *gtk_start_again_button = NULL; - -static void -apply_tint (GdkPixbuf *pixbuf, guint32 tint_color) -{ - guchar *pixels; - guint r, g, b; - gboolean has_alpha; - guint w, h, stride; - guint pixel_stride; - guchar *line; - int i; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); - - r = (tint_color & 0xff0000) >> 16; - g = (tint_color & 0x00ff00) >> 8; - b = (tint_color & 0x0000ff); - - w = gdk_pixbuf_get_width (pixbuf); - h = gdk_pixbuf_get_height (pixbuf); - stride = gdk_pixbuf_get_rowstride (pixbuf); - - pixel_stride = (has_alpha) ? 4 : 3; - - while (h-->0) - { - line = pixels; - - for (i = 0; i < w; i++) - { - line[0] = line[0] * r / 0xff; - line[1] = line[1] * g / 0xff; - line[2] = line[2] * b / 0xff; - line += pixel_stride; - } - - pixels += stride; - } -} - -static GdkPixbuf * -transform_pixbuf (GdkPixbuf *orig, - gboolean has_tint, guint32 tint_color, - double alpha, gint width, gint height) -{ - GdkPixbuf *scaled; - gint p_width, p_height; - - p_width = gdk_pixbuf_get_width (orig); - p_height = gdk_pixbuf_get_height (orig); - - if (p_width != width || - p_height != height || - alpha < 1.0 || - has_tint) - { - int alpha_i; - - if (alpha >= 1.0) - alpha_i = 0xff; - else if (alpha <= 0.0) - alpha_i = 0; - else - alpha_i = (guint) floor (0xff*alpha); - if (alpha != 0xff) - { - scaled = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); - gdk_pixbuf_fill (scaled, 0); - gdk_pixbuf_composite (orig, scaled, 0, 0, width, height, - 0, 0, (double)width/p_width, (double)height/p_height, - GDK_INTERP_BILINEAR, alpha_i); - } - else - scaled = gdk_pixbuf_scale_simple (orig, width, height, GDK_INTERP_BILINEAR); - } - else - scaled = g_object_ref (orig); - - if (has_tint) - apply_tint (scaled, tint_color); - - return scaled; -} - -static void -activate_button (GtkWidget *widget, gpointer data) -{ - const char *id = data; - if (id != NULL) - greeter_item_run_action_callback (id); -} - -static void -menubar_done (GtkMenuShell *menushell, gpointer data) -{ - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; - - gtk_widget_grab_focus (entry); -} - -static GtkWidget * -make_menubar (void) -{ - GtkWidget *w, *menu; - GtkWidget *menubar = gtk_menu_bar_new (); - - /* FIXME: add translatable string here */ - w = gtk_menu_item_new_with_label ("Menu"); - gtk_menu_shell_append (GTK_MENU_SHELL (menubar), w); - gtk_widget_show (GTK_WIDGET (w)); - - menu = gtk_menu_new (); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (w), menu); - - w = gtk_menu_item_new_with_mnemonic (_("Select _Language...")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); - gtk_widget_show (GTK_WIDGET (w)); - g_signal_connect (G_OBJECT (w), "activate", - G_CALLBACK (activate_button), - "language_button"); - - w = gtk_menu_item_new_with_mnemonic (_("Select _Session...")); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); - gtk_widget_show (GTK_WIDGET (w)); - g_signal_connect (G_OBJECT (w), "activate", - G_CALLBACK (activate_button), - "session_button"); - - greeter_system_append_system_menu (menu); - - /* Add a quit/disconnect item when in xdmcp mode or flexi mode */ - /* Do note that the order is important, we always want "Quit" for - * flexi, even if not local (non-local xnest). and Disconnect - * only for xdmcp */ - if ( ! ve_string_empty (g_getenv ("GDM_FLEXI_SERVER"))) { - w = gtk_menu_item_new_with_mnemonic (_("_Quit")); - } else if (ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) { - w = gtk_menu_item_new_with_mnemonic (_("D_isconnect")); - } else { - w = NULL; - } - if (w != NULL) { - GtkWidget *sep; - /* add separator before the quit */ - sep = gtk_separator_menu_item_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), sep); - gtk_widget_show (GTK_WIDGET (sep)); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), w); - gtk_widget_show (GTK_WIDGET (w)); - g_signal_connect (G_OBJECT (w), "activate", - G_CALLBACK (gtk_main_quit), NULL); - } - - g_signal_connect (G_OBJECT(gtk_menu_item_get_submenu( - gtk_container_get_children(GTK_CONTAINER(menubar))->data)), "selection-done", G_CALLBACK (menubar_done), NULL); - - return menubar; -} - -static void -get_gdk_color_from_rgb (GdkColor *c, guint32 rgb) -{ - c->red = ((rgb & 0xff0000) >> 16) * 0x101; - c->green = ((rgb & 0xff00) >> 8) * 0x101; - c->blue = (rgb & 0xff) * 0x101; - c->pixel = 0; -} - -static void -menu_position_func (GtkMenu *menu, - int *x, - int *y, - gboolean *push_in, - GreeterItemInfo *item) -{ - GtkAllocation rect; - GtkRequisition requisition; - - rect = item->allocation; - gtk_widget_size_request (GTK_WIDGET (menu), &requisition); - *x = rect.x; - if (requisition.height <= rect.y) - *y = rect.y - requisition.height; - else - *y = rect.y + rect.height; - - *push_in = TRUE; -} - -/* - * The button with this handler never appears in the F10 menu, so - * it can make use of callback data. - */ -static void -greeter_options_handler (GreeterItemInfo *item, GtkWidget *menubar) -{ - gtk_menu_popup (GTK_MENU(gtk_menu_item_get_submenu( - gtk_container_get_children(GTK_CONTAINER(menubar))->data)), - NULL, NULL, (GtkMenuPositionFunc)menu_position_func, - item, 0, gtk_get_current_event_time()); -} - -static void -greeter_item_run_button_action_callback (GtkButton *button, const char *id) -{ - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; - - greeter_item_run_action_callback (id); - gtk_widget_grab_focus (entry); -} - -void -greeter_item_create_canvas_item (GreeterItemInfo *item) -{ - GnomeCanvasGroup *group; - GtkJustification just; - GtkWidget *entry; - GtkWidget *gtkbutton; - GtkWidget *list; - GtkWidget *swin; - double x1, y1, x2, y2; - int i; - GtkAllocation rect; - char *text; - GtkTooltips *tooltips; - char *num_locale; - GdkColor c; - - if (item->item != NULL) - return; - - if ( ! greeter_item_is_visible (item)) - return; - - g_assert (item->parent->group_item); - - if (item->fixed_children != NULL || - item->box_children != NULL) - { - item->group_item = - (GnomeCanvasGroup *)gnome_canvas_item_new (item->parent->group_item, - GNOME_TYPE_CANVAS_GROUP, - "x", (gdouble) 0.0, - "y", (gdouble) 0.0, - NULL); - group = item->group_item; - } - else - group = item->parent->group_item; - - rect = item->allocation; - - - x1 = (gdouble) rect.x; - y1 = (gdouble) rect.y; - x2 = (gdouble) rect.x + rect.width; - y2 = (gdouble) rect.y + rect.height; - - switch (item->item_type) { - case GREETER_ITEM_TYPE_RECT: - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_RECT, - "x1", x1, - "y1", y1, - "x2", x2, - "y2", y2, - "fill_color_rgba", item->data.rect.colors[GREETER_ITEM_STATE_NORMAL], - NULL); - break; - case GREETER_ITEM_TYPE_SVG: - num_locale = g_strdup (setlocale (LC_NUMERIC, NULL)); - setlocale (LC_NUMERIC, "C"); - for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) - { - if (item->data.pixmap.files[i] != NULL) - { - if (i > 0 && - item->data.pixmap.files[0] != NULL && - item->data.pixmap.pixbufs[0] != NULL && - strcmp (item->data.pixmap.files[0], item->data.pixmap.files[i]) == 0) - item->data.pixmap.pixbufs[i] = g_object_ref (item->data.pixmap.pixbufs[0]); - else - item->data.pixmap.pixbufs[i] = - gdk_pixbuf_new_from_file_at_size (item->data.pixmap.files[i], rect.width, rect.height, NULL); - } - else - item->data.pixmap.pixbufs[i] = NULL; - } - setlocale (LC_NUMERIC, num_locale); - g_free (num_locale); - num_locale = NULL; - - /* Fall through */ - case GREETER_ITEM_TYPE_PIXMAP: - for (i = 0; i < GREETER_ITEM_STATE_MAX; i++) - { - GdkPixbuf *pb = item->data.pixmap.pixbufs[i]; - if (pb != NULL) - { - item->data.pixmap.pixbufs[i] = - transform_pixbuf (pb, - (item->data.pixmap.have_tint & (1<<i)), item->data.pixmap.tints[i], - (double)item->data.pixmap.alphas[i] / 256.0, rect.width, rect.height); - g_object_unref (pb); - } - } - - if (item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL] != NULL) - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_PIXBUF, - "x", (gdouble) x1, - "y", (gdouble) y1, - "pixbuf", item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL], - NULL); - break; - case GREETER_ITEM_TYPE_LABEL: - text = gdm_common_expand_text (item->data.text.orig_text); - - /* Justification is taken from the anchor */ - if (item->anchor == GTK_ANCHOR_NORTH_WEST || - item->anchor == GTK_ANCHOR_SOUTH_WEST || - item->anchor == GTK_ANCHOR_WEST) - just = GTK_JUSTIFY_LEFT; - else if (item->anchor == GTK_ANCHOR_NORTH_EAST || - item->anchor == GTK_ANCHOR_SOUTH_EAST || - item->anchor == GTK_ANCHOR_EAST) - just = GTK_JUSTIFY_RIGHT; - else - just = GTK_JUSTIFY_CENTER; - - item->item = gnome_canvas_item_new (group, - GREETER_TYPE_CANVAS_TEXT, - "text", "", - "x", x1, - "y", y1, - "anchor", item->anchor, - "font_desc", item->data.text.fonts[GREETER_ITEM_STATE_NORMAL], - "fill_color_rgba", item->data.text.colors[GREETER_ITEM_STATE_NORMAL], - "justification", just, - NULL); - - greeter_canvas_item_break_set_string (item, - text, - TRUE /* markup */, - item->data.text.real_max_width, - NULL /* width */, - NULL /* height */, - NULL /* canvas */, - item->item); - g_free (text); - - /* if there is an accelerator we do an INCREDIBLE hack */ - if (strchr (item->data.text.orig_text, '_') != NULL) - { - GreeterItemInfo *button; - GtkWidget *fake_button = gtk_button_new_with_mnemonic (item->data.text.orig_text); - gtk_widget_show (fake_button); - GTK_WIDGET_UNSET_FLAGS (fake_button, GTK_CAN_FOCUS); - gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)), - GNOME_TYPE_CANVAS_WIDGET, - "widget", fake_button, - "x", (double)-999.0, - "y", (double)-999.0, - "height", (double)20.0, - "width", (double)20.0, - NULL); - button = item->my_button; - if (button == NULL) - button = item; - g_signal_connect_data (G_OBJECT (fake_button), "clicked", - G_CALLBACK (activate_button), - g_strdup (button->id), - (GClosureNotify)g_free, - 0 /* connect_flags */); - } - - break; - - case GREETER_ITEM_TYPE_BUTTON: - gtkbutton = gtk_button_new_with_mnemonic (item->data.text.orig_text); - gtk_widget_set_name (gtkbutton, item->id); - if (strcmp (ve_sure_string (item->id), "ok_button") == 0) { - gtk_ok_button = GTK_BUTTON (gtkbutton); - } else if (strcmp (ve_sure_string (item->id), "cancel_button") == 0) { - gtk_start_again_button = GTK_BUTTON (gtkbutton); - } - - g_signal_connect (G_OBJECT (gtkbutton), "clicked", - G_CALLBACK (greeter_item_run_button_action_callback), - item->id); - - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_WIDGET, - "widget", gtkbutton, - "x", x1, - "y", y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); - - break; - - case GREETER_ITEM_TYPE_ENTRY: - entry = gtk_entry_new (); - gtk_widget_set_name (entry, "user-pw-entry"); - gtk_entry_set_has_frame (GTK_ENTRY (entry), FALSE); - - if (gdm_config_get_bool (GDM_KEY_ENTRY_INVISIBLE)) - gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0); - else if (gdm_config_get_bool (GDM_KEY_ENTRY_CIRCLES)) - gtk_entry_set_invisible_char (GTK_ENTRY (entry), 0x25cf); - - gtk_widget_modify_font (entry, item->data.text.fonts[GREETER_ITEM_STATE_NORMAL]); - - get_gdk_color_from_rgb (&c, item->data.text.colors[GREETER_ITEM_STATE_NORMAL]); - gtk_widget_modify_text (entry, GTK_STATE_NORMAL, &c); - - if (item->id != NULL && strcmp (item->id, "user-pw-entry") == 0) { - /* HACK! Add a menubar, this is kind of evil isn't it, - * should probably be done in the pam item setup thingie. - * but this is really widget kind of thing. I dunno where - * this belongs but it's a hack here. */ - GtkWidget *menubar = make_menubar (); - - gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (canvas)), - GNOME_TYPE_CANVAS_WIDGET, - "widget", menubar, - "x", (double)x1, - "y", (double)y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); - - greeter_item_register_action_callback ("options_button", - (ActionFunc)greeter_options_handler, - menubar); - - /* Here add a tooltip, so that the user knows about F10 */ - tooltips = gtk_tooltips_new (); - gtk_tooltips_set_tip (tooltips, GTK_WIDGET (entry), - _("Answer questions here and press Enter " - "when done. For a menu press F10."), - NULL); - - /* FIXME: how to make this accessible??? */ - } - - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_WIDGET, - "widget", entry, - "x", x1, - "y", y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); - - /* cursor blinking is evil on remote displays, don't do it forever */ - gdm_common_setup_blinking_entry (entry); - - break; - - case GREETER_ITEM_TYPE_LIST: - /* Note a list type must be setup later and we will add the list store - * to it then, depending on the type. Likely userlist is the - * only type we support */ - - if (item->data.list.combo_type) { - list = gtk_combo_box_new_text (); - - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_WIDGET, - "widget", list, - "x", x1, - "y", y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); - } else { - list = gtk_tree_view_new (); - - swin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), - GTK_SHADOW_NONE); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_container_add (GTK_CONTAINER (swin), list); - - item->item = gnome_canvas_item_new (group, - GNOME_TYPE_CANVAS_WIDGET, - "widget", swin, - "x", x1, - "y", y1, - "height", (double)rect.height, - "width", (double)rect.width, - NULL); - } - - break; - } - - if (item->item_type == GREETER_ITEM_TYPE_RECT || - item->item_type == GREETER_ITEM_TYPE_SVG || - item->item_type == GREETER_ITEM_TYPE_PIXMAP || - item->item_type == GREETER_ITEM_TYPE_LABEL) - g_signal_connect (G_OBJECT (item->item), "event", - G_CALLBACK (greeter_item_event_handler), - item); -} - -/* This is so evil it hurts */ -static char * -make_ugly_long_string_with_line_breaks (const char *orig) -{ - const char *p; - int n_chars, i; - GString *foo = g_string_new (NULL); - gboolean in_element = FALSE; - - n_chars = g_utf8_strlen (orig, -1); - p = orig; - - i = 0; - while (i < n_chars) { - gunichar ch = g_utf8_get_char (p); - if (ch == '<') - in_element = TRUE; - else if (ch == '>') - in_element = FALSE; - g_string_append_unichar (foo, ch); - if ( ! in_element) - g_string_append_unichar (foo, '\n'); - p = g_utf8_next_char (p); - i++; - } - - return g_string_free (foo, FALSE); -} - -/* This function is very VERY evil */ -static gboolean -append_word (GString *str, GString *line, GString *word, const char *after, int max_width, const char *textattr, GnomeCanvasItem *canvas_item) -{ - int width, height; - char *post = make_ugly_long_string_with_line_breaks (after); - char *try = g_strconcat (str->str, word->str, "\n", post, NULL); - g_free (post); - gnome_canvas_item_set (GNOME_CANVAS_ITEM (canvas_item), textattr, try, NULL); - g_free (try); - - pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (canvas_item)->layout, &width, &height); - - if (width > max_width) { - if ( ! ve_string_empty (line->str)) { - if (str->len > 0 && - str->str[str->len-1] == ' ') { - g_string_truncate (str, str->len-1); - } - g_string_append_unichar (str, '\n'); - } - g_string_assign (line, word->str); - g_string_append (str, word->str); - g_string_assign (word, ""); - - return TRUE; - } else { - g_string_append (line, word->str); - g_string_append (str, word->str); - g_string_assign (word, ""); - - return FALSE; - } -} - -/* This function is very VERY evil */ -/* Note that it should just use pango and do all the right things rather then - the utter hacks it tries to do. But I couldn't figure out how to do this - simply with pango and how to interact with markup properly (it seems easy - to do if there is no markup */ -void -greeter_canvas_item_break_set_string (GreeterItemInfo *info, - const char *orig, - gboolean markup, - int max_width, - int *width, - int *height, - GnomeCanvas *canvas, - GnomeCanvasItem *real_item) -{ - PangoLogAttr *attrs; - int n_chars; - GString *str; - GString *word; - GString *line; - int i; - int n_attrs; - int ia; - const char *p; - int in_current_row; - GnomeCanvasItem *canvas_item; - const char *textattr; - int lwidth, lheight; - - str = g_string_new (NULL); - word = g_string_new (NULL); - line = g_string_new (NULL); - - /* avoid errors and even possible crashes */ - if (markup && ! pango_parse_markup (orig, -1, 0, NULL, NULL, NULL, NULL)) { - markup = FALSE; - } - - textattr = markup ? "markup" : "text"; - - /* A gross hack */ - if (real_item != NULL) - canvas_item = real_item; - else - canvas_item = gnome_canvas_item_new (gnome_canvas_root (canvas), - GREETER_TYPE_CANVAS_TEXT, - textattr, "", - "x", 0.0, - "y", 0.0, - "font_desc", info->data.text.fonts[GREETER_ITEM_STATE_NORMAL], - NULL); - - if (max_width == 0) { - gnome_canvas_item_set (GNOME_CANVAS_ITEM (canvas_item), textattr, orig, NULL); - pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (canvas_item)->layout, width, height); - - if (real_item != canvas_item) { - gtk_object_destroy (GTK_OBJECT (canvas_item)); - g_string_free (line, TRUE); - g_string_free (word, TRUE); - g_string_free (str, TRUE); - } - return; - } - - n_chars = g_utf8_strlen (orig, -1); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (canvas_item), textattr, orig, NULL); - pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (canvas_item)->layout, &lwidth, &lheight); - if (lwidth <= max_width) { - if (width != NULL) - *width = lwidth; - if (height != NULL) - *height = lheight; - if (real_item != canvas_item) { - gtk_object_destroy (GTK_OBJECT (canvas_item)); - g_string_free (line, TRUE); - g_string_free (word, TRUE); - g_string_free (str, TRUE); - } - return; - } - - pango_layout_get_log_attrs (GNOME_CANVAS_TEXT (canvas_item)->layout, &attrs, &n_attrs); - - i = 0; - ia = 0; - in_current_row = 0; - p = orig; - while (i < n_chars) { - gunichar ch; - - ch = g_utf8_get_char (p); - - if (markup && ch == '<') { - while (i < n_chars) { - g_string_append_unichar (word, ch); - p = g_utf8_next_char (p); - i++; - - if (ch == '>') { - ch = g_utf8_get_char (p); - break; - } else { - ch = g_utf8_get_char (p); - } - } - if (i >= n_chars) - break; - } - - if (attrs[ia].is_line_break && in_current_row > 0) { - if (append_word (str, line, word, p, max_width, textattr, canvas_item)) - in_current_row = 0; - } - - in_current_row++; - g_string_append_unichar (word, ch); - - p = g_utf8_next_char (p); - i++; - ia++; - - /* eeek! */ - if (ia >= n_attrs) { - while (i < n_chars) { - ch = g_utf8_get_char (p); - g_string_append_unichar (word, ch); - p = g_utf8_next_char (p); - i++; - } - break; - } - } - - if ( ! ve_string_empty (word->str)) - append_word (str, line, word, "", max_width, textattr, canvas_item); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (canvas_item), textattr, str->str, NULL); - pango_layout_get_pixel_size (GNOME_CANVAS_TEXT (canvas_item)->layout, width, height); - - if (real_item != canvas_item) - gtk_object_destroy (GTK_OBJECT (canvas_item)); - g_free (attrs); - - g_string_free (line, TRUE); - g_string_free (word, TRUE); - - g_string_free (str, TRUE); -} - |