nsresult
nsIconChannel::InitWithGIO(nsIMozIconURI *aIconURI)
{
  nsresult rv;

  GIcon *icon = NULL;
  nsCOMPtr<nsIURL> fileURI;

  // Read icon content
  aIconURI->GetIconURL(getter_AddRefs(fileURI));

  // Get icon for file specified by URI
  if (fileURI) {
    bool isFile;
    nsCAutoString spec;
    fileURI->GetAsciiSpec(spec);
    if (NS_SUCCEEDED(fileURI->SchemeIs("file", &isFile)) && isFile) {
      GFile *file = g_file_new_for_uri(spec.get());
      GFileInfo *fileInfo = g_file_query_info(file,
                                              G_FILE_ATTRIBUTE_STANDARD_ICON,
                                              G_FILE_QUERY_INFO_NONE, NULL, NULL);
      g_object_unref(file);
      if (fileInfo) {
        // icon from g_content_type_get_icon doesn't need unref
        icon = g_file_info_get_icon(fileInfo);
        if (icon)
          g_object_ref(icon);
        g_object_unref(fileInfo);
      }
    }
  }
  
  // Try to get icon by using MIME type
  if (!icon) {
    nsCAutoString type;
    aIconURI->GetContentType(type);
    // Try to get MIME type from file extension by using nsIMIMEService
    if (type.IsEmpty()) {
      nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1"));
      if (ms) {
        nsCAutoString fileExt;
        aIconURI->GetFileExtension(fileExt);
        ms->GetTypeFromExtension(fileExt, type);
      }
    }
    char *ctype = NULL; // character representation of content type
    if (!type.IsEmpty()) {
      ctype = g_content_type_from_mime_type(type.get());
    }
    if (ctype) {
      icon = g_content_type_get_icon(ctype);
      g_free(ctype);
    }
  }

  // Get default icon theme
  GtkIconTheme *iconTheme = gtk_icon_theme_get_default();  
  GtkIconInfo *iconInfo = NULL;
  // Get icon size
  PRInt32 iconSize = GetIconSize(aIconURI);

  if (icon) {
    NS_SUCCEEDED(rv);

    // Use icon and theme to get GtkIconInfo
    iconInfo = gtk_icon_theme_lookup_by_gicon(iconTheme,
                                              icon, iconSize,
                                              (GtkIconLookupFlags)0);
    g_object_unref(icon);
  }
  
  if (!iconInfo) {
    // Mozilla's mimetype lookup failed. Try the "unknown" icon.
    iconInfo = gtk_icon_theme_lookup_icon(iconTheme,
                                          "unknown", iconSize,
                                          (GtkIconLookupFlags)0);
    if (!iconInfo) {
      return NS_ERROR_NOT_AVAILABLE;
    }
  }
  
  // Create a GdkPixbuf buffer containing icon and scale it
  GdkPixbuf* buf = gtk_icon_info_load_icon(iconInfo, NULL);
  gtk_icon_info_free(iconInfo);
  if (!buf) {
    return NS_ERROR_UNEXPECTED;
  }
  
  rv = ScaleIconBuf(&buf, iconSize);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = moz_gdk_pixbuf_to_channel(buf, aIconURI,
                                 getter_AddRefs(mRealChannel));
  g_object_unref(buf);
  return rv;
}
Example #2
0
static void
exo_cell_renderer_icon_render (GtkCellRenderer     *renderer,
                               GdkWindow           *window,
                               GtkWidget           *widget,
                               GdkRectangle        *background_area,
                               GdkRectangle        *cell_area,
                               GdkRectangle        *expose_area,
                               GtkCellRendererState flags)
{
  const ExoCellRendererIconPrivate *priv = EXO_CELL_RENDERER_ICON_GET_PRIVATE (renderer);
  GtkIconSource                    *icon_source;
  GtkIconTheme                     *icon_theme;
  GdkRectangle                      icon_area;
  GdkRectangle                      draw_area;
  GtkStateType                      state;
  const gchar                      *filename;
  GtkIconInfo                      *icon_info = NULL;
  GdkPixbuf                        *icon = NULL;
  GdkPixbuf                        *temp;
  GError                           *err = NULL;
  gchar                            *display_name = NULL;
  gint                             *icon_sizes;
  gint                              icon_size;
  gint                              n;

  /* verify that we have an icon */
  if (G_UNLIKELY (priv->icon == NULL && priv->gicon == NULL))
    return;

  /* icon may be either an image file or a named icon */
  if (priv->icon != NULL && g_path_is_absolute (priv->icon))
    {
      /* load the icon via the thumbnail database */
      icon = _exo_thumbnail_get_for_file (priv->icon, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err);
    }
  else if (priv->icon != NULL || priv->gicon != NULL)
    {
      /* determine the best icon size (GtkIconTheme is somewhat messy scaling up small icons) */
      icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));

      if (priv->icon != NULL)
        {
          icon_sizes = gtk_icon_theme_get_icon_sizes (icon_theme, priv->icon);
          for (icon_size = -1, n = 0; icon_sizes[n] != 0; ++n)
            {
              /* we can use any size if scalable, because we load the file directly */
              if (icon_sizes[n] == -1)
                icon_size = priv->size;
              else if (icon_sizes[n] > icon_size && icon_sizes[n] <= priv->size)
                icon_size = icon_sizes[n];
            }
          g_free (icon_sizes);

          /* if we don't know any icon sizes at all, the icon is probably not present */
          if (G_UNLIKELY (icon_size < 0))
            icon_size = priv->size;

          /* lookup the icon in the icon theme */
          icon_info = gtk_icon_theme_lookup_icon (icon_theme, priv->icon, icon_size, 0);
        }
      else if (priv->gicon != NULL)
        {
          icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme,
                                                      priv->gicon,
                                                      priv->size,
                                                      GTK_ICON_LOOKUP_USE_BUILTIN);
        }

      if (G_UNLIKELY (icon_info == NULL))
        return;

      /* check if we have an SVG icon here */
      filename = gtk_icon_info_get_filename (icon_info);
      if (filename != NULL && g_str_has_suffix (filename, ".svg"))
        {
          /* loading SVG icons is terribly slow, so we try to use thumbnail instead, and we use the
           * real available cell area directly here, because loading thumbnails involves scaling anyway
           * and this way we need to the thumbnail pixbuf scale only once.
           */
          icon = _exo_thumbnail_get_for_file (filename, (priv->size > 128) ? EXO_THUMBNAIL_SIZE_LARGE : EXO_THUMBNAIL_SIZE_NORMAL, &err);
        }
      else
        {
          /* regularly load the icon from the theme */
          icon = gtk_icon_info_load_icon (icon_info, &err);
        }
      gtk_icon_info_free (icon_info);
    }

  /* check if we failed */
  if (G_UNLIKELY (icon == NULL))
    {
      /* better let the user know whats going on, might be surprising otherwise */
      if (G_LIKELY (priv->icon != NULL))
        {
          display_name = g_filename_display_name (priv->icon);
        }
      else if (G_UNLIKELY (priv->gicon != NULL
                           && g_object_class_find_property (G_OBJECT_GET_CLASS (priv->gicon),
                                                            "name")))
        {
          g_object_get (priv->gicon, "name", &display_name, NULL);
        }

      if (display_name != NULL)
        {
          g_warning ("Failed to load \"%s\": %s", display_name, err->message);
          g_free (display_name);
        }

      g_error_free (err);
      return;
    }

  /* determine the real icon size */
  icon_area.width = gdk_pixbuf_get_width (icon);
  icon_area.height = gdk_pixbuf_get_height (icon);

  /* scale down the icon on-demand */
  if (G_UNLIKELY (icon_area.width > cell_area->width || icon_area.height > cell_area->height))
    {
      /* scale down to fit */
      temp = exo_gdk_pixbuf_scale_down (icon, TRUE, cell_area->width, cell_area->height);
      g_object_unref (G_OBJECT (icon));
      icon = temp;

      /* determine the icon dimensions again */
      icon_area.width = gdk_pixbuf_get_width (icon);
      icon_area.height = gdk_pixbuf_get_height (icon);
    }

  icon_area.x = cell_area->x + (cell_area->width - icon_area.width) / 2;
  icon_area.y = cell_area->y + (cell_area->height - icon_area.height) / 2;

  /* check whether the icon is affected by the expose event */
  if (gdk_rectangle_intersect (expose_area, &icon_area, &draw_area))
    {
      /* colorize the icon if we should follow the selection state */
      if ((flags & (GTK_CELL_RENDERER_SELECTED | GTK_CELL_RENDERER_PRELIT)) != 0 && priv->follow_state)
        {
          if ((flags & GTK_CELL_RENDERER_SELECTED) != 0)
            {
              state = GTK_WIDGET_HAS_FOCUS (widget) ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE;
              temp = exo_gdk_pixbuf_colorize (icon, &widget->style->base[state]);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }

          if ((flags & GTK_CELL_RENDERER_PRELIT) != 0)
            {
              temp = exo_gdk_pixbuf_spotlight (icon);
              g_object_unref (G_OBJECT (icon));
              icon = temp;
            }
        }

      /* check if we should render an insensitive icon */
      if (G_UNLIKELY (GTK_WIDGET_STATE (widget) == GTK_STATE_INSENSITIVE || !renderer->sensitive))
        {
          /* allocate an icon source */
          icon_source = gtk_icon_source_new ();
          gtk_icon_source_set_pixbuf (icon_source, icon);
          gtk_icon_source_set_size_wildcarded (icon_source, FALSE);
          gtk_icon_source_set_size (icon_source, GTK_ICON_SIZE_SMALL_TOOLBAR);

          /* render the insensitive icon */
          temp = gtk_style_render_icon (widget->style, icon_source, gtk_widget_get_direction (widget),
                                        GTK_STATE_INSENSITIVE, -1, widget, "gtkcellrendererpixbuf");
          g_object_unref (G_OBJECT (icon));
          icon = temp;

          /* release the icon source */
          gtk_icon_source_free (icon_source);
        }

      /* render the invalid parts of the icon */
      gdk_draw_pixbuf (window, widget->style->black_gc, icon,
                       draw_area.x - icon_area.x, draw_area.y - icon_area.y,
                       draw_area.x, draw_area.y, draw_area.width, draw_area.height,
                       GDK_RGB_DITHER_NORMAL, 0, 0);
    }

  /* release the file's icon */
  g_object_unref (G_OBJECT (icon));
}
Example #3
0
static GitgSpinnerImages *
gitg_spinner_images_load (GdkScreen    *screen,
                          GtkIconTheme *icon_theme,
                          GtkIconSize   icon_size)
{
	GitgSpinnerImages *images;
	GdkPixbuf *icon_pixbuf, *pixbuf;
	GtkIconInfo *icon_info = NULL;
	int grid_width, grid_height, x, y, requested_size, size, isw, ish, n;
	const char *icon;
	GSList *list = NULL, *l;

	/* LOG ("GitgSpinnerCacheData loading for screen %p at size %d", screen, icon_size); */

	/* START_PROFILER ("loading spinner animation") */

	if (screen == NULL)
		screen = gdk_screen_get_default ();

	if (!gtk_icon_size_lookup_for_settings (gtk_settings_get_for_screen (screen),
						icon_size, &isw, &ish))
		goto loser;
 
	requested_size = MAX (ish, isw);

	/* Load the animation. The 'rest icon' is the 0th frame */
	icon_info = gtk_icon_theme_lookup_icon (icon_theme,
						SPINNER_ICON_NAME,
						requested_size, 0);

	if (icon_info == NULL)
	{
		g_warning ("Throbber animation not found");

		/* If the icon naming spec compliant name wasn't found, try the old name */
		icon_info = gtk_icon_theme_lookup_icon (icon_theme,
							SPINNER_FALLBACK_ICON_NAME,
						        requested_size, 0);
		if (icon_info == NULL)
		{
			g_warning ("Throbber fallback animation not found either");
			goto loser;
	 	}
	}

	g_assert (icon_info != NULL);

	size = gtk_icon_info_get_base_size (icon_info);
	icon = gtk_icon_info_get_filename (icon_info);

	if (icon == NULL)
		goto loser;

	icon_pixbuf = gdk_pixbuf_new_from_file (icon, NULL);
	gtk_icon_info_free (icon_info);
	icon_info = NULL;

	if (icon_pixbuf == NULL)
	{
		g_warning ("Could not load the spinner file");
		goto loser;
	}

	grid_width = gdk_pixbuf_get_width (icon_pixbuf);
	grid_height = gdk_pixbuf_get_height (icon_pixbuf);

	n = 0;
	for (y = 0; y < grid_height; y += size)
	{
		for (x = 0; x < grid_width ; x += size)
		{
			pixbuf = extract_frame (icon_pixbuf, x, y, size);

			if (pixbuf)
			{
				list = g_slist_prepend (list, pixbuf);
				++n;
			}
			else
			{
				g_warning ("Cannot extract frame (%d, %d) from the grid\n", x, y);
			}
		}
	}

	g_object_unref (icon_pixbuf);

	if (list == NULL)
		goto loser;

	/* g_assert (n > 0); */

	if (size > requested_size)
	{
		for (l = list; l != NULL; l = l->next)
		{
			l->data = scale_to_size (l->data, isw, ish);
		}
 	}

	/* Now we've successfully got all the data */
	images = g_new (GitgSpinnerImages, 1);
	images->ref_count = 1;
 
	images->size = icon_size;
	images->width = images->height = requested_size;

	images->n_animation_pixbufs = n;
	images->animation_pixbufs = g_new (GdkPixbuf *, n);

	for (l = list; l != NULL; l = l->next)
	{
		g_assert (l->data != NULL);
		images->animation_pixbufs[--n] = l->data;
	}
	g_assert (n == 0);

	g_slist_free (list);

	/* STOP_PROFILER ("loading spinner animation") */
	return images;
 
loser:
	if (icon_info)
	{
		gtk_icon_info_free (icon_info);
 	}

	g_slist_foreach (list, (GFunc) g_object_unref, NULL);

	/* STOP_PROFILER ("loading spinner animation") */

	return NULL;
}
Example #4
0
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
    return NS_ERROR_NOT_AVAILABLE;
