static gboolean gtkdial_signal_emission_hook(GSignalInvocationHint *ihint, guint n_param_values, const GValue *param_values, gpointer data) { GObject *p = G_OBJECT(g_value_peek_pointer(param_values+0)); GtkMenu *m = GTK_MENU(g_value_peek_pointer(param_values+1)); GtkClipboard *c = gtk_clipboard_get(GDK_SELECTION_PRIMARY); GObject *o = gtk_clipboard_get_owner(c); GtkTextBuffer *b = GTK_IS_TEXT_VIEW(p) ? gtk_text_view_get_buffer(GTK_TEXT_VIEW(p)) : NULL; const gchar *text = NULL; int out[3]; if (o && (p == o || (gpointer)b == o)) { /* text is local; should be fast */ text = gtk_clipboard_wait_for_text(c); } else if (GTK_IS_ENTRY(p)) { text = gtk_entry_get_text(GTK_ENTRY(p)); } else if (GTK_IS_LABEL(p)) { text = gtk_label_get_label(GTK_LABEL(p)); } if (text != NULL && pcre_exec(regexp_phone, regexp_phone_extra, text, strlen(text), 0, 0, out, 3) && out[1] > out[0]) { gchar *label; int need, len = out[1] - out[0]; const char *str = text + out[0]; free(last_phone_number); last_phone_number = NULL; if ((need = gtkdial_make_canonical(NULL, str, len)) > 1) { last_phone_number = malloc(1 + need); gtkdial_make_canonical(last_phone_number, str, len); last_phone_number[need] = '\0'; } if (last_phone_number != NULL && asprintf(&label, "Dial: %s", last_phone_number)) { GtkIconSet *icon_set = gtk_style_lookup_icon_set(gtk_widget_get_style(GTK_WIDGET(m)), "call-start"); GtkImageMenuItem *item; GtkImage *icon; if (!icon_set) { icon = GTK_IMAGE(gtk_image_new_from_file("/usr/share/icons/gnome-human/16x16/actions/call-start.png")); } else { icon = GTK_IMAGE(gtk_image_new_from_icon_set(icon_set, GTK_ICON_SIZE_MENU)); } item = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new()); gtk_image_menu_item_set_image(item, GTK_WIDGET(icon)); gtk_menu_item_set_label(GTK_MENU_ITEM(item), label); free(label); g_signal_connect(G_OBJECT(item), "activate", (void*)gtkdial_doit, NULL); gtk_widget_show(GTK_WIDGET(item)); gtk_menu_prepend(m, GTK_WIDGET(item)); } } return TRUE; }
nsresult nsIconChannel::Init(nsIURI* aURI) { nsCOMPtr<nsIMozIconURI> iconURI = do_QueryInterface(aURI); NS_ASSERTION(iconURI, "URI is not an nsIMozIconURI"); nsCAutoString stockIcon; iconURI->GetStockIcon(stockIcon); if (stockIcon.IsEmpty()) { #ifdef MOZ_ENABLE_GNOMEUI return InitWithGnome(iconURI); #else #ifdef MOZ_ENABLE_GIO return InitWithGIO(iconURI); #else return NS_ERROR_NOT_AVAILABLE; #endif #endif } // Search for stockIcon nsCAutoString iconSizeString; iconURI->GetIconSize(iconSizeString); nsCAutoString iconStateString; iconURI->GetIconState(iconStateString); GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get()); GtkStateType state = iconStateString.EqualsLiteral("disabled") ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL; // First lookup the icon by stock id and text direction. GtkTextDirection direction = GTK_TEXT_DIR_NONE; if (StringEndsWith(stockIcon, NS_LITERAL_CSTRING("-ltr"))) { direction = GTK_TEXT_DIR_LTR; } else if (StringEndsWith(stockIcon, NS_LITERAL_CSTRING("-rtl"))) { direction = GTK_TEXT_DIR_RTL; } bool forceDirection = direction != GTK_TEXT_DIR_NONE; nsCAutoString stockID; bool useIconName = false; if (!forceDirection) { direction = gtk_widget_get_default_direction(); stockID = stockIcon; } else { // GTK versions < 2.22 use icon names from concatenating stock id with // -(rtl|ltr), which is how the moz-icon stock name is interpreted here. stockID = Substring(stockIcon, 0, stockIcon.Length() - 4); // However, if we lookup bidi icons by the stock name, then GTK versions // >= 2.22 will use a bidi lookup convention that most icon themes do not // yet follow. Therefore, we first check to see if the theme supports the // old icon name as this will have bidi support (if found). GtkIconTheme *icon_theme = gtk_icon_theme_get_default(); // Micking what gtk_icon_set_render_icon does with sizes, though it's not // critical as icons will be scaled to suit size. It just means we follow // the same pathes and so share caches. gint width, height; if (gtk_icon_size_lookup(icon_size, &width, &height)) { gint size = NS_MIN(width, height); // We use gtk_icon_theme_lookup_icon() without // GTK_ICON_LOOKUP_USE_BUILTIN instead of gtk_icon_theme_has_icon() so // we don't pick up fallback icons added by distributions for backward // compatibility. GtkIconInfo *icon = gtk_icon_theme_lookup_icon(icon_theme, stockIcon.get(), size, (GtkIconLookupFlags)0); if (icon) { useIconName = true; gtk_icon_info_free(icon); } } } ensure_stock_image_widget(); GtkStyle *style = gtk_widget_get_style(gStockImageWidget); GtkIconSet *icon_set = NULL; if (!useIconName) { icon_set = gtk_style_lookup_icon_set(style, stockID.get()); } if (!icon_set) { // Either we have choosen icon-name lookup for a bidi icon, or stockIcon is // not a stock id so we assume it is an icon name. useIconName = true; // Creating a GtkIconSet is a convenient way to allow the style to // render the icon, possibly with variations suitable for insensitive // states. icon_set = gtk_icon_set_new(); GtkIconSource *icon_source = gtk_icon_source_new(); gtk_icon_source_set_icon_name(icon_source, stockIcon.get()); gtk_icon_set_add_source(icon_set, icon_source); gtk_icon_source_free(icon_source); } GdkPixbuf *icon = gtk_icon_set_render_icon (icon_set, style, direction, state, icon_size, gStockImageWidget, NULL); if (useIconName) { gtk_icon_set_unref(icon_set); } // According to documentation, gtk_icon_set_render_icon() never returns // NULL, but it does return NULL when we have the problem reported here: // https://bugzilla.gnome.org/show_bug.cgi?id=629878#c13 if (!icon) return NS_ERROR_NOT_AVAILABLE; nsresult rv = moz_gdk_pixbuf_to_channel(icon, iconURI, getter_AddRefs(mRealChannel)); g_object_unref(icon); return rv; }
GtkIconSize gimp_get_icon_size (GtkWidget *widget, const gchar *stock_id, GtkIconSize max_size, gint width, gint height) { GtkIconSet *icon_set; GtkIconSize *sizes; gint n_sizes; gint i; gint width_diff = 1024; gint height_diff = 1024; gint max_width; gint max_height; GtkIconSize icon_size = GTK_ICON_SIZE_MENU; GtkSettings *settings; g_return_val_if_fail (GTK_IS_WIDGET (widget), icon_size); g_return_val_if_fail (stock_id != NULL, icon_size); g_return_val_if_fail (width > 0, icon_size); g_return_val_if_fail (height > 0, icon_size); icon_set = gtk_style_lookup_icon_set (gtk_widget_get_style (widget), stock_id); if (! icon_set) return GTK_ICON_SIZE_INVALID; settings = gtk_widget_get_settings (widget); if (! gtk_icon_size_lookup_for_settings (settings, max_size, &max_width, &max_height)) { max_width = 1024; max_height = 1024; } gtk_icon_set_get_sizes (icon_set, &sizes, &n_sizes); for (i = 0; i < n_sizes; i++) { gint icon_width; gint icon_height; if (gtk_icon_size_lookup_for_settings (settings, sizes[i], &icon_width, &icon_height)) { if (icon_width <= width && icon_height <= height && icon_width <= max_width && icon_height <= max_height && ((width - icon_width) < width_diff || (height - icon_height) < height_diff)) { width_diff = width - icon_width; height_diff = height - icon_height; icon_size = sizes[i]; } } } g_free (sizes); return icon_size; }