int nsp_feed_update_icon(NspFeed *feed) { NspNetData *data; char *icon_url = NULL; char *icon_path = NULL; GRegex *regex; GMatchInfo *match_info; CURL *curl; CURLcode result; GdkPixbufLoader *loader = NULL; GError *error = NULL; char *feed_id_string = NULL; /* Download web page */ data = nsp_net_new(); if ( nsp_net_load_url(feed->site_url, data) ) { g_warning("ERROR: %s\n", data->error); nsp_net_free(data); return 1; } /* Find <link> tag reffering to the icon */ regex = g_regex_new ("<link[^>]*?rel=[\"'](icon|shortcut icon)[\"'][^>]*?href=[\"'](?<href>.*?)[\"'][^>]*?>", 0, 0, NULL); g_regex_match (regex, data->content, 0, &match_info); while (g_match_info_matches (match_info)) { gchar *word = g_match_info_fetch_named (match_info, "href"); if ( !g_str_has_prefix(word, "http") ) { icon_url = g_strdup_printf("%s/%s", feed->site_url, word); g_free(word); break; } g_free (word); g_match_info_next (match_info, NULL); } g_match_info_free (match_info); g_regex_unref (regex); nsp_net_free(data); /* If no image is found - use home url + /favicon.ico */ if ( icon_url == NULL ) { regex = g_regex_new ("^(?<hostname>https?://[^/]*)", 0, 0, NULL); g_regex_match (regex, feed->site_url, 0, &match_info); if (g_match_info_matches (match_info)) { gchar *word = g_match_info_fetch_named (match_info, "hostname"); icon_url = g_strdup_printf("%s/favicon.ico", word); g_free (word); } g_match_info_free (match_info); g_regex_unref (regex); } /* Store the image to a GtkPixbufLoader */ loader = gdk_pixbuf_loader_new(); curl = curl_easy_init(); curl_easy_setopt (curl, CURLOPT_URL, icon_url); curl_easy_setopt (curl, CURLOPT_HEADER, 0); curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, nsp_feed_download_icon_cb ); curl_easy_setopt (curl, CURLOPT_WRITEDATA, loader); curl_easy_setopt (curl, CURLOPT_TIMEOUT, 60); curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1); result = curl_easy_perform (curl); curl_easy_cleanup(curl); g_free(icon_url); if ( result != 0) { return 1; } gdk_pixbuf_loader_close (loader, NULL); feed->icon = gdk_pixbuf_loader_get_pixbuf (loader); if ( !GDK_IS_PIXBUF(feed->icon) ) { feed->icon = NULL; return 1; } /* Resize and save the image */ if (gdk_pixbuf_get_width (feed->icon) != 16 || gdk_pixbuf_get_height (feed->icon) != 16) { GdkPixbuf *old = feed->icon; feed->icon = gdk_pixbuf_scale_simple (old, 16, 16, GDK_INTERP_BILINEAR); g_object_unref (G_OBJECT (old)); } feed_id_string = malloc(sizeof(char)*9); g_snprintf (feed_id_string, 9, "%i", feed->id); icon_path = g_build_filename( g_get_user_data_dir(), PACKAGE, "/icons", NULL); g_mkdir_with_parents(icon_path, 0700); icon_path = g_build_filename( icon_path, "/", feed_id_string, NULL); gdk_pixbuf_save(feed->icon, icon_path, "png", &error, NULL); if ( error != NULL ) { g_warning("ERROR: %s\n", error->message); g_error_free(error); } g_free(icon_path); free(feed_id_string); return 0; }
/** * as_image_save_pixbuf: * @image: a #AsImage instance. * @width: target width, or 0 for default * @height: target height, or 0 for default * @flags: some #AsImageSaveFlags values, e.g. %AS_IMAGE_SAVE_FLAG_PAD_16_9 * * Resamples a pixbuf to a specific size. * * Returns: (transfer full): A #GdkPixbuf of the specified size * * Since: 0.1.6 **/ GdkPixbuf * as_image_save_pixbuf (AsImage *image, guint width, guint height, AsImageSaveFlags flags) { AsImagePrivate *priv = GET_PRIVATE (image); GdkPixbuf *pixbuf = NULL; guint tmp_height; guint tmp_width; guint pixbuf_height; guint pixbuf_width; g_autoptr(GdkPixbuf) pixbuf_tmp = NULL; /* never set */ if (priv->pixbuf == NULL) return NULL; /* 0 means 'default' */ if (width == 0) width = (guint) gdk_pixbuf_get_width (priv->pixbuf); if (height == 0) height = (guint) gdk_pixbuf_get_height (priv->pixbuf); /* don't do anything to an image with the correct size */ pixbuf_width = (guint) gdk_pixbuf_get_width (priv->pixbuf); pixbuf_height = (guint) gdk_pixbuf_get_height (priv->pixbuf); if (width == pixbuf_width && height == pixbuf_height) return g_object_ref (priv->pixbuf); /* is the aspect ratio of the source perfectly 16:9 */ if (flags == AS_IMAGE_SAVE_FLAG_NONE || (pixbuf_width / 16) * 9 == pixbuf_height) { pixbuf = gdk_pixbuf_scale_simple (priv->pixbuf, (gint) width, (gint) height, GDK_INTERP_HYPER); if ((flags & AS_IMAGE_SAVE_FLAG_SHARPEN) > 0) as_pixbuf_sharpen (pixbuf, 1, -0.5); if ((flags & AS_IMAGE_SAVE_FLAG_BLUR) > 0) as_pixbuf_blur (pixbuf, 5, 3); return pixbuf; } /* create new 16:9 pixbuf with alpha padding */ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, (gint) width, (gint) height); gdk_pixbuf_fill (pixbuf, 0x00000000); if ((pixbuf_width / 16) * 9 > pixbuf_height) { tmp_width = width; tmp_height = width * pixbuf_height / pixbuf_width; } else { tmp_width = height * pixbuf_width / pixbuf_height; tmp_height = height; } pixbuf_tmp = gdk_pixbuf_scale_simple (priv->pixbuf, (gint) tmp_width, (gint) tmp_height, GDK_INTERP_HYPER); if ((flags & AS_IMAGE_SAVE_FLAG_SHARPEN) > 0) as_pixbuf_sharpen (pixbuf_tmp, 1, -0.5); if ((flags & AS_IMAGE_SAVE_FLAG_BLUR) > 0) as_pixbuf_blur (pixbuf_tmp, 5, 3); gdk_pixbuf_copy_area (pixbuf_tmp, 0, 0, /* of src */ (gint) tmp_width, (gint) tmp_height, pixbuf, (gint) (width - tmp_width) / 2, (gint) (height - tmp_height) / 2); return pixbuf; }
// Updates the images according to preferences and the window situation // Warning! This function is called very often, so it should only do the most necessary things! void updateTitle(WTApplet *wtapplet) { WnckWindow *controlledwindow; gchar *title_text, *title_color, *title_font; GdkPixbuf *icon_pixbuf; if (wtapplet->prefs->only_maximized) { controlledwindow = wtapplet->umaxedwindow; } else { controlledwindow = wtapplet->activewindow; } if (controlledwindow == NULL) return; if (controlledwindow == wtapplet->rootwindow) { // we're on desktop if (wtapplet->prefs->hide_on_unmaximized) { // hide everything icon_pixbuf = NULL; title_text = ""; } else { // display "custom" icon/title (TODO: customization via preferences?) icon_pixbuf = gtk_widget_render_icon(GTK_WIDGET(wtapplet),GTK_STOCK_HOME,GTK_ICON_SIZE_MENU,NULL); // This has to be unrefed! title_text = ("Desktop"); } } else { icon_pixbuf = wnck_window_get_icon(controlledwindow); // This only returns a pointer - it SHOULDN'T be unrefed! title_text = (gchar*)wnck_window_get_name(controlledwindow); } // TODO: we need the default font to somehow be the same in both modes if (wtapplet->prefs->custom_style) { // custom style if (controlledwindow == wtapplet->activewindow) { // window focused title_color = wtapplet->prefs->title_active_color; title_font = wtapplet->prefs->title_active_font; } else { // window unfocused title_color = wtapplet->prefs->title_inactive_color; title_font = wtapplet->prefs->title_inactive_font; } } else { // automatic (non-custom) style if (controlledwindow == wtapplet->activewindow) { // window focused title_color = wtapplet->panel_color_fg; title_font = ""; } else { // window unfocused title_color = "#808080"; // inactive title color. best fits for any panel regardless of color title_font = ""; } } // Set tooltips if (wtapplet->prefs->show_tooltips) { gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->icon), title_text); gtk_widget_set_tooltip_text (GTK_WIDGET(wtapplet->title), title_text); } title_text = g_markup_printf_escaped("<span font=\"%s\" color=\"%s\">%s</span>", title_font, title_color, title_text); // Apply markup to label widget gtk_label_set_markup(GTK_LABEL(wtapplet->title), title_text); g_free(title_text); if (icon_pixbuf == NULL) { gtk_image_clear(wtapplet->icon); } else { // We're updating window info (Careful! We've had pixbuf memory leaks here) GdkPixbuf *ipb1 = gdk_pixbuf_scale_simple(icon_pixbuf, ICON_WIDTH, ICON_HEIGHT, GDK_INTERP_BILINEAR); if (controlledwindow == wtapplet->rootwindow) g_object_unref(icon_pixbuf); //this is stupid beyond belief, thanks to the retarded GTK framework GdkPixbuf *ipb2 = gdk_pixbuf_rotate_simple(ipb1, wtapplet->angle); g_object_unref(ipb1); // Unref ipb1 to get it cleared from memory (we still need ipb2) // Saturate icon when window is not focused if (controlledwindow != wtapplet->activewindow) gdk_pixbuf_saturate_and_pixelate(ipb2, ipb2, 0, FALSE); // Apply pixbuf to icon widget gtk_image_set_from_pixbuf(wtapplet->icon, ipb2); g_object_unref(ipb2); // Unref ipb2 to get it cleared from memory } }
nsresult nsIconChannel::InitWithGnome(nsIMozIconURI *aIconURI) { nsresult rv; if (!gnome_program_get()) { // Get the brandShortName from the string bundle to pass to GNOME // as the application name. This may be used for things such as // the title of grouped windows in the panel. nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID); NS_ASSERTION(bundleService, "String bundle service must be present!"); nsCOMPtr<nsIStringBundle> bundle; bundleService->CreateBundle("chrome://branding/locale/brand.properties", getter_AddRefs(bundle)); nsXPIDLString appName; if (bundle) { bundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(), getter_Copies(appName)); } else { NS_WARNING("brand.properties not present, using default application name"); appName.AssignLiteral("Gecko"); } char* empty[] = { "" }; gnome_init(NS_ConvertUTF16toUTF8(appName).get(), "1.0", 1, empty); } nsCAutoString iconSizeString; aIconURI->GetIconSize(iconSizeString); PRUint32 iconSize; if (iconSizeString.IsEmpty()) { rv = aIconURI->GetImageSize(&iconSize); NS_ASSERTION(NS_SUCCEEDED(rv), "GetImageSize failed"); } else { int size; GtkIconSize icon_size = moz_gtk_icon_size(iconSizeString.get()); gtk_icon_size_lookup(icon_size, &size, NULL); iconSize = size; } nsCAutoString type; aIconURI->GetContentType(type); GnomeVFSFileInfo fileInfo = {0}; fileInfo.refcount = 1; // In case some GnomeVFS function addrefs and releases it nsCAutoString spec; nsCOMPtr<nsIURI> fileURI; rv = aIconURI->GetIconFile(getter_AddRefs(fileURI)); if (fileURI) { fileURI->GetAsciiSpec(spec); // Only ask gnome-vfs for a GnomeVFSFileInfo for file: uris, to avoid a // network request PRBool isFile; if (NS_SUCCEEDED(fileURI->SchemeIs("file", &isFile)) && isFile) { gnome_vfs_get_file_info(spec.get(), &fileInfo, GNOME_VFS_FILE_INFO_DEFAULT); } else { // We have to get a leaf name from our uri... nsCOMPtr<nsIURL> url(do_QueryInterface(fileURI)); if (url) { nsCAutoString name; // The filename we get is UTF-8-compatible, which matches gnome expectations. // See also: http://lists.gnome.org/archives/gnome-vfs-list/2004-March/msg00049.html // "Whenever we can detect the charset used for the URI type we try to // convert it to/from utf8 automatically inside gnome-vfs." // I'll interpret that as "otherwise, this field is random junk". url->GetFileName(name); fileInfo.name = g_strdup(name.get()); } // If this is no nsIURL, nothing we can do really. if (!type.IsEmpty()) { fileInfo.valid_fields = GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE; fileInfo.mime_type = g_strdup(type.get()); } } } if (type.IsEmpty()) { nsCOMPtr<nsIMIMEService> ms(do_GetService("@mozilla.org/mime;1")); if (ms) { nsCAutoString fileExt; aIconURI->GetFileExtension(fileExt); ms->GetTypeFromExtension(fileExt, type); } } // Get the icon theme if (!gIconTheme) { gIconTheme = gnome_icon_theme_new(); if (!gIconTheme) { gnome_vfs_file_info_clear(&fileInfo); return NS_ERROR_NOT_AVAILABLE; } } char* name = gnome_icon_lookup(gIconTheme, NULL, spec.get(), NULL, &fileInfo, type.get(), GNOME_ICON_LOOKUP_FLAGS_NONE, NULL); gnome_vfs_file_info_clear(&fileInfo); if (!name) { return NS_ERROR_NOT_AVAILABLE; } char* file = gnome_icon_theme_lookup_icon(gIconTheme, name, iconSize, NULL, NULL); g_free(name); if (!file) return NS_ERROR_NOT_AVAILABLE; // Create a GdkPixbuf buffer and scale it GError *err = nsnull; GdkPixbuf* buf = gdk_pixbuf_new_from_file(file, &err); g_free(file); if (!buf) { if (err) g_error_free(err); return NS_ERROR_UNEXPECTED; } GdkPixbuf* scaled = buf; if (gdk_pixbuf_get_width(buf) != iconSize && gdk_pixbuf_get_height(buf) != iconSize) { // scale... scaled = gdk_pixbuf_scale_simple(buf, iconSize, iconSize, GDK_INTERP_BILINEAR); gdk_pixbuf_unref(buf); if (!scaled) return NS_ERROR_OUT_OF_MEMORY; } // XXX Respect icon state rv = moz_gdk_pixbuf_to_channel(scaled, aIconURI, getter_AddRefs(mRealChannel)); gdk_pixbuf_unref(scaled); return rv; }
/** * as_image_load_filename_full: * @image: a #AsImage instance. * @filename: filename to read from * @dest_size: The size of the constructed pixbuf, or 0 for the native size * @src_size_min: The smallest source size allowed, or 0 for none * @flags: a #AsImageLoadFlags, e.g. %AS_IMAGE_LOAD_FLAG_NONE * @error: A #GError or %NULL. * * Reads an image from a file. * * Returns: %TRUE for success * * Since: 0.5.6 **/ gboolean as_image_load_filename_full (AsImage *image, const gchar *filename, guint dest_size, guint src_size_min, AsImageLoadFlags flags, GError **error) { AsImagePrivate *priv = GET_PRIVATE (image); guint pixbuf_height; guint pixbuf_width; guint tmp_height; guint tmp_width; g_autoptr(GdkPixbuf) pixbuf = NULL; g_autoptr(GdkPixbuf) pixbuf_src = NULL; g_autoptr(GdkPixbuf) pixbuf_tmp = NULL; /* only support non-deprecated types */ if (flags & AS_IMAGE_LOAD_FLAG_ONLY_SUPPORTED) { GdkPixbufFormat *fmt; fmt = gdk_pixbuf_get_file_info (filename, NULL, NULL); if (fmt == NULL) { g_set_error_literal (error, AS_UTILS_ERROR, AS_UTILS_ERROR_FAILED, "image format was not recognized"); return FALSE; } if (g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "png") != 0 && g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "jpeg") != 0 && g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "xpm") != 0 && g_strcmp0 (gdk_pixbuf_format_get_name (fmt), "svg") != 0) { g_set_error (error, AS_UTILS_ERROR, AS_UTILS_ERROR_FAILED, "image format %s is not supported", gdk_pixbuf_format_get_name (fmt)); return FALSE; } } /* update basename */ if (flags & AS_IMAGE_LOAD_FLAG_SET_BASENAME) { g_autofree gchar *basename = NULL; basename = g_path_get_basename (filename); as_image_set_basename (image, basename); } /* update checksum */ if (flags & AS_IMAGE_LOAD_FLAG_SET_CHECKSUM) { gsize len; g_autofree gchar *data = NULL; g_autofree gchar *md5_tmp = NULL; /* get the contents so we can hash the predictable file data, * rather than the unpredicatable (for JPEG) pixel data */ if (!g_file_get_contents (filename, &data, &len, error)) return FALSE; md5_tmp = g_compute_checksum_for_data (G_CHECKSUM_MD5, (guchar * )data, len); as_ref_string_assign_safe (&priv->md5, md5_tmp); } /* load the image of the native size */ if (dest_size == 0) { pixbuf = gdk_pixbuf_new_from_file (filename, error); if (pixbuf == NULL) return FALSE; as_image_set_pixbuf (image, pixbuf); return TRUE; } /* open file in native size */ if (g_str_has_suffix (filename, ".svg")) { pixbuf_src = gdk_pixbuf_new_from_file_at_scale (filename, (gint) dest_size, (gint) dest_size, TRUE, error); } else { pixbuf_src = gdk_pixbuf_new_from_file (filename, error); } if (pixbuf_src == NULL) return FALSE; /* check size */ if (gdk_pixbuf_get_width (pixbuf_src) < (gint) src_size_min && gdk_pixbuf_get_height (pixbuf_src) < (gint) src_size_min) { g_set_error (error, AS_UTILS_ERROR, AS_UTILS_ERROR_FAILED, "icon was too small %ix%i", gdk_pixbuf_get_width (pixbuf_src), gdk_pixbuf_get_height (pixbuf_src)); return FALSE; } /* don't do anything to an icon with the perfect size */ pixbuf_width = (guint) gdk_pixbuf_get_width (pixbuf_src); pixbuf_height = (guint) gdk_pixbuf_get_height (pixbuf_src); if (pixbuf_width == dest_size && pixbuf_height == dest_size) { as_image_set_pixbuf (image, pixbuf_src); return TRUE; } /* never scale up, just pad */ if (pixbuf_width < dest_size && pixbuf_height < dest_size) { g_debug ("icon padded to %ux%u as size %ux%u", dest_size, dest_size, pixbuf_width, pixbuf_height); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, (gint) dest_size, (gint) dest_size); gdk_pixbuf_fill (pixbuf, 0x00000000); gdk_pixbuf_copy_area (pixbuf_src, 0, 0, /* of src */ (gint) pixbuf_width, (gint) pixbuf_height, pixbuf, (gint) (dest_size - pixbuf_width) / 2, (gint) (dest_size - pixbuf_height) / 2); as_image_set_pixbuf (image, pixbuf); return TRUE; } /* is the aspect ratio perfectly square */ if (pixbuf_width == pixbuf_height) { pixbuf = gdk_pixbuf_scale_simple (pixbuf_src, (gint) dest_size, (gint) dest_size, GDK_INTERP_HYPER); as_image_set_pixbuf (image, pixbuf); return TRUE; } /* create new square pixbuf with alpha padding */ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, (gint) dest_size, (gint) dest_size); gdk_pixbuf_fill (pixbuf, 0x00000000); if (pixbuf_width > pixbuf_height) { tmp_width = dest_size; tmp_height = dest_size * pixbuf_height / pixbuf_width; } else { tmp_width = dest_size * pixbuf_width / pixbuf_height; tmp_height = dest_size; } pixbuf_tmp = gdk_pixbuf_scale_simple (pixbuf_src, (gint) tmp_width, (gint) tmp_height, GDK_INTERP_HYPER); if (flags & AS_IMAGE_LOAD_FLAG_SHARPEN) as_pixbuf_sharpen (pixbuf_tmp, 1, -0.5); gdk_pixbuf_copy_area (pixbuf_tmp, 0, 0, /* of src */ (gint) tmp_width, (gint) tmp_height, pixbuf, (gint) (dest_size - tmp_width) / 2, (gint) (dest_size - tmp_height) / 2); as_image_set_pixbuf (image, pixbuf); return TRUE; }
int compositor_process(weed_plant_t *inst, weed_timecode_t timecode) { int error; weed_plant_t **in_channels=NULL; int num_in_channels=0; weed_plant_t *out_channel=weed_get_plantptr_value(inst,"out_channels",&error); unsigned char *src; unsigned char *dst=weed_get_voidptr_value(out_channel,"pixel_data",&error),*dst2; int owidth=weed_get_int_value(out_channel,"width",&error),owidth3=owidth*3; int oheight=weed_get_int_value(out_channel,"height",&error); int in_width,in_height,out_width,out_height; int irowstride; int orowstride=weed_get_int_value(out_channel,"rowstrides",&error); //int palette=weed_get_int_value(out_channel,"current_palette",&error); weed_plant_t **in_params; int numscalex,numscaley,numoffsx,numoffsy,numalpha; int *bgcol; double *offsx,*offsy,*scalex,*scaley,*alpha; double myoffsx,myoffsy,myscalex,myscaley,myalpha; unsigned char *end; register int x,y,z; GdkPixbuf *in_pixbuf,*out_pixbuf; int up_interp=GDK_INTERP_HYPER; int down_interp=GDK_INTERP_BILINEAR; if (weed_plant_has_leaf(inst,"in_channels")) { num_in_channels=weed_leaf_num_elements(inst,"in_channels"); in_channels=weed_get_plantptr_array(inst,"in_channels",&error); } in_params=weed_get_plantptr_array(inst,"in_parameters",&error); numoffsx=weed_leaf_num_elements(in_params[0],"value"); offsx=weed_get_double_array(in_params[0],"value",&error); numoffsy=weed_leaf_num_elements(in_params[1],"value"); offsy=weed_get_double_array(in_params[1],"value",&error); numscalex=weed_leaf_num_elements(in_params[2],"value"); scalex=weed_get_double_array(in_params[2],"value",&error); numscaley=weed_leaf_num_elements(in_params[3],"value"); scaley=weed_get_double_array(in_params[3],"value",&error); numalpha=weed_leaf_num_elements(in_params[4],"value"); alpha=weed_get_double_array(in_params[4],"value",&error); bgcol=weed_get_int_array(in_params[5],"value",&error); // set out frame to bgcol end=dst+oheight*orowstride; for (dst2=dst; dst2<end; dst2+=orowstride) { for (x=0; x<owidth3; x+=3) { dst2[x]=bgcol[0]; dst2[x+1]=bgcol[1]; dst2[x+2]=bgcol[2]; } } weed_free(bgcol); // add overlays in reverse order for (z=num_in_channels-1; z>=0; z--) { // check if host disabled this channel : this is allowed as we have set "max_repeats" if (weed_plant_has_leaf(in_channels[z],"disabled")&&weed_get_boolean_value(in_channels[z],"disabled",&error)==WEED_TRUE) continue; if (z<numoffsx) myoffsx=(int)(offsx[z]*(double)owidth); else myoffsx=0; if (z<numoffsy) myoffsy=(int)(offsy[z]*(double)oheight); else myoffsy=0; if (z<numscalex) myscalex=scalex[z]; else myscalex=1.; if (z<numscaley) myscaley=scaley[z]; else myscaley=1.; if (z<numalpha) myalpha=alpha[z]; else myalpha=1.; out_width=(owidth*myscalex+.5); out_height=(oheight*myscaley+.5); if (out_width*out_height>0) { in_width=weed_get_int_value(in_channels[z],"width",&error); in_height=weed_get_int_value(in_channels[z],"height",&error); src=weed_get_voidptr_value(in_channels[z],"pixel_data",&error); irowstride=weed_get_int_value(in_channels[z],"rowstrides",&error); // scale image to new size in_pixbuf=pl_data_to_pixbuf(WEED_PALETTE_RGB24, in_width, in_height, irowstride, (guchar *)src); if (out_width>in_width||out_height>in_height) { out_pixbuf=gdk_pixbuf_scale_simple(in_pixbuf,out_width,out_height,up_interp); } else { out_pixbuf=gdk_pixbuf_scale_simple(in_pixbuf,out_width,out_height,down_interp); } g_object_unref(in_pixbuf); src=gdk_pixbuf_get_pixels(out_pixbuf); out_width=gdk_pixbuf_get_width(out_pixbuf); out_height=gdk_pixbuf_get_height(out_pixbuf); irowstride=gdk_pixbuf_get_rowstride(out_pixbuf); for (y=myoffsy; y<oheight&&y<myoffsy+out_height; y++) { for (x=myoffsx; x<owidth&&x<myoffsx+out_width; x++) { paint_pixel(dst,y*orowstride+x*3,src,(y-myoffsy)*irowstride+(x-myoffsx)*3,myalpha); } } g_object_unref(out_pixbuf); } } weed_free(offsx); weed_free(offsy); weed_free(scalex); weed_free(scaley); weed_free(alpha); if (num_in_channels>0) weed_free(in_channels); return WEED_NO_ERROR; }
static void insert_text (GtkTextBuffer *buffer) { GtkTextIter iter; GtkTextIter start, end; GdkPixbuf *pixbuf; GdkPixbuf *scaled; char *filename; /* demo_find_file() looks in the current directory first, * so you can run gtk-demo without installing GTK, then looks * in the location where the file is installed. */ pixbuf = NULL; filename = demo_find_file ("gtk-logo-rgb.gif", NULL); if (filename) { pixbuf = gdk_pixbuf_new_from_file (filename, NULL); g_free (filename); } if (pixbuf == NULL) { g_printerr ("Failed to load image file gtk-logo-rgb.gif\n"); exit (1); } scaled = gdk_pixbuf_scale_simple (pixbuf, 32, 32, GDK_INTERP_BILINEAR); g_object_unref (pixbuf); pixbuf = scaled; /* get start of buffer; each insertion will revalidate the * iterator to point to just after the inserted text. */ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0); gtk_text_buffer_insert (buffer, &iter, "The text widget can display text with all kinds of nifty attributes. " "It also supports multiple views of the same buffer; this demo is " "showing the same buffer in two places.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Font styles. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "For example, you can have ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "italic", -1, "italic", NULL); gtk_text_buffer_insert (buffer, &iter, ", ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "bold", -1, "bold", NULL); gtk_text_buffer_insert (buffer, &iter, ", or ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "monospace (typewriter)", -1, "monospace", NULL); gtk_text_buffer_insert (buffer, &iter, ", or ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "big", -1, "big", NULL); gtk_text_buffer_insert (buffer, &iter, " text. ", -1); gtk_text_buffer_insert (buffer, &iter, "It's best not to hardcode specific text sizes; you can use relative " "sizes as with CSS, such as ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "xx-small", -1, "xx-small", NULL); gtk_text_buffer_insert (buffer, &iter, " or ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "x-large", -1, "x-large", NULL); gtk_text_buffer_insert (buffer, &iter, " to ensure that your program properly adapts if the user changes the " "default font size.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Colors. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "Colors such as ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "a blue foreground", -1, "blue_foreground", NULL); gtk_text_buffer_insert (buffer, &iter, " or ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "a red background", -1, "red_background", NULL); gtk_text_buffer_insert (buffer, &iter, " or even ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "a blue foreground on red background", -1, "blue_foreground", "red_background", NULL); gtk_text_buffer_insert (buffer, &iter, " (select that to read it) can be used.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Underline, strikethrough, and rise. ", -1, "heading", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Strikethrough", -1, "strikethrough", NULL); gtk_text_buffer_insert (buffer, &iter, ", ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "underline", -1, "underline", NULL); gtk_text_buffer_insert (buffer, &iter, ", ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "double underline", -1, "double_underline", NULL); gtk_text_buffer_insert (buffer, &iter, ", ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "superscript", -1, "superscript", NULL); gtk_text_buffer_insert (buffer, &iter, ", and ", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "subscript", -1, "subscript", NULL); gtk_text_buffer_insert (buffer, &iter, " are all supported.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Images. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1); gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf); gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf); gtk_text_buffer_insert_pixbuf (buffer, &iter, pixbuf); gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Spacing. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "You can adjust the amount of space before each line.\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "This line has a whole lot of space before it.\n", -1, "big_gap_before_line", "wide_margins", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "You can also adjust the amount of space after each line; " "this line has a whole lot of space after it.\n", -1, "big_gap_after_line", "wide_margins", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "You can also adjust the amount of space between wrapped lines; " "this line has extra space between each wrapped line in the same " "paragraph. To show off wrapping, some filler text: the quick " "brown fox jumped over the lazy dog. Blah blah blah blah blah " "blah blah blah blah.\n", -1, "double_spaced_line", "wide_margins", NULL); gtk_text_buffer_insert (buffer, &iter, "Also note that those lines have extra-wide margins.\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Editability. ", -1, "heading", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "This line is 'locked down' and can't be edited by the user - just " "try it! You can't delete this line.\n\n", -1, "not_editable", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Wrapping. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "This line (and most of the others in this buffer) is word-wrapped, " "using the proper Unicode algorithm. Word wrap should work in all " "scripts and languages that GTK+ supports. Let's make this a long " "paragraph to demonstrate: blah blah blah blah blah blah blah blah " "blah blah blah blah blah blah blah blah blah blah blah\n\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "This line has character-based wrapping, and can wrap between any two " "character glyphs. Let's make this a long paragraph to demonstrate: " "blah blah blah blah blah blah blah blah blah blah blah blah blah blah " "blah blah blah blah blah\n\n", -1, "char_wrap", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "This line has all wrapping turned off, so it makes the horizontal " "scrollbar appear.\n\n\n", -1, "no_wrap", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Justification. ", -1, "heading", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "\nThis line has center justification.\n", -1, "center", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "This line has right justification.\n", -1, "right_justify", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "\nThis line has big wide margins. Text text text text text text text " "text text text text text text text text text text text text text text " "text text text text text text text text text text text text text text " "text.\n", -1, "wide_margins", NULL); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Internationalization. ", -1, "heading", NULL); gtk_text_buffer_insert (buffer, &iter, "You can put all sorts of Unicode text in the buffer.\n\nGerman " "(Deutsch S\303\274d) Gr\303\274\303\237 Gott\nGreek " "(\316\225\316\273\316\273\316\267\316\275\316\271\316\272\316\254) " "\316\223\316\265\316\271\316\254 \317\203\316\261\317\202\nHebrew " "\327\251\327\234\327\225\327\235\nJapanese " "(\346\227\245\346\234\254\350\252\236)\n\nThe widget properly handles " "bidirectional text, word wrapping, DOS/UNIX/Unicode paragraph separators, " "grapheme boundaries, and so on using the Pango internationalization " "framework.\n", -1); gtk_text_buffer_insert (buffer, &iter, "Here's a word-wrapped quote in a right-to-left language:\n", -1); gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "\331\210\331\202\330\257 \330\250\330\257\330\243 " "\330\253\331\204\330\247\330\253 \331\205\331\206 " "\330\243\331\203\330\253\330\261 \330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 " "\330\252\331\202\330\257\331\205\330\247 \331\201\331\212 " "\330\264\330\250\331\203\330\251 \330\247\331\203\330\263\331\212\331\210\331\206 " "\330\250\330\261\330\247\331\205\330\254\331\207\330\247 " "\331\203\331\205\331\206\330\270\331\205\330\247\330\252 " "\331\204\330\247 \330\252\330\263\330\271\331\211 \331\204\331\204\330\261\330\250\330\255\330\214 " "\330\253\331\205 \330\252\330\255\331\210\331\204\330\252 " "\331\201\331\212 \330\247\331\204\330\263\331\206\331\210\330\247\330\252 " "\330\247\331\204\330\256\331\205\330\263 \330\247\331\204\331\205\330\247\330\266\331\212\330\251 " "\330\245\331\204\331\211 \331\205\330\244\330\263\330\263\330\247\330\252 " "\331\205\330\247\331\204\331\212\330\251 \331\205\331\206\330\270\331\205\330\251\330\214 " "\331\210\330\250\330\247\330\252\330\252 \330\254\330\262\330\241\330\247 " "\331\205\331\206 \330\247\331\204\331\206\330\270\330\247\331\205 " "\330\247\331\204\331\205\330\247\331\204\331\212 \331\201\331\212 " "\330\250\331\204\330\257\330\247\331\206\331\207\330\247\330\214 " "\331\210\331\204\331\203\331\206\331\207\330\247 \330\252\330\252\330\256\330\265\330\265 " "\331\201\331\212 \330\256\330\257\331\205\330\251 \331\202\330\267\330\247\330\271 " "\330\247\331\204\331\205\330\264\330\261\331\210\330\271\330\247\330\252 " "\330\247\331\204\330\265\330\272\331\212\330\261\330\251. \331\210\330\243\330\255\330\257 " "\330\243\331\203\330\253\330\261 \331\207\330\260\331\207 " "\330\247\331\204\331\205\330\244\330\263\330\263\330\247\330\252 " "\331\206\330\254\330\247\330\255\330\247 \331\207\331\210 " "\302\273\330\250\330\247\331\206\331\203\331\210\330\263\331\210\331\204\302\253 " "\331\201\331\212 \330\250\331\210\331\204\331\212\331\201\331\212\330\247.\n\n", -1, "rtl_quote", NULL); gtk_text_buffer_insert (buffer, &iter, "You can put widgets in the buffer: Here's a button: ", -1); gtk_text_buffer_create_child_anchor (buffer, &iter); gtk_text_buffer_insert (buffer, &iter, " and a menu: ", -1); gtk_text_buffer_create_child_anchor (buffer, &iter); gtk_text_buffer_insert (buffer, &iter, " and a scale: ", -1); gtk_text_buffer_create_child_anchor (buffer, &iter); gtk_text_buffer_insert (buffer, &iter, " and an animation: ", -1); gtk_text_buffer_create_child_anchor (buffer, &iter); gtk_text_buffer_insert (buffer, &iter, " finally a text entry: ", -1); gtk_text_buffer_create_child_anchor (buffer, &iter); gtk_text_buffer_insert (buffer, &iter, ".\n", -1); gtk_text_buffer_insert (buffer, &iter, "\n\nThis demo doesn't demonstrate all the GtkTextBuffer features; " "it leaves out, for example: invisible/hidden text, tab stops, " "application-drawn areas on the sides of the widget for displaying " "breakpoints and such...", -1); /* Apply word_wrap tag to whole buffer */ gtk_text_buffer_get_bounds (buffer, &start, &end); gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end); g_object_unref (pixbuf); }
int _camera_storage_image_filename(const dt_camera_t *camera,const char *filename,CameraFile *preview,CameraFile *exif,void *user_data) { _camera_import_dialog_t *data=(_camera_import_dialog_t*)user_data; GtkTreeIter iter; const char *img; unsigned long size; GdkPixbuf *pixbuf=NULL; GdkPixbuf *thumb=NULL; /* stop fetching previews if job is cancelled */ if (data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED ) return 0; gboolean i_own_lock = dt_control_gdk_lock(); char exif_info[1024]= {0}; char file_info[4096]= {0}; if( preview ) { gp_file_get_data_and_size(preview, &img, &size); if( size > 0 ) { // we got preview image data lets create a pixbuf from image blob GError *err=NULL; GInputStream *stream; if( (stream = g_memory_input_stream_new_from_data(img, size,NULL)) !=NULL) pixbuf = gdk_pixbuf_new_from_stream( stream, NULL, &err ); } if(pixbuf) { // Scale pixbuf to a thumbnail double sw=gdk_pixbuf_get_width( pixbuf ); double scale=75.0/gdk_pixbuf_get_height( pixbuf ); thumb = gdk_pixbuf_scale_simple( pixbuf, sw*scale,75 , GDK_INTERP_BILINEAR ); } } #if 0 // libgphoto only supports fetching exif in jpegs, not raw char buffer[1024]= {0}; if ( exif ) { const char *exif_data; char *value=NULL; gp_file_get_data_and_size(exif, &exif_data, &size); if( size > 0 ) { void *exif=dt_exif_data_new((uint8_t *)exif_data,size); if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL); snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value); } else fprintf(stderr,"No exifdata read\n"); } #endif // filename\n 1/60 f/2.8 24mm iso 160 snprintf(file_info, sizeof(file_info), "%s%c%s",filename,strlen(exif_info)?'\n':'\0',strlen(exif_info)?exif_info:""); gtk_list_store_append(data->store,&iter); gtk_list_store_set(data->store,&iter,0,thumb,1,file_info,-1); if(pixbuf) g_object_unref(pixbuf); if(thumb) g_object_ref(thumb); if (i_own_lock) dt_control_gdk_unlock(); return 1; }
void PictureEntry_Update (Picture *pic, gboolean select_it) { GdkPixbufLoader *loader = 0; GError *error = NULL; g_return_if_fail (pic != NULL || PictureEntryView != NULL); if (!pic->data) { PictureEntry_Clear(); return; } loader = gdk_pixbuf_loader_new(); if (loader) { if (gdk_pixbuf_loader_write(loader, pic->data, pic->size, &error)) { GtkTreeSelection *selection; GdkPixbuf *pixbuf; if (!gdk_pixbuf_loader_close(loader, &error)) { Log_Print(LOG_ERROR,_("Error with 'loader_close': %s"), error->message); g_error_free(error); } selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(PictureEntryView)); pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); if (pixbuf) { GtkListStore *picture_store; GtkTreeIter iter1; GdkPixbuf *scaled_pixbuf; gint scaled_pixbuf_width; gint scaled_pixbuf_height; gchar *pic_info; g_object_ref(pixbuf); g_object_unref(loader); // Keep aspect ratio of the picture pic->width = gdk_pixbuf_get_width(pixbuf); pic->height = gdk_pixbuf_get_height(pixbuf); if (pic->width > pic->height) { scaled_pixbuf_width = 96; scaled_pixbuf_height = 96 * pic->height / pic->width; }else { scaled_pixbuf_width = 96 * pic->width / pic->height; scaled_pixbuf_height = 96; } scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, scaled_pixbuf_width, scaled_pixbuf_height, //GDK_INTERP_NEAREST); // Lower quality but better speed GDK_INTERP_BILINEAR); g_object_unref(pixbuf); picture_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(PictureEntryView))); pic_info = Picture_Info(pic); gtk_list_store_insert_with_values (picture_store, &iter1, G_MAXINT, PICTURE_COLUMN_PIC, scaled_pixbuf, PICTURE_COLUMN_TEXT, pic_info, PICTURE_COLUMN_DATA, Picture_Copy_One (pic), -1); g_free(pic_info); if (select_it) gtk_tree_selection_select_iter(selection, &iter1); g_object_unref(scaled_pixbuf); }else { GtkWidget *msgdialog; g_object_unref(loader); Log_Print (LOG_ERROR, "%s", _("Cannot display the image because not enough data has been read to determine how to create the image buffer.")); msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", _("Cannot display the image")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (msgdialog), _("Not enough data has been read to determine how to create the image buffer.")); gtk_window_set_title (GTK_WINDOW (msgdialog), _("Load Image File")); gtk_dialog_run(GTK_DIALOG(msgdialog)); gtk_widget_destroy(msgdialog); } }else { Log_Print(LOG_ERROR,_("Error with 'loader_write': %s"), error->message); g_error_free(error); } } // Do also for next picture if (pic->next) PictureEntry_Update(pic->next, select_it); return; }
static int image_constructor(Plugin *p, char **fp) { gchar *tooltip, *fname; image *img; GdkPixbuf *gp, *gps; GtkWidget *wid; GError *err = NULL; char *config_start, *config_end; line s; s.len = 256; ENTER; img = g_new0(image, 1); g_return_val_if_fail(img != NULL, 0); p->priv = img; tooltip = fname = 0; if( fp ) { config_start = *fp; while (lxpanel_get_line(fp, &s) != LINE_BLOCK_END) { if (s.type == LINE_NONE) { ERR( "image: illegal token %s\n", s.str); goto error; } if (s.type == LINE_VAR) { if (!g_ascii_strcasecmp(s.t[0], "image")) fname = expand_tilda(s.t[1]); else if (!g_ascii_strcasecmp(s.t[0], "tooltip")) tooltip = g_strdup(s.t[1]); else { ERR( "image: unknown var %s\n", s.t[0]); goto error; } } else { ERR( "image: illegal in this context %s\n", s.str); goto error; } } config_end = *fp - 1; while( *config_end != '}' && config_end > config_start ) { --config_end; } if( *config_end == '}' ) --config_end; img->config_data = g_strndup( config_start, (config_end-config_start) ); } else { config_start = config_end = NULL; } img->mainw = gtk_event_box_new(); gtk_widget_show(img->mainw); //g_signal_connect(G_OBJECT(img->mainw), "expose_event", // G_CALLBACK(gtk_widget_queue_draw), NULL); gp = gdk_pixbuf_new_from_file(fname, &err); if (!gp) { g_warning("image: can't read image %s\n", fname); wid = gtk_label_new("?"); } else { float ratio; ratio = (p->panel->orientation == ORIENT_HORIZ) ? (float) (p->panel->ah - 2) / (float) gdk_pixbuf_get_height(gp) : (float) (p->panel->aw - 2) / (float) gdk_pixbuf_get_width(gp); gps = gdk_pixbuf_scale_simple (gp, ratio * ((float) gdk_pixbuf_get_width(gp)), ratio * ((float) gdk_pixbuf_get_height(gp)), GDK_INTERP_HYPER); wid = gtk_image_new_from_pixbuf(gps); g_object_unref(gp); g_object_unref(gps); } gtk_widget_show(wid); gtk_container_add(GTK_CONTAINER(img->mainw), wid); gtk_container_set_border_width(GTK_CONTAINER(img->mainw), 0); g_free(fname); if (tooltip) { gtk_widget_set_tooltip_text(img->mainw, tooltip); g_free(tooltip); } RET(1); error: g_free(fname); g_free(tooltip); image_destructor(p); RET(0); }
G_MODULE_EXPORT gboolean display_show(NOTIFICATION_INFO* ni) { GdkColor color; GtkWidget* vbox; GtkWidget* hbox; GtkWidget* label; GtkWidget* image; GdkScreen* screen; gint n, pos, len; gint x, y; gint monitor_num; GdkRectangle rect; DISPLAY_INFO* di = g_new0(DISPLAY_INFO, 1); if (!di) { perror("g_new0"); return FALSE; } di->ni = ni; len = g_list_length(notifications); for (pos = 0; pos < len; pos++) { DISPLAY_INFO* p = g_list_nth_data(notifications, pos); if (pos != p->pos) break; } screen = gdk_screen_get_default(); monitor_num = gdk_screen_get_primary_monitor(screen); gdk_screen_get_monitor_geometry(screen, monitor_num, &rect); x = rect.x + rect.width - 250; y = rect.y + rect.height - 110; for (n = 0; n < pos; n++) { y -= 110; if (y < 0) { x -= 250; if (x < 0) { return FALSE; } y = rect.y + rect.height - 110; } } di->pos = pos; notifications = g_list_insert_sorted(notifications, di, notifications_compare); di->x = x; di->y = y; di->popup = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_title(GTK_WINDOW(di->popup), "growl-for-linux"); gtk_window_set_resizable(GTK_WINDOW(di->popup), FALSE); gtk_window_set_decorated(GTK_WINDOW(di->popup), FALSE); gtk_window_set_keep_above(GTK_WINDOW(di->popup), TRUE); gtk_window_stick(GTK_WINDOW(di->popup)); vbox = gtk_vbox_new(FALSE, 5); gtk_container_set_border_width(GTK_CONTAINER(vbox), 18); gtk_container_add(GTK_CONTAINER(di->popup), vbox); hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); if (di->ni->icon && *di->ni->icon) { GdkPixbuf* pixbuf; if (di->ni->local) { gchar* newurl = g_filename_from_uri(di->ni->icon, NULL, NULL); GError* error = NULL; pixbuf = gdk_pixbuf_new_from_file(newurl ? newurl : di->ni->icon, &error); if (newurl) g_free(newurl); } else pixbuf = url2pixbuf(di->ni->icon, NULL); if (pixbuf) { GdkPixbuf* tmp = gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_TILES); if (tmp) { g_object_unref(pixbuf); pixbuf = tmp; } image = gtk_image_new_from_pixbuf(pixbuf); gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); g_object_unref(pixbuf); } } PangoFontDescription* font_desc; font_desc = pango_font_description_new(); pango_font_description_set_family(font_desc, "Sans"); pango_font_description_set_size(font_desc, 12 * PANGO_SCALE); label = gtk_label_new(di->ni->title); gdk_color_parse("white", &color); gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color); gtk_widget_modify_font(label, font_desc); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); pango_font_description_free(font_desc); font_desc = pango_font_description_new(); pango_font_description_set_family(font_desc, "Sans"); pango_font_description_set_size(font_desc, 8 * PANGO_SCALE); label = gtk_label_new(di->ni->text); gdk_color_parse("white", &color); gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color); gtk_widget_modify_font(label, font_desc); g_signal_connect(G_OBJECT(label), "size-allocate", G_CALLBACK(label_size_allocate), NULL); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_CHAR); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0); pango_font_description_free(font_desc); gtk_widget_set_events(di->popup, GDK_BUTTON_PRESS_MASK); g_signal_connect(G_OBJECT(di->popup), "button-press-event", G_CALLBACK(display_clicked), di); di->offset = 0; di->timeout = 500; gtk_window_move(GTK_WINDOW(di->popup), di->x, di->y); gtk_window_set_opacity(GTK_WINDOW(di->popup), 0); gtk_widget_set_app_paintable(di->popup, TRUE); gtk_widget_show_all(di->popup); if (pixmap == NULL) { pixmap = gdk_pixmap_create_from_xpm_d(di->popup->window, &bitmap, NULL, balloon); } gdk_drawable_get_size(pixmap, &pixmap_width, &pixmap_height); gtk_widget_set_size_request(di->popup, pixmap_width, pixmap_height); gdk_window_shape_combine_mask(di->popup->window, bitmap, 0, 0); g_signal_connect(G_OBJECT(di->popup), "expose-event", G_CALLBACK(display_expose), di); g_timeout_add(10, display_animation_func, di); return FALSE; }
static gboolean gdict_applet_draw (GdictApplet *applet) { GdictAppletPrivate *priv = applet->priv; GtkWidget *box; GtkWidget *hbox; gchar *text = NULL; if (priv->entry) text = gtk_editable_get_chars (GTK_EDITABLE (priv->entry), 0, -1); if (priv->box) gtk_widget_destroy (priv->box); switch (priv->orient) { case GTK_ORIENTATION_VERTICAL: box = gtk_vbox_new (FALSE, 0); break; case GTK_ORIENTATION_HORIZONTAL: box = gtk_hbox_new (FALSE, 0); break; default: g_assert_not_reached (); break; } gtk_container_add (GTK_CONTAINER (applet), box); gtk_widget_show (box); /* toggle button */ priv->toggle = gtk_toggle_button_new (); gtk_widget_set_tooltip_text (priv->toggle, _("Click to view the dictionary window")); set_atk_name_description (priv->toggle, _("Toggle dictionary window"), _("Show or hide the definition window")); gtk_button_set_relief (GTK_BUTTON (priv->toggle), GTK_RELIEF_NONE); g_signal_connect (priv->toggle, "toggled", G_CALLBACK (gdict_applet_icon_toggled_cb), applet); g_signal_connect (priv->toggle, "button-press-event", G_CALLBACK (gdict_applet_icon_button_press_event_cb), applet); gtk_box_pack_start (GTK_BOX (box), priv->toggle, FALSE, FALSE, 0); gtk_widget_show (priv->toggle); hbox = gtk_hbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (hbox), 0); gtk_container_add (GTK_CONTAINER (priv->toggle), hbox); gtk_widget_show (hbox); if (priv->icon) { GdkPixbuf *scaled; priv->image = gtk_image_new (); gtk_image_set_pixel_size (GTK_IMAGE (priv->image), priv->size - 10); scaled = gdk_pixbuf_scale_simple (priv->icon, priv->size - 5, priv->size - 5, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), scaled); g_object_unref (scaled); gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0); gtk_widget_show (priv->image); } else { priv->image = gtk_image_new (); gtk_image_set_pixel_size (GTK_IMAGE (priv->image), priv->size - 10); gtk_image_set_from_stock (GTK_IMAGE (priv->image), GTK_STOCK_MISSING_IMAGE, -1); gtk_box_pack_start (GTK_BOX (hbox), priv->image, FALSE, FALSE, 0); gtk_widget_show (priv->image); } /* entry */ priv->entry = gtk_entry_new (); gtk_widget_set_tooltip_text (priv->entry, _("Type the word you want to look up")); set_atk_name_description (priv->entry, _("Dictionary entry"), _("Look up words in dictionaries")); gtk_editable_set_editable (GTK_EDITABLE (priv->entry), TRUE); gtk_entry_set_width_chars (GTK_ENTRY (priv->entry), 12); g_signal_connect (priv->entry, "activate", G_CALLBACK (gdict_applet_entry_activate_cb), applet); g_signal_connect (priv->entry, "button-press-event", G_CALLBACK (gdict_applet_entry_button_press_event_cb), applet); g_signal_connect (priv->entry, "key-press-event", G_CALLBACK (gdict_applet_entry_key_press_cb), applet); gtk_box_pack_end (GTK_BOX (box), priv->entry, FALSE, FALSE, 0); gtk_widget_show (priv->entry); if (text) { gtk_entry_set_text (GTK_ENTRY (priv->entry), text); g_free (text); } priv->box = box; #if 0 gtk_widget_grab_focus (priv->entry); #endif gtk_widget_show_all (GTK_WIDGET (applet)); return FALSE; }
// TODO: use orientation to correctly rotate the image. // maybe this should be (partly) in common/imageio.[c|h]? static void _lib_import_update_preview(GtkFileChooser *file_chooser, gpointer data) { GtkWidget *preview; char *filename; GdkPixbuf *pixbuf = NULL; gboolean have_preview = FALSE; preview = GTK_WIDGET(data); filename = gtk_file_chooser_get_preview_filename(file_chooser); if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) goto no_preview_fallback; // don't create dng thumbnails to avoid crashes in libtiff when these are hdr: char *c = filename + strlen(filename); while(c > filename && *c != '.') c--; if(!strcasecmp(c, ".dng")) goto no_preview_fallback; pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL); have_preview = (pixbuf != NULL); if(!have_preview) { // raw image thumbnail int ret; libraw_data_t *raw = libraw_init(0); libraw_processed_image_t *image = NULL; ret = libraw_open_file(raw, filename); if(ret) goto libraw_fail; ret = libraw_unpack_thumb(raw); if(ret) goto libraw_fail; ret = libraw_adjust_sizes_info_only(raw); if(ret) goto libraw_fail; image = libraw_dcraw_make_mem_thumb(raw, &ret); if(!image || ret) goto libraw_fail; // const int orientation = raw->sizes.flip; GdkPixbuf *tmp; GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); have_preview = gdk_pixbuf_loader_write(loader, image->data, image->data_size, NULL); tmp = gdk_pixbuf_loader_get_pixbuf(loader); gdk_pixbuf_loader_close(loader, NULL); float ratio; if(image->type == LIBRAW_IMAGE_JPEG) { // jpeg dt_imageio_jpeg_t jpg; if(dt_imageio_jpeg_decompress_header(image->data, image->data_size, &jpg)) goto libraw_fail; ratio = 1.0*jpg.height/jpg.width; } else { // bmp -- totally untested ratio = 1.0*image->height/image->width; } int width = 128, height = 128*ratio; pixbuf = gdk_pixbuf_scale_simple(tmp, width, height, GDK_INTERP_BILINEAR); if(loader) g_object_unref(loader); // clean up raw stuff. libraw_recycle(raw); libraw_close(raw); free(image); if(0) { libraw_fail: // fprintf(stderr,"[imageio] %s: %s\n", filename, libraw_strerror(ret)); libraw_close(raw); have_preview = FALSE; } } if(!have_preview) { no_preview_fallback: pixbuf = gdk_pixbuf_new_from_inline(-1, dt_logo_128x128, FALSE, NULL); have_preview = TRUE; } if(have_preview) gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf); if(pixbuf) g_object_unref(pixbuf); g_free(filename); gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview); }
static int renderer_overlay_wallpaper( GdkPixbuf *background, const char *wallpaper, MMB_Screen *screen, int clip ) { GError *error = NULL; GdkPixbuf *image = gdk_pixbuf_new_from_file( wallpaper, &error ); if ( error != NULL ) { fprintf( stderr, "Failed to parse image: %s\n" , error->message ); return 0; } double wp_width = gdk_pixbuf_get_width( image ); double wp_height = gdk_pixbuf_get_height( image ); for ( int monitor = 0; monitor < screen->num_monitors; monitor++ ) { MMB_Rectangle rectangle = screen->monitors[monitor]; double w_scale = wp_width/( double )( rectangle.w ); double h_scale = wp_height/( double )( rectangle.h ); // Picture is small then screen, center it. if ( w_scale < 1 && h_scale < 1 ) { gdk_pixbuf_copy_area( image, 0,0, wp_width, wp_height, background, rectangle.x + ( rectangle.w-wp_width )/2, rectangle.y + ( rectangle.h-wp_height )/2 ); } // Picture is smaller on one of the sides and we want to clip. else if ( clip && ( w_scale < 1 || h_scale < 1 ) ) { double x_off = ( ( float )rectangle.w-wp_width )/2.0; double y_off = ( ( float )rectangle.h-wp_height )/2.0; gdk_pixbuf_copy_area( image, -( x_off < 0 )*x_off,-( y_off < 0 )*y_off, wp_width+( x_off < 0 )*2*x_off, wp_height+( y_off < 0 )*2*y_off, background, rectangle.x + ( ( x_off> 0 )?x_off:0 ), rectangle.y + ( ( y_off> 0 )?y_off:0 ) ); } // Picture is bigger/equal then screen. // Scale to fit. else { int new_w= 0; int new_h = 0; double x_off = 0; double y_off = 0; if ( clip ) { if ( w_scale < h_scale ) { new_w = wp_width/w_scale; new_h = wp_height/w_scale; } else { new_w = wp_width/h_scale; new_h = wp_height/h_scale; } x_off = ( ( new_w-rectangle.w )/2.0 ); y_off = ( ( new_h-rectangle.h )/2.0 ); } else { if ( w_scale > h_scale ) { new_w = wp_width/w_scale; new_h = wp_height/w_scale; } else { new_w = wp_width/h_scale; new_h = wp_height/h_scale; } } GdkPixbuf *scaled_wp = gdk_pixbuf_scale_simple( image, new_w, new_h, GDK_INTERP_HYPER ); gdk_pixbuf_copy_area( scaled_wp, ( int )ceil( x_off ),( int )ceil( y_off ), new_w-ceil(x_off)*2, new_h-ceil(y_off)*2, background, rectangle.x + ( ( double )rectangle.w-new_w+x_off*2 )/2, rectangle.y + ( ( double )rectangle.h-new_h+y_off*2 )/2 ); g_object_unref( scaled_wp ); } } g_object_unref( image ); return 1; }
static void _lib_filmstrip_dnd_begin_callback(GtkWidget *widget, GdkDragContext *context, gpointer user_data) { const int ts = 64; dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data; int imgid = strip->mouse_over_id; // imgid part of selection -> do nothing // otherwise -> select the current image strip->select = DT_LIB_FILMSTRIP_SELECT_NONE; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images where imgid=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, imgid); if(sqlite3_step(stmt) != SQLITE_ROW) { dt_selection_select_single(darktable.selection, imgid); /* redraw filmstrip */ if(darktable.view_manager->proxy.filmstrip.module) gtk_widget_queue_draw(darktable.view_manager->proxy.filmstrip.module->widget); } sqlite3_finalize(stmt); // if we are dragging a single image -> use the thumbnail of that image // otherwise use the generic d&d icon // TODO: have something pretty in the 2nd case, too. if(dt_collection_get_selected_count(NULL) == 1) { dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, ts, ts); dt_mipmap_cache_read_get(darktable.mipmap_cache, &buf, imgid, mip, DT_MIPMAP_BLOCKING); if(buf.buf) { uint8_t *scratchmem = dt_mipmap_cache_alloc_scratchmem(darktable.mipmap_cache); uint8_t *buf_decompressed = dt_mipmap_cache_decompress(&buf, scratchmem); uint8_t *rgbbuf = g_malloc((buf.width+2)*(buf.height+2)*3); memset(rgbbuf, 64, (buf.width+2)*(buf.height+2)*3); for(int i=1; i<=buf.height; i++) for(int j=1; j<=buf.width; j++) for(int k=0; k<3; k++) rgbbuf[(i*(buf.width+2)+j)*3+k] = buf_decompressed[((i-1)*buf.width+j-1)*4+2-k]; int w=ts, h=ts; if(buf.width < buf.height) w = (buf.width*ts)/buf.height; // portrait else h = (buf.height*ts)/buf.width; // landscape GdkPixbuf *source = gdk_pixbuf_new_from_data(rgbbuf, GDK_COLORSPACE_RGB, FALSE, 8, (buf.width+2), (buf.height+2), (buf.width+2)*3, NULL, NULL); GdkPixbuf *scaled = gdk_pixbuf_scale_simple(source, w, h, GDK_INTERP_HYPER); gtk_drag_set_icon_pixbuf(context, scaled, 0, 0); if(source) g_object_unref(source); if(scaled) g_object_unref(scaled); g_free(rgbbuf); } dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); } }
static gboolean update_icon_idle (ButtonData *button_data) { int width, height; GdkPixbuf *icon; GdkPixbuf *scaled; int icon_size; GError *error; int xrequest, yrequest; GtkRequisition empty_button_request; /* FIXME this function could do a lot more short-circuiting and maybe * save some effort */ g_debug("Updating icon, allocated size=%d", button_data->size); if (!button_data->icon_theme) goto done; gtk_image_clear (GTK_IMAGE (button_data->image)); gtk_widget_set_size_request (button_data->image, 10, 10); /* we undo this later, it's just in case the button special-cases 0x0 contents */ gtk_widget_size_request (GTK_WIDGET(button_data->button), &empty_button_request); empty_button_request.width -= 10; empty_button_request.height -= 10; icon_size = 0; xrequest = -1; yrequest = -1; switch (button_data->orient) { case GTK_ORIENTATION_HORIZONTAL: xrequest = button_data->size - empty_button_request.width; if (xrequest < 0) xrequest = 0; yrequest = 12; icon_size = xrequest; break; case GTK_ORIENTATION_VERTICAL: xrequest = 12; yrequest = button_data->size - empty_button_request.height; if (yrequest < 0) yrequest = 0; icon_size = yrequest; break; } /* clamp icon size to a max of 60 which is the native server-side size */ if (icon_size < 22) icon_size = 16; else if (icon_size < 32) icon_size = 22; else if (icon_size < 48) icon_size = 32; else if (icon_size < 60) icon_size = 48; else icon_size = 60; g_debug("Settled on icon size %d, and image widget request %dx%d, based on empty button request %dx%d", icon_size, xrequest, yrequest, empty_button_request.width, empty_button_request.height); if (button_data->user_photo) { icon = button_data->user_photo; g_object_ref(icon); } else { error = NULL; icon = gtk_icon_theme_load_icon (button_data->icon_theme, ICON_NAME, icon_size, 0, &error); } if (icon == NULL) { g_printerr (_("Failed to load %s: %s\n"), ICON_NAME, error ? error->message : _("Icon not found")); if (error) { g_error_free (error); error = NULL; } icon = gdk_pixbuf_new_from_file (DATADIR "/pixmaps/nobody.png", NULL); if (icon == NULL) { gtk_image_set_from_stock (GTK_IMAGE (button_data->image), GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_SMALL_TOOLBAR); goto done; } } width = gdk_pixbuf_get_width (icon); height = gdk_pixbuf_get_height (icon); scaled = NULL; /* Make it fit on the given panel */ switch (button_data->orient) { case GTK_ORIENTATION_HORIZONTAL: width = (icon_size * width) / (double) height; height = icon_size; break; case GTK_ORIENTATION_VERTICAL: height = (icon_size * height) / (double) width; width = icon_size; break; } scaled = gdk_pixbuf_scale_simple (icon, width, height, GDK_INTERP_BILINEAR); if (scaled != NULL) { gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), scaled); g_object_unref (scaled); } else { gtk_image_set_from_pixbuf (GTK_IMAGE (button_data->image), icon); } /* don't put much size request on the image, since we are scaling * to the allocation, if we didn't do this we could a) never be resized * smaller and b) get infinite request/alloc loops */ gtk_widget_set_size_request(button_data->image, xrequest, yrequest); g_object_unref (icon); #ifdef GUI_LOG { GtkRequisition with_image_request; gtk_widget_size_request(button_data->button, &with_image_request); g_debug("Entire button will request %dx%d", with_image_request.width, with_image_request.height); } #endif done: button_data->update_icon_idle = 0; return FALSE; }
static int _camera_storage_image_filename(const dt_camera_t *camera, const char *filename, CameraFile *preview, CameraFile *exif, void *user_data) { _camera_import_dialog_t *data = (_camera_import_dialog_t *)user_data; const char *img; unsigned long size; GdkPixbuf *pixbuf = NULL; GdkPixbuf *thumb = NULL; /* stop fetching previews if job is cancelled */ if(data->preview_job && dt_control_job_get_state(data->preview_job) == DT_JOB_STATE_CANCELLED) return 0; char exif_info[1024] = { 0 }; if(preview) { gp_file_get_data_and_size(preview, &img, &size); if(size > 0) { // we got preview image data lets create a pixbuf from image blob GError *err = NULL; GInputStream *stream; if((stream = g_memory_input_stream_new_from_data(img, size, NULL)) != NULL) pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, &err); } if(pixbuf) { // Scale pixbuf to a thumbnail double sw = gdk_pixbuf_get_width(pixbuf); double scale = 75.0 / gdk_pixbuf_get_height(pixbuf); thumb = gdk_pixbuf_scale_simple(pixbuf, sw * scale, 75, GDK_INTERP_BILINEAR); } } #if 0 // libgphoto only supports fetching exif in jpegs, not raw char buffer[1024]= {0}; if ( exif ) { const char *exif_data; char *value=NULL; gp_file_get_data_and_size(exif, &exif_data, &size); if( size > 0 ) { void *exif=dt_exif_data_new((uint8_t *)exif_data,size); if( (value=g_strdup( dt_exif_data_get_value(exif,"Exif.Photo.ExposureTime",buffer,1024) ) ) != NULL); snprintf(exif_info, sizeof(exif_info), "exposure: %s\n", value); } else fprintf(stderr,"No exifdata read\n"); } #endif _image_filename_t *params = (_image_filename_t *)malloc(sizeof(_image_filename_t)); if(!params) { if(pixbuf) g_object_unref(pixbuf); if(thumb) g_object_unref(thumb); return 0; } // filename\n 1/60 f/2.8 24mm iso 160 params->file_info = g_strdup_printf("%s%c%s", filename, *exif_info ? '\n' : '\0', *exif_info ? exif_info : ""); params->thumb = thumb; params->store = data->store; g_main_context_invoke(NULL, _camera_storage_image_filename_gui_thread, params); if(pixbuf) g_object_unref(pixbuf); return 1; }
gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event ) { /* g_message("Exposed!!! %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */ gint insetX = 0; gint insetY = 0; (void)event; /* gint lower = widget->allocation.width; lower = (widget->allocation.height < lower) ? widget->allocation.height : lower; if ( lower > 16 ) { insetX++; if ( lower > 18 ) { insetX++; if ( lower > 22 ) { insetX++; if ( lower > 24 ) { insetX++; if ( lower > 32 ) { insetX++; } } } } insetY = insetX; } */ if ( GTK_WIDGET_DRAWABLE( widget ) ) { GtkStyle* style = gtk_widget_get_style( widget ); if ( insetX > 0 || insetY > 0 ) { gtk_paint_flat_box( style, widget->window, (GtkStateType)GTK_WIDGET_STATE(widget), GTK_SHADOW_NONE, NULL, widget, NULL, 0, 0, widget->allocation.width, widget->allocation.height); } GdkGC *gc = gdk_gc_new( widget->window ); EekPreview* preview = EEK_PREVIEW(widget); GdkColor fg = {0, static_cast<guint16>(preview->_r), static_cast<guint16>(preview->_g), static_cast<guint16>(preview->_b)}; gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE ); gdk_gc_set_foreground( gc, &fg ); gdk_draw_rectangle( widget->window, gc, TRUE, insetX, insetY, widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) ); if ( preview->_previewPixbuf ) { GtkDrawingArea* da = &(preview->drawing); GdkDrawable* drawable = (GdkDrawable*) (((GtkWidget*)da)->window); gint w = 0; gint h = 0; gdk_drawable_get_size(drawable, &w, &h); if ((w != preview->_scaledW) || (h != preview->_scaledH)) { if (preview->_scaled) { g_object_unref(preview->_scaled); } preview->_scaled = gdk_pixbuf_scale_simple(preview->_previewPixbuf, w, h, GDK_INTERP_BILINEAR); preview->_scaledW = w; preview->_scaledH = h; } GdkPixbuf* pix = (preview->_scaled) ? preview->_scaled : preview->_previewPixbuf; gdk_draw_pixbuf( drawable, 0, pix, 0, 0, 0, 0, w, h, GDK_RGB_DITHER_NONE, 0, 0 ); } if ( preview->_linked ) { /* Draw arrow */ GdkRectangle possible = {insetX, insetY, (widget->allocation.width - (insetX * 2)), (widget->allocation.height - (insetY * 2)) }; GdkRectangle area = {possible.x, possible.y, possible.width / 2, possible.height / 2 }; /* Make it square */ if ( area.width > area.height ) area.width = area.height; if ( area.height > area.width ) area.height = area.width; /* Center it horizontally */ if ( area.width < possible.width ) { int diff = (possible.width - area.width) / 2; area.x += diff; } if ( preview->_linked & PREVIEW_LINK_IN ) { gtk_paint_arrow( style, widget->window, (GtkStateType)widget->state, GTK_SHADOW_ETCHED_IN, NULL, /* clip area. &area, */ widget, /* may be NULL */ NULL, /* detail */ GTK_ARROW_DOWN, FALSE, area.x, area.y, area.width, area.height ); } if ( preview->_linked & PREVIEW_LINK_OUT ) { GdkRectangle otherArea = {area.x, area.y, area.width, area.height}; if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height); } gtk_paint_arrow( style, widget->window, (GtkStateType)widget->state, GTK_SHADOW_ETCHED_OUT, NULL, /* clip area. &area, */ widget, /* may be NULL */ NULL, /* detail */ GTK_ARROW_DOWN, FALSE, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); } if ( preview->_linked & PREVIEW_LINK_OTHER ) { GdkRectangle otherArea = {insetX, area.y, area.width, area.height}; if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } gtk_paint_arrow( style, widget->window, (GtkStateType)widget->state, GTK_SHADOW_ETCHED_OUT, NULL, /* clip area. &area, */ widget, /* may be NULL */ NULL, /* detail */ GTK_ARROW_LEFT, FALSE, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); } if ( preview->_linked & PREVIEW_FILL ) { GdkRectangle otherArea = {possible.x + ((possible.width / 4) - (area.width / 2)), area.y, area.width, area.height}; if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } gtk_paint_check( style, widget->window, (GtkStateType)widget->state, GTK_SHADOW_ETCHED_OUT, NULL, widget, NULL, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); } if ( preview->_linked & PREVIEW_STROKE ) { GdkRectangle otherArea = {possible.x + (((possible.width * 3) / 4) - (area.width / 2)), area.y, area.width, area.height}; if ( otherArea.height < possible.height ) { otherArea.y = possible.y + (possible.height - otherArea.height) / 2; } gtk_paint_diamond( style, widget->window, (GtkStateType)widget->state, GTK_SHADOW_ETCHED_OUT, NULL, widget, NULL, otherArea.x, otherArea.y, otherArea.width, otherArea.height ); } } if ( GTK_WIDGET_HAS_FOCUS(widget) ) { gtk_paint_focus( style, widget->window, GTK_STATE_NORMAL, NULL, /* GdkRectangle *area, */ widget, NULL, 0 + 1, 0 + 1, widget->allocation.width - 2, widget->allocation.height - 2 ); } } return FALSE; }
static void colorful_tabs_view_notify_uri_cb (MidoriView* view, GParamSpec* pspec, MidoriExtension* extension) { GtkWidget* box; GtkWidget* label; SoupURI* uri; gchar* colorstr; GdkColor color; GdkColor fgcolor; GdkPixbuf* icon; label = midori_view_get_proxy_tab_label (view); if ((uri = soup_uri_new (midori_view_get_display_uri (view))) && uri->host && (katze_object_get_enum (view, "load-status") == MIDORI_LOAD_FINISHED)) { icon = midori_view_get_icon (view); if (midori_view_get_icon_uri (view) != NULL) { GdkPixbuf* newpix; guchar* pixels; newpix = gdk_pixbuf_scale_simple (icon, 1, 1, GDK_INTERP_BILINEAR); g_return_if_fail (gdk_pixbuf_get_bits_per_sample (newpix) == 8); pixels = gdk_pixbuf_get_pixels (newpix); color.red = pixels[0] * 225; color.green = pixels[1] * 225; color.blue = pixels[2] * 225; } else { gchar* hash = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri->host, 1); colorstr = g_strndup (hash, 6 + 1); g_free (hash); colorstr[0] = '#'; gdk_color_parse (colorstr, &color); } soup_uri_free (uri); if ((color.red < 35000) && (color.green < 35000) && (color.blue < 35000)) { color.red += 20000; color.green += 20000; color.blue += 20000; } /* Ensure high contrast by enforcing black/ white text colour. */ if ((color.red < 41000) && (color.green < 41000) && (color.blue < 41000)) gdk_color_parse ("#fff", &fgcolor); else gdk_color_parse ("#000", &fgcolor); box = gtk_bin_get_child (GTK_BIN (label)); gtk_event_box_set_visible_window (GTK_EVENT_BOX (label), TRUE); gtk_container_foreach (GTK_CONTAINER (box), (GtkCallback) colorful_tabs_modify_fg, &fgcolor); gtk_widget_modify_bg (label, GTK_STATE_NORMAL, &color); if (color.red < 10000) color.red = 5000; else color.red -= 5000; if (color.blue < 10000) color.blue = 5000; else color.blue -= 5000; if (color.green < 10000) color.green = 5000; else color.green -= 5000; gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, &color); } else { gtk_widget_modify_bg (label, GTK_STATE_NORMAL, NULL); gtk_widget_modify_bg (label, GTK_STATE_ACTIVE, NULL); gtk_container_foreach (GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (label))), (GtkCallback) colorful_tabs_modify_fg, NULL); } }
static void button_clicked(GtkWidget * button, ScreenshotData * sd) { GdkPixbuf * screenshot; GdkPixbuf * thumbnail; GdkWindow * window; GdkNativeWindow nwindow; gint delay; gint width; gint height; gchar * filename = NULL; gchar * basename = NULL; gchar * curdir = NULL; if (sd->whole_screen) { window = gdk_get_default_root_window(); } else { if (delay = sd->window_delay) { g_timeout_add(1000, delay_callback, &delay); gtk_main(); } nwindow = select_window(gdk_screen_get_default()); if (nwindow) { window = gdk_window_foreign_new(nwindow); } else { window = gdk_get_default_root_window(); } } gdk_drawable_get_size(window, &width, &height); if (delay = sd->screenshot_delay) { g_timeout_add(1000, delay_callback, &delay); gtk_main(); } screenshot = gdk_pixbuf_get_from_drawable (NULL, window, NULL, 0, 0, 0, 0, width, height); thumbnail = gdk_pixbuf_scale_simple (screenshot, width/5, height/5, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf (GTK_IMAGE (sd->preview), thumbnail); g_object_unref (thumbnail); filename = generate_filename_for_uri (xfce_file_chooser_get_current_folder(XFCE_FILE_CHOOSER (sd->chooser))); if (sd->ask_for_file && filename) { gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (sd->chooser), filename); if (gtk_dialog_run (GTK_DIALOG (sd->chooser)) == GTK_RESPONSE_ACCEPT) { filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(sd->chooser)); } gtk_widget_hide (GTK_WIDGET (sd->chooser)); } else { /* sd->counter++; basename = g_strdup_printf ("Screenshot-%d.png", sd->counter); filename = g_build_filename (sd->screenshots_dir, basename, NULL); curdir = g_get_current_dir(); filename = g_build_filename (curdir, basename, NULL); g_free(basename); */ } if (filename) { gdk_pixbuf_save (screenshot, filename, "png", NULL, NULL); g_free (filename); } }
GdkPixbuf * panel_make_menu_icon (GtkIconTheme *icon_theme, const char *icon, const char *fallback, int size, gboolean *long_operation) { GdkPixbuf *pb; char *file, *key; gboolean loaded; g_return_val_if_fail (size > 0, NULL); file = NULL; if (icon != NULL) file = panel_find_icon (icon_theme, icon, size); if (file == NULL && fallback != NULL) file = panel_find_icon (icon_theme, fallback, size); if (file == NULL) return NULL; if (long_operation != NULL) *long_operation = TRUE; pb = NULL; loaded = FALSE; key = g_strdup_printf ("%d:%s", size, file); if (loaded_icons != NULL && (pb = g_hash_table_lookup (loaded_icons, key)) != NULL) { if (pb != NULL) g_object_ref (G_OBJECT (pb)); } if (pb == NULL) { pb = gdk_pixbuf_new_from_file (file, NULL); if (pb) { gint width, height; width = gdk_pixbuf_get_width (pb); height = gdk_pixbuf_get_height (pb); /* if we want 24 and we get 22, do nothing; * else scale */ if (!(size - 2 <= width && width <= size && size - 2 <= height && height <= size)) { GdkPixbuf *tmp; tmp = gdk_pixbuf_scale_simple (pb, size, size, GDK_INTERP_BILINEAR); g_object_unref (pb); pb = tmp; } } /* add icon to the hash table so we don't load it again */ loaded = TRUE; } if (pb == NULL) { g_free (file); g_free (key); return NULL; } if (loaded && (gdk_pixbuf_get_width (pb) != size && gdk_pixbuf_get_height (pb) != size)) { GdkPixbuf *pb2; int dest_width; int dest_height; int width; int height; width = gdk_pixbuf_get_width (pb); height = gdk_pixbuf_get_height (pb); if (height > width) { dest_width = (size * width) / height; dest_height = size; } else { dest_width = size; dest_height = (size * height) / width; } pb2 = gdk_pixbuf_scale_simple (pb, dest_width, dest_height, GDK_INTERP_BILINEAR); g_object_unref (G_OBJECT (pb)); pb = pb2; } if (loaded) { if (loaded_icons == NULL) loaded_icons = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); g_hash_table_replace (loaded_icons, g_strdup (key), g_object_ref (G_OBJECT (pb))); g_object_weak_ref (G_OBJECT (pb), (GWeakNotify) remove_pixmap_from_loaded, g_strdup (key)); } else { /* we didn't load from disk */ if (long_operation != NULL) *long_operation = FALSE; } g_free (file); g_free (key); return pb; }
static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_format format, int width, int height ) { // Obtain properties of frame and producer mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); mlt_producer producer = &self->parent; // Get index and pixbuf int current_idx = refresh_pixbuf( self, frame ); // optimization for subsequent iterations on single picture if ( current_idx != self->image_idx || width != self->width || height != self->height ) self->image = NULL; mlt_log_debug( MLT_PRODUCER_SERVICE( producer ), "image %p pixbuf %p idx %d current_idx %d pixbuf_idx %d width %d\n", self->image, self->pixbuf, current_idx, self->image_idx, self->pixbuf_idx, width ); // If we have a pixbuf and we need an image if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) ) ) { char *interps = mlt_properties_get( properties, "rescale.interp" ); if ( interps ) interps = strdup( interps ); int interp = GDK_INTERP_BILINEAR; if ( !interps ) { // Keep bilinear by default } else if ( strcmp( interps, "nearest" ) == 0 ) interp = GDK_INTERP_NEAREST; else if ( strcmp( interps, "tiles" ) == 0 ) interp = GDK_INTERP_TILES; else if ( strcmp( interps, "hyper" ) == 0 || strcmp( interps, "bicubic" ) == 0 ) interp = GDK_INTERP_HYPER; free( interps ); // Note - the original pixbuf is already safe and ready for destruction pthread_mutex_lock( &g_mutex ); GdkPixbuf* pixbuf = gdk_pixbuf_scale_simple( self->pixbuf, width, height, interp ); // Store width and height self->width = width; self->height = height; // Allocate/define image int has_alpha = gdk_pixbuf_get_has_alpha( pixbuf ); int src_stride = gdk_pixbuf_get_rowstride( pixbuf ); int dst_stride = self->width * ( has_alpha ? 4 : 3 ); int image_size = dst_stride * ( height + 1 ); self->image = mlt_pool_alloc( image_size ); self->alpha = NULL; self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24; if ( src_stride != dst_stride ) { int y = self->height; uint8_t *src = gdk_pixbuf_get_pixels( pixbuf ); uint8_t *dst = self->image; while ( y-- ) { memcpy( dst, src, dst_stride ); dst += dst_stride; src += src_stride; } } else { memcpy( self->image, gdk_pixbuf_get_pixels( pixbuf ), src_stride * height ); } pthread_mutex_unlock( &g_mutex ); // Convert image to requested format if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) { uint8_t *buffer = NULL; // First, set the image so it can be converted when we get it mlt_frame_replace_image( frame, self->image, self->format, width, height ); mlt_frame_set_image( frame, self->image, image_size, mlt_pool_release ); self->format = format; // get_image will do the format conversion mlt_frame_get_image( frame, &buffer, &format, &width, &height, 0 ); // cache copies of the image and alpha buffers if ( buffer ) { image_size = mlt_image_format_size( format, width, height, NULL ); self->image = mlt_pool_alloc( image_size ); memcpy( self->image, buffer, image_size ); } if ( ( buffer = mlt_frame_get_alpha_mask( frame ) ) ) { self->alpha = mlt_pool_alloc( width * height ); memcpy( self->alpha, buffer, width * height ); } } // Update the cache mlt_cache_item_close( self->image_cache ); mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", self->image, image_size, mlt_pool_release ); self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" ); self->image_idx = current_idx; mlt_cache_item_close( self->alpha_cache ); self->alpha_cache = NULL; if ( self->alpha ) { mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha", self->alpha, width * height, mlt_pool_release ); self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" ); } // Finished with pixbuf now g_object_unref( pixbuf ); } // Set width/height of frame mlt_properties_set_int( properties, "width", self->width ); mlt_properties_set_int( properties, "height", self->height ); }