#endif
  }

  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;
  }

  PRBool forceDirection = direction != GTK_TEXT_DIR_NONE;
  nsCAutoString stockID;
  PRBool useIconName = PR_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 = PR_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 = PR_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;
}
Example #5
0
/* Load image from file */
static void _xfdashboard_image_content_load_from_file(XfdashboardImageContent *self)
{
	XfdashboardImageContentPrivate		*priv;
	gchar								*lookupFilename;
	gchar								*filename;

	g_return_if_fail(XFDASHBOARD_IS_IMAGE_CONTENT(self));

	priv=self->priv;
	filename=NULL;

	/* Check if type of image is valid and all needed parameters are set */
	g_return_if_fail(priv->type==XFDASHBOARD_IMAGE_TYPE_FILE);
	g_return_if_fail(priv->iconName);
	g_return_if_fail(priv->iconSize>0);

	/* If path of icon filename is relative build absolute path by prefixing theme path ... */
	if(!g_path_is_absolute(priv->iconName))
	{
		XfdashboardTheme				*theme;
		const gchar						*themePath;

		/* Get theme path */
		theme=xfdashboard_application_get_theme();
		g_object_ref(theme);

		themePath=xfdashboard_theme_get_path(theme);

		/* Build absolute path from theme path and given relative path to icon */
		lookupFilename=g_build_filename(themePath, priv->iconName, NULL);

		/* Release allocated resources */
		g_object_unref(theme);
	}
		/* ... otherwise it is an absolute path already so just copy it */
		else lookupFilename=g_strdup(priv->iconName);

	/* If file does not exists then load fallback icon */
	if(!g_file_test(lookupFilename, G_FILE_TEST_EXISTS))
	{
		GtkIconInfo						*iconInfo;

		g_warning(_("Icon file '%s' does not exist - trying fallback icon '%s'"),
					priv->iconName,
					priv->missingIconName);

		iconInfo=gtk_icon_theme_lookup_icon(priv->iconTheme,
											priv->missingIconName,
											priv->iconSize,
#ifdef USE_GTK_BUILTIN_ICONS
											GTK_ICON_LOOKUP_USE_BUILTIN);
#else
											0);
#endif

		if(!iconInfo)
		{
			g_error(_("Could not load fallback icon for file '%s'"), priv->iconName);
			_xfdashboard_image_content_set_empty_image(self);
			g_free(lookupFilename);
			return;
		}

		/* Check if have to use built-in GdkPixbuf for icon ... */
		filename=g_strdup(gtk_icon_info_get_filename(iconInfo));
#ifdef USE_GTK_BUILTIN_ICONS
		if(!filename)
		{
			GdkPixbuf					*iconPixbuf;
			GError						*error=NULL;

			iconPixbuf=gtk_icon_info_get_builtin_pixbuf(iconInfo);
			if(!clutter_image_set_data(CLUTTER_IMAGE(self),
										gdk_pixbuf_get_pixels(iconPixbuf),
										gdk_pixbuf_get_has_alpha(iconPixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
										gdk_pixbuf_get_width(iconPixbuf),
										gdk_pixbuf_get_height(iconPixbuf),
										gdk_pixbuf_get_rowstride(iconPixbuf),
										&error))
			{
				g_warning(_("Failed to load image data into content for icon '%s': %s"),
							priv->iconName,
							error ? error->message : _("Unknown error"));
				if(error)
				{
					g_error_free(error);
					error=NULL;
				}
			}
				else g_debug("Loaded fallback icon for file '%s' from built-in pixbuf", priv->iconName);

			g_object_unref(iconPixbuf);
		}
#endif

		/* Release allocated resources */
		g_object_unref(iconInfo);
	}
Example #6
0
static gboolean
swatch_draw (GtkWidget *widget,
             cairo_t   *cr)
{
  GtkColorSwatch *swatch = (GtkColorSwatch*)widget;
  GtkThemingBackground background;
  gdouble width, height;
  GtkStyleContext *context;
  GtkStateFlags state;
  GtkIconTheme *theme;
  GtkIconInfo *icon_info = NULL;

  theme = gtk_icon_theme_get_default ();
  context = gtk_widget_get_style_context (widget);
  state = gtk_widget_get_state_flags (widget);
  width = gtk_widget_get_allocated_width (widget);
  height = gtk_widget_get_allocated_height (widget);

  cairo_save (cr);

  gtk_style_context_save (context);
  gtk_style_context_set_state (context, state);

  _gtk_theming_background_init_from_context (&background, context,
                                             0, 0, width, height,
                                             GTK_JUNCTION_NONE);

  if (swatch->priv->has_color)
    {
      cairo_pattern_t *pattern;
      cairo_matrix_t matrix;

      if (swatch->priv->use_alpha)
        {
          cairo_save (cr);

          _gtk_rounded_box_path (&background.padding_box, cr);
          cairo_clip_preserve (cr);

          cairo_set_source_rgb (cr, 0.33, 0.33, 0.33);
          cairo_fill_preserve (cr);

          pattern = _gtk_color_chooser_get_checkered_pattern ();
          cairo_matrix_init_scale (&matrix, 0.125, 0.125);
          cairo_pattern_set_matrix (pattern, &matrix);

          cairo_set_source_rgb (cr, 0.66, 0.66, 0.66);
          cairo_mask (cr, pattern);
          cairo_pattern_destroy (pattern);

          cairo_restore (cr);

          background.bg_color = swatch->priv->color;
        }
      else
        {
          background.bg_color = swatch->priv->color;
          background.bg_color.alpha = 1.0;
        }

      _gtk_theming_background_render (&background, cr);
    }
  else
    _gtk_theming_background_render (&background, cr);

  gtk_render_frame (context, cr,
                    0, 0, width, height);

  if (gtk_widget_has_visible_focus (widget))
    {
      cairo_set_line_width (cr, 2);
      if (swatch->priv->has_color && INTENSITY (swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue) < 0.5)
        cairo_set_source_rgba (cr, 1., 1., 1., 0.4);
      else
        cairo_set_source_rgba (cr, 0., 0., 0., 0.4);
        _gtk_rounded_box_shrink (&background.padding_box, 3, 3, 3, 3);
        _gtk_rounded_box_path (&background.padding_box, cr);
        cairo_stroke (cr);
    }

  if (swatch->priv->icon)
    {
      icon_info = gtk_icon_theme_lookup_icon (theme, swatch->priv->icon, 16,
                                              GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                              | GTK_ICON_LOOKUP_USE_BUILTIN);
    }
  else if ((state & GTK_STATE_FLAG_SELECTED) != 0)
    {
      GdkRGBA bg, border;
      GtkBorder border_width;
      GIcon *gicon;

      gtk_style_context_add_class (context, "color-active-badge");
      _gtk_theming_background_init_from_context (&background, context,
                                                 (width - 2 * ACTIVE_BADGE_RADIUS) / 2, (height - 2 * ACTIVE_BADGE_RADIUS) / 2,
                                                 2 * ACTIVE_BADGE_RADIUS, 2* ACTIVE_BADGE_RADIUS,
                                                 GTK_JUNCTION_NONE);

      if (_gtk_theming_background_has_background_image (&background))
        {
          _gtk_theming_background_render (&background, cr);
        }
      else
        {
          gtk_style_context_get_background_color (context, state, &bg);
          gtk_style_context_get_border_color (context, state, &border);
          gtk_style_context_get_border (context, state, &border_width);

          cairo_new_sub_path (cr);
          cairo_arc (cr, width / 2, height / 2, ACTIVE_BADGE_RADIUS, 0, 2 * G_PI);
          cairo_close_path (cr);
          gdk_cairo_set_source_rgba (cr, &bg);
          cairo_fill_preserve (cr);

          gdk_cairo_set_source_rgba (cr, &border);
          cairo_set_line_width (cr, border_width.left);
          cairo_stroke (cr);

          gicon = g_themed_icon_new ("object-select-symbolic");
          /* fallback for themes that don't have object-select-symbolic */
          g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply");

          icon_info = gtk_icon_theme_lookup_by_gicon (theme, gicon, 16,
                                                      GTK_ICON_LOOKUP_GENERIC_FALLBACK
                                                      | GTK_ICON_LOOKUP_USE_BUILTIN);
          g_object_unref (gicon);
        }
    }

  if (icon_info != NULL)
    {
      GdkPixbuf *pixbuf;

      pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context,
                                                        NULL, NULL);

      if (pixbuf != NULL)
        {
          gtk_render_icon (context, cr, pixbuf,
                           (width - gdk_pixbuf_get_width (pixbuf)) / 2,
                           (height - gdk_pixbuf_get_height (pixbuf)) / 2);
          g_object_unref (pixbuf);
        }

      g_object_unref (icon_info);
    }

  cairo_restore (cr);
  gtk_style_context_restore (context);

  return FALSE;
}