diff options
author | Havoc Pennington <hp@redhat.com> | 2000-10-18 18:42:54 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2000-10-18 18:42:54 +0000 |
commit | 7a4c68938789206bfec3c6d15cc4bb922daf6443 (patch) | |
tree | e5f031fc609e50a8b7b12e7d6abf63cc78cc88e7 | |
parent | 7420908815651a1ff2ceb1c0fb5e92fe9b260619 (diff) | |
download | gtk+-7a4c68938789206bfec3c6d15cc4bb922daf6443.tar.gz |
Some updates
2000-10-18 Havoc Pennington <hp@redhat.com>
* gtk/gtk-sections.txt: Some updates
* gdk/gdk-sections.txt: remove GdkPixbufAlphaMode
* gdk-pixbuf/gdk-pixbuf-sections.txt: Add new API, remove
GdkPixbufClass/GdkAnimationClass since those are private
* gdk-pixbuf/Makefile.am (IGNORE_HFILES): ignore more headers
2000-10-18 Havoc Pennington <hp@redhat.com>
* gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug
where any number of empty lines would get skipped
* gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the
edge.
* gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the
warning about invalid iterators (explain more thoroughly)
(gtk_text_iter_in_region): rename gtk_text_iter_in_range
* gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less
big
* demos/*.c: Add error handling
* gtk/gtktextbuffer.c: don't modify const iterators
* gtk/gdk-pixbuf-loader.c: Add full error handling here
* gtk/gtkimage.c (gtk_image_set_from_file): ignore errors
on file load
* gtk/gtkiconfactory.c: Update to reflect addition of error
handling to gdk-pixbuf loaders
2000-10-16 Havoc Pennington <hp@redhat.com>
* gdk-pixbuf-io.c (gdk_pixbuf_get_module)
(gdk_pixbuf_get_named_module) (gdk_pixbuf_load_module):
add error reporting here also
* make-inline-pixbuf.c (main): use GError
* io-xpm.c: include unistd.h
* gdk-pixbuf-util.c: include string.h
* io-*.c: add error reporting
* gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file): add
error reporting
* gdk-pixbuf-io.c (gdk_pixbuf_new_from_file): Add error reporting
* gdk-pixbuf-io.h: Add GError** to load_increment and load
methods
* gdk-pixbuf-io.c (gdk_pixbuf_save) (gdk_pixbuf_savev): return
a G_FILE_ERROR if we fail to write or close the file.
* gdk-pixbuf.h: remove GDK_PIXBUF_ERROR_IO, instead we'll use
G_FILE_ERROR_*. Rename enum to GdkPixbufError, properly following
the GError naming rules. Add GError** to load functions.
67 files changed, 2158 insertions, 1654 deletions
@@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 6ab2943246..1a2399d2df 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,4 +1,31 @@ -Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtktextiter.c (gtk_text_iter_forward_to_newline): Fix a bug + where any number of empty lines would get skipped + + * gtk/gtktextiter.h: Remove padding from GtkTextIter; live on the + edge. + + * gtk/gtktextiter.c (gtk_text_iter_make_surreal): enhance the + warning about invalid iterators (explain more thoroughly) + (gtk_text_iter_in_region): rename gtk_text_iter_in_range + + * gtk/gtktextview.c (FOCUS_EDGE_WIDTH): Make focus rectangle less + big + + * demos/*.c: Add error handling + + * gtk/gtktextbuffer.c: don't modify const iterators + + * gtk/gdk-pixbuf-loader.c: Add full error handling here + + * gtk/gtkimage.c (gtk_image_set_from_file): ignore errors + on file load + + * gtk/gtkiconfactory.c: Update to reflect addition of error + handling to gdk-pixbuf loaders + +Wed Oct 18 11:14:05 2000 Owen Taylor <otaylor@redhat.com> * configure.in demos/Makefile.am demos/testgtk/*: Start of work to move to new modularized testgtk. diff --git a/demos/pixbuf-demo.c b/demos/pixbuf-demo.c index 528101d3e4..ae9a0998e2 100644 --- a/demos/pixbuf-demo.c +++ b/demos/pixbuf-demo.c @@ -65,7 +65,11 @@ load_pixbufs (void) { int i; - background = gdk_pixbuf_new_from_file (BACKGROUND_NAME); + /* We pass NULL for the error return location, we don't care + * about the error message. + */ + + background = gdk_pixbuf_new_from_file (BACKGROUND_NAME, NULL); if (!background) return FALSE; @@ -73,7 +77,7 @@ load_pixbufs (void) back_height = gdk_pixbuf_get_height (background); for (i = 0; i < N_IMAGES; i++) { - images[i] = gdk_pixbuf_new_from_file (image_names[i]); + images[i] = gdk_pixbuf_new_from_file (image_names[i], NULL); if (!images[i]) return FALSE; } diff --git a/demos/testanimation.c b/demos/testanimation.c index 35f981b2eb..fcfbde739f 100644 --- a/demos/testanimation.c +++ b/demos/testanimation.c @@ -408,8 +408,18 @@ main (int argc, char **argv) return 0; } else { for (i = 1; i < argc; i++) { - animation = gdk_pixbuf_animation_new_from_file (argv[i]); - + GError *error; + + error = NULL; + animation = gdk_pixbuf_animation_new_from_file (argv[i], + &error); + + if (animation == NULL) { + g_warning ("Failed to load animation: %s", + error->message); + g_error_free (error); + } + if (animation) { gint i = 0; GList *listptr; diff --git a/demos/testpixbuf-scale.c b/demos/testpixbuf-scale.c index 932d13cf4b..68b57a5bca 100644 --- a/demos/testpixbuf-scale.c +++ b/demos/testpixbuf-scale.c @@ -62,7 +62,8 @@ main(int argc, char **argv) GtkWidget *hbox, *label, *hscale; GtkAdjustment *adjustment; GtkRequisition scratch_requisition; - + GError *error; + pixbuf_init (); gtk_init (&argc, &argv); @@ -73,9 +74,12 @@ main(int argc, char **argv) exit (1); } - pixbuf = gdk_pixbuf_new_from_file (argv[1]); + error = NULL; + pixbuf = gdk_pixbuf_new_from_file (argv[1], &error); if (!pixbuf) { - fprintf (stderr, "Cannot load %s\n", argv[1]); + fprintf (stderr, "Cannot load image: %s\n", + error->message); + g_error_free (error); exit(1); } diff --git a/demos/testpixbuf.c b/demos/testpixbuf.c index f118205e21..fac01f6b87 100644 --- a/demos/testpixbuf.c +++ b/demos/testpixbuf.c @@ -428,22 +428,27 @@ static gint update_timeout(gpointer data) { ProgressFileStatus *status = data; - gboolean done, error; + gboolean done; + GError *error; done = FALSE; error = FALSE; if (!feof(status->imagefile)) { gint nbytes; - + nbytes = fread(status->buf, 1, status->readlen, status->imagefile); - error = !gdk_pixbuf_loader_write (GDK_PIXBUF_LOADER (status->loader), status->buf, nbytes); - if (error) { - G_BREAKPOINT(); + error = NULL; + if (!gdk_pixbuf_loader_write (GDK_PIXBUF_LOADER (status->loader), status->buf, nbytes, &error)) { + g_warning ("Error writing to loader: %s", + error->message); + g_error_free (error); + done = TRUE; } - + + } else { /* Really done */ GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (status->loader); @@ -452,11 +457,6 @@ update_timeout(gpointer data) } - if (error) { - g_warning ("Serious error writing to loader"); - done = TRUE; - } - if (done) { gtk_widget_queue_draw(*status->rgbwin); gdk_pixbuf_loader_close (GDK_PIXBUF_LOADER (status->loader)); @@ -556,17 +556,26 @@ main (int argc, char **argv) } /* Test loading from inline data. */ - pixbuf = gdk_pixbuf_new_from_inline (apple_red, FALSE, -1); + pixbuf = gdk_pixbuf_new_from_inline (apple_red, FALSE, -1, NULL); new_testrgb_window (pixbuf, "Red apple from inline data"); - pixbuf = gdk_pixbuf_new_from_inline (gnome_foot, TRUE, sizeof (gnome_foot)); + pixbuf = gdk_pixbuf_new_from_inline (gnome_foot, TRUE, sizeof (gnome_foot), NULL); new_testrgb_window (pixbuf, "Foot from inline data"); found_valid = TRUE; } else { for (i = 1; i < argc; i++) { + GError *error; + + error = NULL; + pixbuf = gdk_pixbuf_new_from_file (argv[i], &error); - pixbuf = gdk_pixbuf_new_from_file (argv[i]); + if (pixbuf == NULL) { + g_warning ("Error loading image: %s", + error->message); + g_error_free (error); + } + #if 0 pixbuf = gdk_pixbuf_rotate(pixbuf, 10.0); #endif diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 695d665520..5180f2406c 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,14 @@ +2000-10-18 Havoc Pennington <hp@redhat.com> + + * gtk/gtk-sections.txt: Some updates + + * gdk/gdk-sections.txt: remove GdkPixbufAlphaMode + + * gdk-pixbuf/gdk-pixbuf-sections.txt: Add new API, remove + GdkPixbufClass/GdkAnimationClass since those are private + + * gdk-pixbuf/Makefile.am (IGNORE_HFILES): ignore more headers + 2000-10-06 Havoc Pennington <hp@redhat.com> * gdk-pixbuf/*.sgml, gdk-pixbuf/tmpl/*.sgml: copy in from 1.0 diff --git a/docs/reference/gdk-pixbuf/Makefile.am b/docs/reference/gdk-pixbuf/Makefile.am index b399994664..70eb077119 100644 --- a/docs/reference/gdk-pixbuf/Makefile.am +++ b/docs/reference/gdk-pixbuf/Makefile.am @@ -14,7 +14,7 @@ SECOND_DOC_SOURCE_DIR=$(top_srcdir)/contrib/gdk-pixbuf-xlib FIXXREF_OPTIONS= # Header files to ignore when scanning -IGNORE_HFILES=pixops.h pixops-internal.h gdk-pixbuf-xlib-private.h +IGNORE_HFILES=pixops.h pixops-internal.h gdk-pixbuf-xlib-private.h gdk-pixbuf-i18n.h gdk-pixbuf-private.h # Extra files to add when scanning EXTRA_HFILES= \ diff --git a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt index 39fc15ddc6..a721ece386 100644 --- a/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt +++ b/docs/reference/gdk-pixbuf/gdk-pixbuf-sections.txt @@ -17,9 +17,11 @@ GDK_PIXBUF_MICRO <SECTION> <FILE>gdk-pixbuf</FILE> +GdkPixbufError +GDK_PIXBUF_ERROR GdkColorspace +GdkPixbufAlphaMode GdkPixbuf -GdkPixbufClass gdk_pixbuf_get_colorspace gdk_pixbuf_get_n_channels gdk_pixbuf_get_has_alpha @@ -33,12 +35,10 @@ gdk_pixbuf_get_rowstride GDK_PIXBUF GDK_TYPE_PIXBUF GDK_IS_PIXBUF -GDK_IS_PIXBUF_CLASS -GDK_PIXBUF_CLASS -GDK_PIXBUF_GET_CLASS <SUBSECTION Private> gdk_pixbuf_get_type +gdk_pixbuf_error_quark </SECTION> <SECTION> @@ -54,10 +54,17 @@ gdk_pixbuf_new_from_file </SECTION> <SECTION> +<FILE>file-saving</FILE> +gdk_pixbuf_savev +gdk_pixbuf_save +</SECTION> + +<SECTION> <FILE>creating</FILE> gdk_pixbuf_new gdk_pixbuf_new_from_data gdk_pixbuf_new_from_xpm_data +gdk_pixbuf_new_from_inline gdk_pixbuf_copy </SECTION> @@ -65,6 +72,7 @@ gdk_pixbuf_copy <FILE>util</FILE> gdk_pixbuf_add_alpha gdk_pixbuf_copy_area +gdk_pixbuf_saturate_and_pixelate </SECTION> <SECTION> @@ -72,7 +80,6 @@ gdk_pixbuf_copy_area GdkPixbufFrameAction GdkPixbufFrame GdkPixbufAnimation -GdkPixbufAnimationClass gdk_pixbuf_animation_new_from_file gdk_pixbuf_animation_ref gdk_pixbuf_animation_unref @@ -88,10 +95,7 @@ gdk_pixbuf_frame_get_x_offset <SUBSECTION Standard> GDK_PIXBUF_ANIMATION -GDK_PIXBUF_ANIMATION_CLASS GDK_TYPE_PIXBUF_ANIMATION -GDK_PIXBUF_ANIMATION_GET_CLASS -GDK_IS_PIXBUF_ANIMATION_CLASS GDK_IS_PIXBUF_ANIMATION <SUBSECTION Private> diff --git a/docs/reference/gdk-pixbuf/tmpl/animation.sgml b/docs/reference/gdk-pixbuf/tmpl/animation.sgml index 6a64ac85dd..c8bff9b017 100644 --- a/docs/reference/gdk-pixbuf/tmpl/animation.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/animation.sgml @@ -41,11 +41,6 @@ frame. action. </para> -@pixbuf: -@x_offset: -@y_offset: -@delay_time: -@action: <!-- ##### STRUCT GdkPixbufAnimation ##### --> <para> @@ -53,17 +48,6 @@ frame. list of #GdkPixbufFrame structures. </para> -@parent_instance: -@n_frames: -@frames: -@width: -@height: - -<!-- ##### STRUCT GdkPixbufAnimationClass ##### --> -<para> - -</para> - <!-- ##### FUNCTION gdk_pixbuf_animation_new_from_file ##### --> <para> @@ -71,6 +55,7 @@ frame. </para> @filename: +@error: @Returns: diff --git a/docs/reference/gdk-pixbuf/tmpl/creating.sgml b/docs/reference/gdk-pixbuf/tmpl/creating.sgml index 74cbe81590..b98b4024fa 100644 --- a/docs/reference/gdk-pixbuf/tmpl/creating.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/creating.sgml @@ -82,6 +82,18 @@ Creating a pixbuf from image data that is already in memory. @Returns: +<!-- ##### FUNCTION gdk_pixbuf_new_from_inline ##### --> +<para> + +</para> + +@inline_pixbuf: +@copy_pixels: +@length: +@error: +@Returns: + + <!-- ##### FUNCTION gdk_pixbuf_copy ##### --> <para> diff --git a/docs/reference/gdk-pixbuf/tmpl/file-loading.sgml b/docs/reference/gdk-pixbuf/tmpl/file-loading.sgml index 3f00def6c4..7025c7edd5 100644 --- a/docs/reference/gdk-pixbuf/tmpl/file-loading.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/file-loading.sgml @@ -31,6 +31,7 @@ Loading a pixbuf from a file. </para> @filename: +@error: @Returns: <!-- Local variables: mode: sgml diff --git a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-loader.sgml b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-loader.sgml index 6ad7d7b913..8d5ba404d1 100644 --- a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-loader.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-loader.sgml @@ -88,6 +88,7 @@ Application-driven progressive image loading. </para> @image_type: +@error: @Returns: @@ -99,6 +100,7 @@ Application-driven progressive image loading. @loader: @buf: @count: +@error: @Returns: diff --git a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml index 094a3a188a..456531628e 100644 --- a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf-unused.sgml @@ -1,7 +1,3 @@ -<!-- ##### SECTION ./tmpl/from-drawables.sgml:Title ##### --> -Drawables to Pixbufs - - <!-- ##### USER_FUNCTION GdkPixbufLastUnref ##### --> <para> A function of this type can be used to override the default @@ -19,6 +15,10 @@ Drawables to Pixbufs @pixbuf: The pixbuf that is losing its last reference. @data: User closure data. +<!-- ##### SECTION ./tmpl/from-drawables.sgml:Title ##### --> +Drawables to Pixbufs + + <!-- ##### ARG GnomeCanvasPixbuf:height_pixels ##### --> <para> @@ -415,13 +415,19 @@ XlibRGB </para> +<!-- ##### SECTION ./tmpl/xlib-from-drawables.sgml:See_Also ##### --> +<para> + +</para> + + <!-- ##### SECTION ./tmpl/from-drawables.sgml:See_Also ##### --> <para> gdk_image_get(). </para> -<!-- ##### SECTION ./tmpl/xlib-from-drawables.sgml:See_Also ##### --> +<!-- ##### STRUCT GdkPixbufAnimationClass ##### --> <para> </para> @@ -503,26 +509,7 @@ Getting parts of a drawable's image data into a pixbuf. </para> -<!-- ##### ENUM GdkPixbufAlphaMode ##### --> - <para> - These values can be passed to - gdk_pixbuf_render_to_drawable_alpha() to control how the alpha - chanel of an image should be handled. This function can create a - bilevel clipping mask (black and white) and use it while painting - the image. In the future, when the X Window System gets an alpha - channel extension, it will be possible to do full alpha - compositing onto arbitrary drawables. For now both cases fall - back to a bilevel clipping mask. - </para> - -@GDK_PIXBUF_ALPHA_BILEVEL: A bilevel clipping mask (black and white) -will be created and used to draw the image. Pixels below 0.5 opacity -will be considered fully transparent, and all others will be -considered fully opaque. -@GDK_PIXBUF_ALPHA_FULL: For now falls back to #GDK_PIXBUF_ALPHA_BILEVEL. -In the future it will do full alpha compositing. - -<!-- ##### SECTION ./tmpl/gdk-pixbuf-io.sgml:Long_Description ##### --> +<!-- ##### STRUCT GdkPixbufClass ##### --> <para> </para> @@ -697,6 +684,12 @@ In the future it will do full alpha compositing. </refsect2> +<!-- ##### SECTION ./tmpl/gdk-pixbuf-io.sgml:Long_Description ##### --> +<para> + +</para> + + <!-- ##### SECTION ./tmpl/xlib-rendering.sgml:Title ##### --> Xlib Rendering diff --git a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml index 08b549d0fc..403941efa9 100644 --- a/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/gdk-pixbuf.sgml @@ -15,6 +15,25 @@ Information that describes an image. <para> </para> +<!-- ##### ENUM GdkPixbufError ##### --> +<para> + +</para> + +@GDK_PIXBUF_ERROR_CORRUPT_IMAGE: +@GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY: +@GDK_PIXBUF_ERROR_BAD_OPTION_VALUE: +@GDK_PIXBUF_ERROR_UNKNOWN_TYPE: +@GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION: +@GDK_PIXBUF_ERROR_FAILED: + +<!-- ##### MACRO GDK_PIXBUF_ERROR ##### --> +<para> + +</para> + + + <!-- ##### ENUM GdkColorspace ##### --> <para> This enumeration defines the color spaces that are supported by @@ -23,6 +42,25 @@ Information that describes an image. @GDK_COLORSPACE_RGB: Indicates a red/green/blue additive color space. +<!-- ##### ENUM GdkPixbufAlphaMode ##### --> + <para> + These values can be passed to + gdk_pixbuf_render_to_drawable_alpha() to control how the alpha + chanel of an image should be handled. This function can create a + bilevel clipping mask (black and white) and use it while painting + the image. In the future, when the X Window System gets an alpha + channel extension, it will be possible to do full alpha + compositing onto arbitrary drawables. For now both cases fall + back to a bilevel clipping mask. + </para> + +@GDK_PIXBUF_ALPHA_BILEVEL: A bilevel clipping mask (black and white) +will be created and used to draw the image. Pixels below 0.5 opacity +will be considered fully transparent, and all others will be +considered fully opaque. +@GDK_PIXBUF_ALPHA_FULL: For now falls back to #GDK_PIXBUF_ALPHA_BILEVEL. +In the future it will do full alpha compositing. + <!-- ##### STRUCT GdkPixbuf ##### --> <para> This is the main structure in the &gdk-pixbuf; library. It is @@ -31,23 +69,6 @@ Information that describes an image. height, and the rowstride or number of bytes between rows. </para> -@parent_instance: -@colorspace: -@n_channels: -@bits_per_sample: -@width: -@height: -@rowstride: -@pixels: -@destroy_fn: -@destroy_fn_data: -@has_alpha: - -<!-- ##### STRUCT GdkPixbufClass ##### --> -<para> - -</para> - <!-- ##### FUNCTION gdk_pixbuf_get_colorspace ##### --> <para> diff --git a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml index c0a33f2eee..734ee8034a 100644 --- a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml @@ -77,6 +77,8 @@ Module Interface @buffer: @size: +@filename: +@error: @Returns: @@ -86,6 +88,7 @@ Module Interface </para> @name: +@error: @Returns: @@ -95,5 +98,7 @@ Module Interface </para> @image_module: +@error: +@Returns: diff --git a/docs/reference/gdk-pixbuf/tmpl/util.sgml b/docs/reference/gdk-pixbuf/tmpl/util.sgml index fc429f4244..35726a967b 100644 --- a/docs/reference/gdk-pixbuf/tmpl/util.sgml +++ b/docs/reference/gdk-pixbuf/tmpl/util.sgml @@ -50,3 +50,14 @@ End: --> +<!-- ##### FUNCTION gdk_pixbuf_saturate_and_pixelate ##### --> +<para> + +</para> + +@src: +@dest: +@saturation: +@pixelate: + + diff --git a/docs/reference/gdk/gdk-sections.txt b/docs/reference/gdk/gdk-sections.txt index fd033c63a4..f5900c0de8 100644 --- a/docs/reference/gdk/gdk-sections.txt +++ b/docs/reference/gdk/gdk-sections.txt @@ -156,7 +156,6 @@ gdk_rgb_set_verbose <SECTION> <TITLE>Pixbufs</TITLE> <FILE>pixbufs</FILE> -GdkPixbufAlphaMode gdk_pixbuf_render_threshold_alpha gdk_pixbuf_render_to_drawable gdk_pixbuf_render_to_drawable_alpha diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 430e442de7..2b2412ce5c 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -1938,15 +1938,19 @@ gtk_text_buffer_insert gtk_text_buffer_insert_at_cursor gtk_text_buffer_insert_interactive gtk_text_buffer_insert_interactive_at_cursor +gtk_text_buffer_insert_range gtk_text_buffer_delete gtk_text_buffer_delete_interactive +gtk_text_buffer_set_text gtk_text_buffer_get_text gtk_text_buffer_get_slice -gtk_text_buffer_insert_pixmap +gtk_text_buffer_insert_pixbuf gtk_text_buffer_create_mark gtk_text_buffer_move_mark gtk_text_buffer_delete_mark +gtk_text_buffer_delete_mark_by_name gtk_text_buffer_get_mark +gtk_text_buffer_get_insert gtk_text_buffer_place_cursor gtk_text_buffer_apply_tag gtk_text_buffer_remove_tag @@ -1970,9 +1974,6 @@ gtk_text_buffer_cut gtk_text_buffer_copy gtk_text_buffer_paste_clipboard gtk_text_buffer_get_selection_bounds -gtk_text_buffer_find_string -gtk_text_buffer_find_regexp -gtk_text_buffer_spew <SUBSECTION Standard> GTK_TEXT_BUFFER GTK_IS_TEXT_BUFFER @@ -2000,7 +2001,7 @@ gtk_text_iter_get_slice gtk_text_iter_get_text gtk_text_iter_get_visible_slice gtk_text_iter_get_visible_text -gtk_text_iter_get_pixmap +gtk_text_iter_get_pixbuf gtk_text_iter_get_marks gtk_text_iter_get_toggled_tags gtk_text_iter_begins_tag @@ -2040,7 +2041,7 @@ gtk_text_iter_forward_search gtk_text_iter_backward_search gtk_text_iter_equal gtk_text_iter_compare -gtk_text_iter_in_region +gtk_text_iter_in_range gtk_text_iter_reorder gtk_text_iter_spew </SECTION> @@ -2053,7 +2054,7 @@ gtk_text_mark_set_visible gtk_text_mark_is_visible gtk_text_mark_ref gtk_text_mark_unref -gtk_text_mark_deleted +gtk_text_mark_get_deleted </SECTION> <SECTION> @@ -2107,15 +2108,11 @@ GTK_TEXT_TAG_TABLE_GET_CLASS <SECTION> <FILE>gtktextview</FILE> GtkTextView -GtkTextViewMovementStep -GtkTextViewScrollType -GtkTextViewDeleteType <TITLE>GtkTextView</TITLE> gtk_text_view_new gtk_text_view_new_with_buffer gtk_text_view_set_buffer gtk_text_view_get_buffer -gtk_text_view_get_iter_at_pixel gtk_text_view_scroll_to_mark gtk_text_view_move_mark_onscreen gtk_text_view_place_cursor_onscreen @@ -2514,7 +2511,6 @@ gtk_widget_get_ancestor gtk_widget_get_colormap gtk_widget_set_colormap gtk_widget_get_visual -gtk_widget_set_visual gtk_widget_get_events gtk_widget_get_pointer gtk_widget_is_ancestor @@ -2527,14 +2523,11 @@ gtk_widget_restore_default_style gtk_widget_reset_rc_styles gtk_widget_push_style gtk_widget_push_colormap -gtk_widget_push_visual gtk_widget_pop_style gtk_widget_pop_colormap -gtk_widget_pop_visual gtk_widget_set_default_style gtk_widget_set_default_colormap gtk_widget_get_default_style -gtk_widget_set_default_visual gtk_widget_get_default_colormap gtk_widget_get_default_visual gtk_widget_set_direction diff --git a/docs/reference/gtk/tmpl/gtk-unused.sgml b/docs/reference/gtk/tmpl/gtk-unused.sgml index ca67652dd7..a359c75d41 100644 --- a/docs/reference/gtk/tmpl/gtk-unused.sgml +++ b/docs/reference/gtk/tmpl/gtk-unused.sgml @@ -12,6 +12,30 @@ Debugging </para> +<!-- ##### SECTION ./tmpl/gtkclipboard.sgml:See_Also ##### --> +<para> +<variablelist> + +<varlistentry> +<term>#GtkSelection</term> +<listitem><para>@GtkClipboard provides a high-level wrapper around the + lower level routines that deal with X selections. It is + also possibly to directly manipulate the X selections, + though it is seldom necessary to do so.</para></listitem> +</varlistentry> + +</variablelist> +</para> + + +<!-- ##### FUNCTION gtk_clipboard_get ##### --> +<para> + +</para> + +@selection: +@Returns: + <!-- ##### SECTION ./tmpl/gtkmenufactory.sgml:Short_Description ##### --> @@ -43,6 +67,14 @@ Debugging </para> +<!-- ##### MACRO gtk_widget_set_default_visual ##### --> +<para> + +</para> + +@v: +@visual: + <!-- ##### FUNCTION gtk_window_set_focus ##### --> <para> @@ -117,6 +149,21 @@ A structure used to return values from @gtk_type_query. @object_size: @class_size: +<!-- ##### MACRO gtk_widget_pop_visual ##### --> +<para> + +</para> + +@v: + +<!-- ##### FUNCTION gtk_text_buffer_get_clipboard_contents ##### --> +<para> + +</para> + +@buffer: +@Returns: + <!-- ##### FUNCTION gtk_marshal_NONE__C_CALLBACK ##### --> <para> @@ -127,6 +174,17 @@ A structure used to return values from @gtk_type_query. @func_data: @args: +<!-- ##### FUNCTION gtk_text_buffer_paste_primary_selection ##### --> +<para> + +</para> + +@buffer: +@override_location: +@time: +@interactive: +@default_editable: + <!-- ##### FUNCTION gtk_marshal_BOOL__POINTER_INT_INT ##### --> <para> @@ -137,6 +195,64 @@ A structure used to return values from @gtk_type_query. @func_data: @args: +<!-- ##### FUNCTION gtk_clipboard_set_with_data ##### --> +<para> + +</para> + +@clipboard: +@targets: +@n_targets: +@get_func: +@clear_func: +@user_data: +@Returns: + +<!-- ##### SIGNAL GtkTextView::copy-text ##### --> +<para> + +</para> + +@textview: the object which received the signal. + +<!-- ##### FUNCTION gtk_text_view_get_iter_at_pixel ##### --> +<para> + +</para> + +@text_view: +@iter: +@x: +@y: + +<!-- ##### USER_FUNCTION GtkClipboardReceivedFunc ##### --> +<para> + A function to be called when the results of gtk_clipboard_request_text() + are received, or when the request fails. +</para> + +@clipboard: the #GtkClipboard +@selection_data: a #GtkSelectionData containing the data was received. + If retrieving the data failed, then then length field + of @selection_data will be negative. +@data: the @user_data supplied to gtk_clipboard_request_contents(). + +<!-- ##### FUNCTION gtk_clipboard_clear ##### --> +<para> + +</para> + +@clipboard: + +<!-- ##### FUNCTION gtk_clipboard_wait_for_contents ##### --> +<para> + +</para> + +@clipboard: +@target: +@Returns: + <!-- ##### SECTION ./tmpl/gtkenums.sgml.sgml:Short_Description ##### --> @@ -184,6 +300,14 @@ Get the type of GtkIdentifier. @func_data: @args: +<!-- ##### FUNCTION gtk_text_mark_deleted ##### --> +<para> + +</para> + +@mark: +@Returns: + <!-- ##### MACRO gtk_marshal_BOOL__POINTER_STRING_STRING_POINTER ##### --> <para> @@ -197,6 +321,15 @@ Get the type of GtkIdentifier. @ruler: the gtkruler +<!-- ##### FUNCTION gtk_selection_data_set_text ##### --> +<para> + +</para> + +@selection_data: +@str: +@Returns: + <!-- ##### FUNCTION gtk_themes_init ##### --> <para> @@ -225,6 +358,16 @@ Menu Factory </para> +<!-- ##### MACRO gtk_widget_set_visual ##### --> +<para> + +</para> + +@w: +@v: +@widget: +@visual: + <!-- ##### MACRO gtk_marshal_NONE__UINT_POINTER_UINT_ENUM_ENUM_POINTER ##### --> <para> @@ -265,6 +408,17 @@ Convert a gtk type into its sequence number </para> +<!-- ##### USER_FUNCTION GtkClipboardClearFunc ##### --> +<para> +A function that will be called when the contents of the clipboard are changed +or cleared. Once this has called, the @user_data_or_owner argument +will not be used again. +</para> + +@clipboard: the #GtkClipboard +@user_data_or_owner: the @user_data argument passed to gtk_clipboard_set_with_data(), or + the @owner argument passed to gtk_clipboard_set_owner() + <!-- ##### MACRO GTK_WIDGET_IS_OFFSCREEN ##### --> <para> @@ -282,6 +436,13 @@ Convert a gtk type into its sequence number +<!-- ##### SIGNAL GtkTextView::cut-text ##### --> +<para> + +</para> + +@textview: the object which received the signal. + <!-- ##### FUNCTION gtk_marshal_BOOL__POINTER ##### --> <para> @@ -292,6 +453,35 @@ Convert a gtk type into its sequence number @func_data: @args: +<!-- ##### ARG GtkTextTag:overstrike_set ##### --> +<para> + +</para> + + +<!-- ##### FUNCTION gtk_text_buffer_cut ##### --> +<para> + +</para> + +@buffer: +@time: +@interactive: +@default_editable: + +<!-- ##### ENUM GtkTextViewMovementStep ##### --> +<para> + +</para> + +@GTK_TEXT_MOVEMENT_CHAR: +@GTK_TEXT_MOVEMENT_POSITIONS: +@GTK_TEXT_MOVEMENT_WORD: +@GTK_TEXT_MOVEMENT_WRAPPED_LINE: +@GTK_TEXT_MOVEMENT_LINE: +@GTK_TEXT_MOVEMENT_LINE_ENDS: +@GTK_TEXT_MOVEMENT_BUFFER_ENDS: + <!-- ##### FUNCTION gtk_marshal_NONE__POINTER_POINTER_INT_INT ##### --> <para> @@ -302,6 +492,72 @@ Convert a gtk type into its sequence number @func_data: @args: +<!-- ##### SECTION ./tmpl/gtkclipboard.sgml:Long_Description ##### --> + <para> + The #GtkClipboard object represents a clipboard of data shared + between different processes or between different widgets in + the same process. Each clipboard is identified by a name encoded as a + #GdkAtom. (Conversion to and from strings can be done with + gdk_atom_intern() and gdk_atom_name().) The default clipboard + corresponds to the CLIPBOARD atom; another commonly used clipboard + is the PRIMARY clipboard, which, in X, traditionally contains + the currently selected text. + </para> + <para> + To support having a number of different formats on the clipboard + at the same time, the clipboard mechanism allows providing + callbacks instead of the actual data. When you set the contents + of the clipboard, you can either supply the data directly (via + functions like gtk_clipboard_set_text()), or you can supply a + callback to be called at a later time when the data is needed (via + gtk_clipboard_set_with_data() or gtk_clipboard_set_with_owner().) + Providing a callback also avoids having to make copies of the data + when it is not needed. + </para> + <para> + gtk_clipboard_set_with_data() and gtk_clipboard_set_with_owner() + are quite similar; the choice between the two depends mostly on + which is more convenient in a particular situation. + The former is most useful when you want to have a blob of data + with callbacks to convert it into the various data types that you + advertise. When the @clear_func you provided is called, you + simply free the data blob. The latter is more useful when the + contents of clipboard reflect the internal state of a @GObject + (As an example, for the PRIMARY clipboard, when an entry widget + provides the clipboard's contents the contents are simply the + text within the selected region.) If the contents change, the + entry widget can call gtk_clipboard_set_with_owner() to update + the timestamp for clipboard ownership, without having to worry + about @clear_func being called. + </para> + <para> + Requesting the data from the clipboard is essentially + asynchronous. If the contents of the clipboard are provided within + the same process, then a direct function call will be made to + retrieve the data, but if they are provided by another process, + then the data needs to be retrieved from the other process, which + may take some time. To avoid blocking the user interface, the call + to request the selection, gtk_clipboard_request_contents() takes a + callback that will be called when the contents are received (or + when the request fails.) If you don't want to deal with providing + a separate callback, you can also use gtk_clipboard_wait_for_contents(). + What this does is run the Glib main loop recursively waiting for + the contents. This can simplify the code flow, but you still have + to be aware that other callbacks in your program can be called + while this recursive mainloop is running. + </para> + <para> + Along with the functions to get the clipboard contents as an + arbitrary data chunk, there are also functions to retrieve + it as text, gtk_clipboard_request_text() and + gtk_clipboard_wait_for_text(). These functions take care of + determining which formats are advertised by the clipboard + provider, asking for the clipboard in the best available format + and converting the results into the UTF-8 encoding. (The standard + form for representing strings in GTK+.) + </para> + + <!-- ##### SECTION ./tmpl/gtkdebug.sgml:See_Also ##### --> <para> @@ -324,6 +580,18 @@ Convert a gtk type into its sequence number @entries: @nentries: +<!-- ##### FUNCTION gtk_text_buffer_find_string ##### --> +<para> + +</para> + +@buffer: +@iter: +@str: +@start: +@end: +@Returns: + <!-- ##### FUNCTION gtk_marshal_NONE__INT_POINTER_INT_INT_INT_POINTER ##### --> <para> @@ -429,6 +697,10 @@ Get the number of signals defined by this object. @subfactory: @path: +<!-- ##### SECTION ./tmpl/gtkclipboard.sgml:Short_Description ##### --> +Storing data on Clipboards. + + <!-- ##### FUNCTION gtk_type_children_types ##### --> <para> Return the pointer to the type's children's types. @@ -447,6 +719,22 @@ Register a new set of flags @values and give them the name in @values: GtkFlagValue* @Returns: +<!-- ##### SIGNAL GtkTextView::scroll-text ##### --> +<para> + +</para> + +@textview: the object which received the signal. +@arg1: + +<!-- ##### FUNCTION gtk_selection_clear_targets ##### --> +<para> + +</para> + +@widget: +@selection: + <!-- ##### ENUM GtkPrivateFlags ##### --> <para> @@ -484,6 +772,16 @@ show the size if @show_size is true. @type: GtkType @show_size: gboolean +<!-- ##### FUNCTION gtk_clipboard_request_contents ##### --> +<para> + +</para> + +@clipboard: +@target: +@callback: +@user_data: + <!-- ##### FUNCTION gtk_marshal_BOOL__POINTER_INT_INT_INT ##### --> <para> @@ -494,6 +792,14 @@ show the size if @show_size is true. @func_data: @args: +<!-- ##### FUNCTION gtk_clipboard_get_owner ##### --> +<para> + +</para> + +@clipboard: +@Returns: + <!-- ##### SECTION ./tmpl/gtkdebug.sgml:Long_Description ##### --> <para> @@ -518,6 +824,16 @@ show the size if @show_size is true. @func_data: @args: +<!-- ##### FUNCTION gtk_text_iter_get_pixmap ##### --> +<para> + +</para> + +@iter: +@pixmap: +@mask: +@Returns: + <!-- ##### MACRO gtk_marshal_NONE__POINTER_UINT_UINT ##### --> <para> @@ -549,6 +865,19 @@ will be shown, or NULL to show all spacings. @charsets: a NULL-terminated array of strings containing charset names which will be shown, or NULL to show all charsets. +<!-- ##### SECTION ./tmpl/gtkclipboard.sgml:Title ##### --> +Clipboards + + +<!-- ##### SIGNAL GtkTextView::delete-text ##### --> +<para> + +</para> + +@textview: the object which received the signal. +@arg1: +@arg2: + <!-- ##### FUNCTION gtk_container_get_toplevels ##### --> <para> @@ -596,6 +925,16 @@ The last "flat" (no struct) enumerated type value. @func_data: @args: +<!-- ##### FUNCTION gtk_text_iter_in_region ##### --> +<para> + +</para> + +@iter: +@start: +@end: +@Returns: + <!-- ##### FUNCTION gtk_type_get_varargs_type ##### --> <para> Get the varargs type associated with @foreign_type @@ -604,6 +943,20 @@ Get the varargs type associated with @foreign_type @foreign_type: GtkType @Returns: GtkType +<!-- ##### FUNCTION gtk_clipboard_wait_for_text ##### --> +<para> + +</para> + +@clipboard: +@Returns: +<!-- +Local variables: +mode: sgml +sgml-parent-document: ("../gtk-docs.sgml" "book" "refsect2" "") +End: +--> + <!-- ##### STRUCT GtkMenuFactory ##### --> <para> @@ -622,6 +975,13 @@ Use to get the value of a GtkArg whose GtkType is GTK_TYPE_C_FOREIGN @a: +<!-- ##### SIGNAL GtkTextView::paste-text ##### --> +<para> + +</para> + +@textview: the object which received the signal. + <!-- ##### MACRO GTK_PRIVATE_SET_FLAG ##### --> <para> @@ -655,6 +1015,19 @@ Use to get the value of a GtkArg whose GtkType is GTK_TYPE_C_FOREIGN @GTK_DEBUG_DND: @GTK_DEBUG_PLUGSOCKET: +<!-- ##### FUNCTION gtk_clipboard_set_with_owner ##### --> +<para> + +</para> + +@clipboard: +@targets: +@n_targets: +@get_func: +@clear_func: +@owner: +@Returns: + <!-- ##### FUNCTION gtk_menu_factory_remove_paths ##### --> <para> @@ -707,6 +1080,14 @@ Hide the name of gtk_identifier_get_type @wid: +<!-- ##### FUNCTION gtk_selection_data_get_text ##### --> +<para> + +</para> + +@selection_data: +@Returns: + <!-- ##### FUNCTION gtk_marshal_BOOL__NONE ##### --> <para> @@ -833,6 +1214,21 @@ is enabled. @type: @action: +<!-- ##### ENUM GtkTextViewDeleteType ##### --> +<para> + +</para> + +@GTK_TEXT_DELETE_CHAR: +@GTK_TEXT_DELETE_HALF_WORD: +@GTK_TEXT_DELETE_WHOLE_WORD: +@GTK_TEXT_DELETE_HALF_WRAPPED_LINE: +@GTK_TEXT_DELETE_WHOLE_WRAPPED_LINE: +@GTK_TEXT_DELETE_HALF_LINE: +@GTK_TEXT_DELETE_WHOLE_LINE: +@GTK_TEXT_DELETE_WHITESPACE: +@GTK_TEXT_DELETE_WHITESPACE_LEAVE_ONE: + <!-- ##### MACRO GTK_TYPE_FLAT_FIRST ##### --> <para> The first "flat" (no struct) enumerated type value. @@ -853,6 +1249,36 @@ The first "flat" (no struct) enumerated type value. </para> +<!-- ##### FUNCTION gtk_text_buffer_spew ##### --> +<para> + +</para> + +@buffer: + +<!-- ##### STRUCT GtkTextTabArray ##### --> +<para> + +</para> + + +<!-- ##### ARG GtkTextTag:overstrike ##### --> +<para> + +</para> + + +<!-- ##### USER_FUNCTION GtkClipboardTextReceivedFunc ##### --> +<para> + A function to be called when the results of gtk_clipboard_request_text() + are received, or when the request fails. +</para> + +@clipboard: the #GtkClipboard +@text: the text received, as a UTF-8 encoded string, or %NULL + if retrieving the data failed. +@data: the @user_data supplied to gtk_clipboard_request_text(). + <!-- ##### MACRO GTK_WIDGET_HAS_SHAPE_MASK ##### --> <para> @@ -860,6 +1286,14 @@ The first "flat" (no struct) enumerated type value. @obj: +<!-- ##### FUNCTION gtk_text_buffer_copy ##### --> +<para> + +</para> + +@buffer: +@time: + <!-- ##### FUNCTION gtk_marshal_NONE__POINTER_INT ##### --> <para> @@ -891,6 +1325,14 @@ gtkenums.sgml @func_data: @args: +<!-- ##### USER_FUNCTION GtkMenuCallback ##### --> +<para> + +</para> + +@widget: +@user_data: + <!-- ##### FUNCTION gtk_type_check_object_cast ##### --> <para> Given a pointer to a GtkTypeObject @type_object, and a GtkType @cast_type, @@ -901,14 +1343,6 @@ make sure that it's okay to cast @type_object into a @cast_type. @cast_type: GtkType @Returns: the same GtkTypeObject* as @type_object -<!-- ##### USER_FUNCTION GtkMenuCallback ##### --> -<para> - -</para> - -@widget: -@user_data: - <!-- ##### FUNCTION gtk_themes_exit ##### --> <para> @@ -926,17 +1360,47 @@ make sure that it's okay to cast @type_object into a @cast_type. @func_data: @args: +<!-- ##### USER_FUNCTION GtkClipboardGetFunc ##### --> +<para> +A function that will be called to provide the contents of the selection. +If multiple types of data were advertised, the requested type can +be determined from the @info parameter or by checking the target field +of @selection_data. If the data could succesfully be converted into +then it should be stored into the @selection_data object by +calling gtk_selection_data_set() (or related functions such +as gtk_seletion_data_get().) If no data is set, the requestor +will be informed that the attempt to get the data failed. +</para> + +@clipboard: the #GtkClipboard +@selection_data: a #GtkSelectionData argument in which the requested + data should be stored. +@info: the info field corresponding to the requested + target from the #GtkTargetEntry array passed to + gtk_clipboard_set_with_data() or gtk_clipboard_set_with_owner(). +@user_data_or_owner: the @user_data argument passed to gtk_clipboard_set_with_data(), or + the @owner argument passed to gtk_clipboard_set_owner() + +<!-- ##### SECTION ./tmpl/gtkmenufactory.sgml:Long_Description ##### --> +<para> + +</para> + + <!-- ##### MACRO gtk_marshal_NONE__OBJECT ##### --> <para> </para> -<!-- ##### SECTION ./tmpl/gtkmenufactory.sgml:Long_Description ##### --> +<!-- ##### FUNCTION gtk_clipboard_set_text ##### --> <para> </para> +@clipboard: +@text: +@len: <!-- ##### FUNCTION gtk_type_set_varargs_type ##### --> <para> @@ -947,6 +1411,12 @@ Set the varargs type for a fundamental type @foreign_type. fundamental type. @varargs_type: Must be a GtkType which is either structured or flag, or NONE. +<!-- ##### STRUCT GtkClipboard ##### --> +<para> + +</para> + + <!-- ##### FUNCTION gtk_type_check_class_cast ##### --> <para> Given a GtkTypeClass pointer @klass, and a GtkType @cast_type, make @@ -964,6 +1434,16 @@ sure that it's okay to cast something of that @klass into a @cast_type. @factory: +<!-- ##### FUNCTION gtk_text_buffer_insert_pixmap ##### --> +<para> + +</para> + +@buffer: +@iter: +@pixmap: +@mask: + <!-- ##### FUNCTION gtk_marshal_NONE__C_CALLBACK_C_CALLBACK ##### --> <para> @@ -1014,6 +1494,14 @@ Print the types @type inherits from. @type: GtkType +<!-- ##### FUNCTION gtk_text_buffer_set_clipboard_contents ##### --> +<para> + +</para> + +@buffer: +@text: + <!-- ##### ENUM GtkFontFilterType ##### --> <para> A set of bit flags used to specify the filter being set @@ -1042,6 +1530,15 @@ Return NULL if anything goes wrong. @window: @defaultw: +<!-- ##### FUNCTION gtk_clipboard_request_text ##### --> +<para> + +</para> + +@clipboard: +@callback: +@user_data: + <!-- ##### FUNCTION gtk_marshal_NONE__INT ##### --> <para> @@ -1140,12 +1637,13 @@ Internal function. </para> -<!-- ##### FUNCTION gtk_container_register_toplevel ##### --> +<!-- ##### MACRO gtk_widget_push_visual ##### --> <para> </para> -@container: +@v: +@visual: <!-- ##### MACRO gtk_marshal_ENUM__ENUM ##### --> <para> @@ -1153,6 +1651,13 @@ Internal function. </para> +<!-- ##### FUNCTION gtk_container_register_toplevel ##### --> +<para> + +</para> + +@container: + <!-- ##### SECTION ./tmpl/gtkimcontextsimple.sgml:Title ##### --> GtkIMContextSimple @@ -1180,12 +1685,33 @@ Use to get the value of a GtkArg whose GtkType is GTK_TYPE_C_CALLBACK @func_data: @args: +<!-- ##### SIGNAL GtkTextView::move-insert ##### --> +<para> + +</para> + +@textview: the object which received the signal. +@arg1: +@arg2: +@arg3: + <!-- ##### SECTION ./tmpl/gtkimcontextsimple.sgml:Long_Description ##### --> <para> </para> +<!-- ##### FUNCTION gtk_text_buffer_find_regexp ##### --> +<para> + +</para> + +@buffer: +@regexp: +@start: +@end: +@Returns: + <!-- ##### FUNCTION gtk_menu_factory_add_subfactory ##### --> <para> @@ -1195,3 +1721,13 @@ Use to get the value of a GtkArg whose GtkType is GTK_TYPE_C_CALLBACK @subfactory: @path: +<!-- ##### ENUM GtkTextViewScrollType ##### --> +<para> + +</para> + +@GTK_TEXT_SCROLL_TO_TOP: +@GTK_TEXT_SCROLL_TO_BOTTOM: +@GTK_TEXT_SCROLL_PAGE_DOWN: +@GTK_TEXT_SCROLL_PAGE_UP: + diff --git a/docs/reference/gtk/tmpl/gtkrc.sgml b/docs/reference/gtk/tmpl/gtkrc.sgml index 08a457665b..ba0fccecd6 100644 --- a/docs/reference/gtk/tmpl/gtkrc.sgml +++ b/docs/reference/gtk/tmpl/gtkrc.sgml @@ -609,6 +609,9 @@ specific portions of a RC file. @GTK_RC_TOKEN_HIGHEST: @GTK_RC_TOKEN_ENGINE: @GTK_RC_TOKEN_MODULE_PATH: +@GTK_RC_TOKEN_STOCK: +@GTK_RC_TOKEN_LTR: +@GTK_RC_TOKEN_RTL: @GTK_RC_TOKEN_LAST: <!-- ##### FUNCTION gtk_rc_get_style ##### --> diff --git a/docs/reference/gtk/tmpl/gtkselection.sgml b/docs/reference/gtk/tmpl/gtkselection.sgml index eaeb6e1987..32717f272d 100644 --- a/docs/reference/gtk/tmpl/gtkselection.sgml +++ b/docs/reference/gtk/tmpl/gtkselection.sgml @@ -184,15 +184,6 @@ for a given widget and selection. @ntargets: number of entries in @targets -<!-- ##### FUNCTION gtk_selection_clear_targets ##### --> -<para> - -</para> - -@widget: -@selection: - - <!-- ##### FUNCTION gtk_selection_convert ##### --> <para> Request the contents of a selection. When received, @@ -209,29 +200,6 @@ a "selection_received" signal will be generated. this widget). -<!-- ##### FUNCTION gtk_selection_remove_all ##### --> -<para> -Removes all handlers and unsets ownership of all -selections for a widget. Called when widget is being -destroyed. This function will not generally be -called by applications. -</para> - -@widget: a #GtkWidget - - -<!-- ##### STRUCT GtkSelectionData ##### --> -<para> - -</para> - -@selection: -@target: -@type: -@format: -@data: -@length: - <!-- ##### FUNCTION gtk_selection_data_set ##### --> <para> Store new data into a GtkSelectionData object. Should @@ -246,23 +214,15 @@ Null terminates the stored data. @length: length of the data -<!-- ##### FUNCTION gtk_selection_data_set_text ##### --> -<para> - -</para> - -@selection_data: -@str: -@Returns: - - -<!-- ##### FUNCTION gtk_selection_data_get_text ##### --> +<!-- ##### FUNCTION gtk_selection_remove_all ##### --> <para> - +Removes all handlers and unsets ownership of all +selections for a widget. Called when widget is being +destroyed. This function will not generally be +called by applications. </para> -@selection_data: -@Returns: +@widget: a #GtkWidget <!-- ##### FUNCTION gtk_selection_data_copy ##### --> diff --git a/docs/reference/gtk/tmpl/gtkstyle.sgml b/docs/reference/gtk/tmpl/gtkstyle.sgml index 86d41005ab..618d49de6e 100644 --- a/docs/reference/gtk/tmpl/gtkstyle.sgml +++ b/docs/reference/gtk/tmpl/gtkstyle.sgml @@ -71,6 +71,7 @@ Styles @clone: @init_from_rc: @set_background: +@render_icon: @draw_hline: @draw_vline: @draw_shadow: diff --git a/docs/reference/gtk/tmpl/gtktextbuffer.sgml b/docs/reference/gtk/tmpl/gtktextbuffer.sgml index 8048a7fee7..cd8a16a348 100644 --- a/docs/reference/gtk/tmpl/gtktextbuffer.sgml +++ b/docs/reference/gtk/tmpl/gtktextbuffer.sgml @@ -102,6 +102,17 @@ GtkTextBuffer @Returns: +<!-- ##### FUNCTION gtk_text_buffer_insert_range ##### --> +<para> + +</para> + +@buffer: +@iter: +@start: +@end: + + <!-- ##### FUNCTION gtk_text_buffer_delete ##### --> <para> @@ -127,6 +138,16 @@ GtkTextBuffer @Returns: +<!-- ##### FUNCTION gtk_text_buffer_set_text ##### --> +<para> + +</para> + +@buffer: +@text: +@len: + + <!-- ##### FUNCTION gtk_text_buffer_get_text ##### --> <para> @@ -157,15 +178,14 @@ GtkTextBuffer @end_iter: -<!-- ##### FUNCTION gtk_text_buffer_insert_pixmap ##### --> +<!-- ##### FUNCTION gtk_text_buffer_insert_pixbuf ##### --> <para> </para> @buffer: @iter: -@pixmap: -@mask: +@pixbuf: <!-- ##### FUNCTION gtk_text_buffer_create_mark ##### --> @@ -199,6 +219,15 @@ GtkTextBuffer @mark: +<!-- ##### FUNCTION gtk_text_buffer_delete_mark_by_name ##### --> +<para> + +</para> + +@buffer: +@name: + + <!-- ##### FUNCTION gtk_text_buffer_get_mark ##### --> <para> @@ -209,6 +238,15 @@ GtkTextBuffer @Returns: +<!-- ##### FUNCTION gtk_text_buffer_get_insert ##### --> +<para> + +</para> + +@buffer: +@Returns: + + <!-- ##### FUNCTION gtk_text_buffer_place_cursor ##### --> <para> @@ -360,36 +398,6 @@ GtkTextBuffer @setting: -<!-- ##### FUNCTION gtk_text_buffer_set_clipboard_contents ##### --> -<para> - -</para> - -@buffer: -@text: - - -<!-- ##### FUNCTION gtk_text_buffer_get_clipboard_contents ##### --> -<para> - -</para> - -@buffer: -@Returns: - - -<!-- ##### FUNCTION gtk_text_buffer_paste_primary_selection ##### --> -<para> - -</para> - -@buffer: -@override_location: -@time: -@interactive: -@default_editable: - - <!-- ##### FUNCTION gtk_text_buffer_delete_selection ##### --> <para> @@ -401,35 +409,16 @@ GtkTextBuffer @Returns: -<!-- ##### FUNCTION gtk_text_buffer_cut ##### --> -<para> - -</para> - -@buffer: -@time: -@interactive: -@default_editable: - - -<!-- ##### FUNCTION gtk_text_buffer_copy ##### --> -<para> - -</para> - -@buffer: -@time: - - <!-- ##### FUNCTION gtk_text_buffer_paste_clipboard ##### --> <para> </para> @buffer: +@default_editable: +<!-- # Unused Parameters # --> @time: @interactive: -@default_editable: <!-- ##### FUNCTION gtk_text_buffer_get_selection_bounds ##### --> @@ -443,39 +432,6 @@ GtkTextBuffer @Returns: -<!-- ##### FUNCTION gtk_text_buffer_find_string ##### --> -<para> - -</para> - -@buffer: -@iter: -@str: -@start: -@end: -@Returns: - - -<!-- ##### FUNCTION gtk_text_buffer_find_regexp ##### --> -<para> - -</para> - -@buffer: -@regexp: -@start: -@end: -@Returns: - - -<!-- ##### FUNCTION gtk_text_buffer_spew ##### --> -<para> - -</para> - -@buffer: - - <!-- ##### SIGNAL GtkTextBuffer::insert-text ##### --> <para> diff --git a/docs/reference/gtk/tmpl/gtktextiter.sgml b/docs/reference/gtk/tmpl/gtktextiter.sgml index 0164958620..bee274eb6e 100644 --- a/docs/reference/gtk/tmpl/gtktextiter.sgml +++ b/docs/reference/gtk/tmpl/gtktextiter.sgml @@ -29,15 +29,14 @@ gtktextiter @dummy2: @dummy3: @dummy4: -@dummy10: -@dummy11: @dummy5: @dummy6: @dummy7: @dummy8: @dummy9: -@pad1: -@pad2: +@dummy10: +@dummy11: +@dummy12: <!-- ##### FUNCTION gtk_text_iter_get_buffer ##### --> <para> @@ -150,14 +149,12 @@ gtktextiter @Returns: -<!-- ##### FUNCTION gtk_text_iter_get_pixmap ##### --> +<!-- ##### FUNCTION gtk_text_iter_get_pixbuf ##### --> <para> </para> @iter: -@pixmap: -@mask: @Returns: @@ -504,6 +501,8 @@ gtktextiter @str: @visible_only: @slice: +@match_start: +@match_end: @Returns: @@ -539,7 +538,7 @@ gtktextiter @Returns: -<!-- ##### FUNCTION gtk_text_iter_in_region ##### --> +<!-- ##### FUNCTION gtk_text_iter_in_range ##### --> <para> </para> diff --git a/docs/reference/gtk/tmpl/gtktextmark.sgml b/docs/reference/gtk/tmpl/gtktextmark.sgml index 3bfdbc0dff..23557ebfb2 100644 --- a/docs/reference/gtk/tmpl/gtktextmark.sgml +++ b/docs/reference/gtk/tmpl/gtktextmark.sgml @@ -55,12 +55,3 @@ gtktextmark @mark: -<!-- ##### FUNCTION gtk_text_mark_deleted ##### --> -<para> - -</para> - -@mark: -@Returns: - - diff --git a/docs/reference/gtk/tmpl/gtktexttag.sgml b/docs/reference/gtk/tmpl/gtktexttag.sgml index 87c937a479..6bf264242e 100644 --- a/docs/reference/gtk/tmpl/gtktexttag.sgml +++ b/docs/reference/gtk/tmpl/gtktexttag.sgml @@ -32,12 +32,6 @@ GtkTextTag </para> -<!-- ##### STRUCT GtkTextTabArray ##### --> -<para> - -</para> - - <!-- ##### ENUM GtkWrapMode ##### --> <para> @@ -54,7 +48,6 @@ GtkTextTag @refcount: @appearance: -@border_width: @relief: @justify: @direction: @@ -66,7 +59,7 @@ GtkTextTag @pixels_above_lines: @pixels_below_lines: @pixels_inside_wrap: -@tab_array: +@tabs: @wrap_mode: @language: @invisible: @@ -127,7 +120,7 @@ GtkTextTag @bg_stipple: @fg_stipple: @underline: -@overstrike: +@strikethrough: @draw_bg: @inside_selection: @@ -260,11 +253,6 @@ GtkTextTag </para> -<!-- ##### ARG GtkTextTag:overstrike ##### --> -<para> - -</para> - <!-- ##### ARG GtkTextTag:pixels_above_lines ##### --> <para> @@ -285,6 +273,11 @@ GtkTextTag </para> +<!-- ##### ARG GtkTextTag:strikethrough ##### --> +<para> + +</para> + <!-- ##### ARG GtkTextTag:underline ##### --> <para> @@ -295,6 +288,11 @@ GtkTextTag </para> +<!-- ##### ARG GtkTextTag:tabs ##### --> +<para> + +</para> + <!-- ##### ARG GtkTextTag:background_set ##### --> <para> @@ -365,22 +363,22 @@ GtkTextTag </para> -<!-- ##### ARG GtkTextTag:overstrike_set ##### --> +<!-- ##### ARG GtkTextTag:pixels_above_lines_set ##### --> <para> </para> -<!-- ##### ARG GtkTextTag:pixels_above_lines_set ##### --> +<!-- ##### ARG GtkTextTag:pixels_below_lines_set ##### --> <para> </para> -<!-- ##### ARG GtkTextTag:pixels_below_lines_set ##### --> +<!-- ##### ARG GtkTextTag:pixels_inside_wrap_set ##### --> <para> </para> -<!-- ##### ARG GtkTextTag:pixels_inside_wrap_set ##### --> +<!-- ##### ARG GtkTextTag:strikethrough_set ##### --> <para> </para> @@ -400,3 +398,8 @@ GtkTextTag </para> +<!-- ##### ARG GtkTextTag:tabs_set ##### --> +<para> + +</para> + diff --git a/docs/reference/gtk/tmpl/gtktextview.sgml b/docs/reference/gtk/tmpl/gtktextview.sgml index 2ab94d5ba7..9f36a4eaec 100644 --- a/docs/reference/gtk/tmpl/gtktextview.sgml +++ b/docs/reference/gtk/tmpl/gtktextview.sgml @@ -20,44 +20,6 @@ GtkTextView </para> -<!-- ##### ENUM GtkTextViewMovementStep ##### --> -<para> - -</para> - -@GTK_TEXT_MOVEMENT_CHAR: -@GTK_TEXT_MOVEMENT_POSITIONS: -@GTK_TEXT_MOVEMENT_WORD: -@GTK_TEXT_MOVEMENT_WRAPPED_LINE: -@GTK_TEXT_MOVEMENT_LINE: -@GTK_TEXT_MOVEMENT_LINE_ENDS: -@GTK_TEXT_MOVEMENT_BUFFER_ENDS: - -<!-- ##### ENUM GtkTextViewScrollType ##### --> -<para> - -</para> - -@GTK_TEXT_SCROLL_TO_TOP: -@GTK_TEXT_SCROLL_TO_BOTTOM: -@GTK_TEXT_SCROLL_PAGE_DOWN: -@GTK_TEXT_SCROLL_PAGE_UP: - -<!-- ##### ENUM GtkTextViewDeleteType ##### --> -<para> - -</para> - -@GTK_TEXT_DELETE_CHAR: -@GTK_TEXT_DELETE_HALF_WORD: -@GTK_TEXT_DELETE_WHOLE_WORD: -@GTK_TEXT_DELETE_HALF_WRAPPED_LINE: -@GTK_TEXT_DELETE_WHOLE_WRAPPED_LINE: -@GTK_TEXT_DELETE_HALF_LINE: -@GTK_TEXT_DELETE_WHOLE_LINE: -@GTK_TEXT_DELETE_WHITESPACE: -@GTK_TEXT_DELETE_WHITESPACE_LEAVE_ONE: - <!-- ##### FUNCTION gtk_text_view_new ##### --> <para> @@ -93,17 +55,6 @@ GtkTextView @Returns: -<!-- ##### FUNCTION gtk_text_view_get_iter_at_pixel ##### --> -<para> - -</para> - -@text_view: -@iter: -@x: -@y: - - <!-- ##### FUNCTION gtk_text_view_scroll_to_mark ##### --> <para> @@ -207,7 +158,7 @@ GtkTextView @location: -<!-- ##### SIGNAL GtkTextView::move-insert ##### --> +<!-- ##### SIGNAL GtkTextView::move ##### --> <para> </para> @@ -224,7 +175,7 @@ GtkTextView @textview: the object which received the signal. -<!-- ##### SIGNAL GtkTextView::scroll-text ##### --> +<!-- ##### SIGNAL GtkTextView::insert ##### --> <para> </para> @@ -232,7 +183,7 @@ GtkTextView @textview: the object which received the signal. @arg1: -<!-- ##### SIGNAL GtkTextView::delete-text ##### --> +<!-- ##### SIGNAL GtkTextView::delete ##### --> <para> </para> @@ -241,21 +192,21 @@ GtkTextView @arg1: @arg2: -<!-- ##### SIGNAL GtkTextView::cut-text ##### --> +<!-- ##### SIGNAL GtkTextView::cut-clipboard ##### --> <para> </para> @textview: the object which received the signal. -<!-- ##### SIGNAL GtkTextView::copy-text ##### --> +<!-- ##### SIGNAL GtkTextView::copy-clipboard ##### --> <para> </para> @textview: the object which received the signal. -<!-- ##### SIGNAL GtkTextView::paste-text ##### --> +<!-- ##### SIGNAL GtkTextView::paste-clipboard ##### --> <para> </para> diff --git a/docs/reference/gtk/tmpl/gtkwidget.sgml b/docs/reference/gtk/tmpl/gtkwidget.sgml index d24a46888c..2acc333bc1 100644 --- a/docs/reference/gtk/tmpl/gtkwidget.sgml +++ b/docs/reference/gtk/tmpl/gtkwidget.sgml @@ -823,18 +823,6 @@ GtkWidget @Returns: -<!-- ##### MACRO gtk_widget_set_visual ##### --> -<para> - -</para> - -@w: -@v: -<!-- # Unused Parameters # --> -@widget: -@visual: - - <!-- ##### FUNCTION gtk_widget_get_events ##### --> <para> @@ -939,16 +927,6 @@ GtkWidget @cmap: -<!-- ##### MACRO gtk_widget_push_visual ##### --> -<para> - -</para> - -@v: -<!-- # Unused Parameters # --> -@visual: - - <!-- ##### FUNCTION gtk_widget_pop_style ##### --> <para> @@ -963,14 +941,6 @@ GtkWidget -<!-- ##### MACRO gtk_widget_pop_visual ##### --> -<para> - -</para> - -@v: - - <!-- ##### FUNCTION gtk_widget_set_default_style ##### --> <para> @@ -995,16 +965,6 @@ GtkWidget @Returns: -<!-- ##### MACRO gtk_widget_set_default_visual ##### --> -<para> - -</para> - -@v: -<!-- # Unused Parameters # --> -@visual: - - <!-- ##### FUNCTION gtk_widget_get_default_colormap ##### --> <para> diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index 321f5ad582..172bd53061 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,32 @@ +2000-10-16 Havoc Pennington <hp@redhat.com> + + * gdk-pixbuf-io.c (gdk_pixbuf_get_module) + (gdk_pixbuf_get_named_module) (gdk_pixbuf_load_module): + add error reporting here also + + * make-inline-pixbuf.c (main): use GError + + * io-xpm.c: include unistd.h + + * gdk-pixbuf-util.c: include string.h + + * io-*.c: add error reporting + + * gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file): add + error reporting + + * gdk-pixbuf-io.c (gdk_pixbuf_new_from_file): Add error reporting + + * gdk-pixbuf-io.h: Add GError** to load_increment and load + methods + + * gdk-pixbuf-io.c (gdk_pixbuf_save) (gdk_pixbuf_savev): return + a G_FILE_ERROR if we fail to write or close the file. + + * gdk-pixbuf.h: remove GDK_PIXBUF_ERROR_IO, instead we'll use + G_FILE_ERROR_*. Rename enum to GdkPixbufError, properly following + the GError naming rules. Add GError** to load functions. + 2000-10-06 Havoc Pennington <hp@redhat.com> * gdk-pixbuf.h: add GdkPixbufAlphaMode diff --git a/gdk-pixbuf/gdk-pixbuf-animation.c b/gdk-pixbuf/gdk-pixbuf-animation.c index 25f5d7d17a..16dc26d6c2 100644 --- a/gdk-pixbuf/gdk-pixbuf-animation.c +++ b/gdk-pixbuf/gdk-pixbuf-animation.c @@ -22,6 +22,7 @@ */ #include <config.h> +#include <errno.h> #include "gdk-pixbuf-io.h" #include "gdk-pixbuf-private.h" @@ -92,10 +93,12 @@ gdk_pixbuf_animation_finalize (GObject *object) /** * gdk_pixbuf_animation_new_from_file: * @filename: Name of file to load. + * @error: return location for error * * Creates a new animation by loading it from a file. The file format is * detected automatically. If the file's format does not support multi-frame - * images, then an animation with a single frame will be created. + * images, then an animation with a single frame will be created. Possible errors + * are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains. * * Return value: A newly created animation with a reference count of 1, or NULL * if any of several error conditions ocurred: the file could not be opened, @@ -103,7 +106,8 @@ gdk_pixbuf_animation_finalize (GObject *object) * allocate the image buffer, or the image file contained invalid data. **/ GdkPixbufAnimation * -gdk_pixbuf_animation_new_from_file (const char *filename) +gdk_pixbuf_animation_new_from_file (const char *filename, + GError **error) { GdkPixbufAnimation *animation; int size; @@ -114,25 +118,39 @@ gdk_pixbuf_animation_new_from_file (const char *filename) g_return_val_if_fail (filename != NULL, NULL); f = fopen (filename, "rb"); - if (!f) + if (!f) { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Failed to open file '%s': %s"), + filename, g_strerror (errno)); return NULL; + } size = fread (&buffer, 1, sizeof (buffer), f); if (size == 0) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image file '%s' contains no data"), + filename); + fclose (f); return NULL; } - image_module = gdk_pixbuf_get_module (buffer, size); + image_module = gdk_pixbuf_get_module (buffer, size, filename, error); if (!image_module) { - g_warning ("Unable to find handler for file: %s", filename); fclose (f); return NULL; } if (image_module->module == NULL) - gdk_pixbuf_load_module (image_module); + if (!gdk_pixbuf_load_module (image_module, error)) { + fclose (f); + return NULL; + } if (image_module->load_animation == NULL) { GdkPixbuf *pixbuf; @@ -141,14 +159,35 @@ gdk_pixbuf_animation_new_from_file (const char *filename) /* Keep this logic in sync with gdk_pixbuf_new_from_file() */ if (image_module->load == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("Don't know how to load the animation in file '%s'"), + filename); fclose (f); return NULL; } fseek (f, 0, SEEK_SET); - pixbuf = (* image_module->load) (f); + pixbuf = (* image_module->load) (f, error); fclose (f); + if (pixbuf == NULL && error != NULL && *error == NULL) { + /* I don't trust these crufty longjmp()'ing image libs + * to maintain proper error invariants, and I don't + * want user code to segfault as a result. We need to maintain + * the invariant that error gets set if NULL is returned. + */ + + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", + image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load image '%s': reason not known, probably a corrupt image file"), + filename); + } + if (pixbuf == NULL) return NULL; @@ -167,7 +206,26 @@ gdk_pixbuf_animation_new_from_file (const char *filename) animation->height = gdk_pixbuf_get_height (pixbuf); } else { fseek (f, 0, SEEK_SET); - animation = (* image_module->load_animation) (f); + animation = (* image_module->load_animation) (f, error); + + if (animation == NULL && error != NULL && *error == NULL) { + /* I don't trust these crufty longjmp()'ing + * image libs to maintain proper error + * invariants, and I don't want user code to + * segfault as a result. We need to maintain + * the invariant that error gets set if NULL + * is returned. + */ + + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", + image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load animation '%s': reason not known, probably a corrupt animation file"), + filename); + } + fclose (f); } diff --git a/gdk-pixbuf/gdk-pixbuf-data.c b/gdk-pixbuf/gdk-pixbuf-data.c index 94db20f376..a1b0232400 100644 --- a/gdk-pixbuf/gdk-pixbuf-data.c +++ b/gdk-pixbuf/gdk-pixbuf-data.c @@ -23,6 +23,7 @@ #include <config.h> #include "gdk-pixbuf.h" #include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-i18n.h" #include <stdlib.h> #include <string.h> @@ -106,7 +107,10 @@ read_bool (const guchar **p) } static GdkPixbuf* -read_raw_inline (const guchar *data, gboolean copy_pixels, int length) +read_raw_inline (const guchar *data, + gboolean copy_pixels, + int length, + GError **error) { GdkPixbuf *pixbuf; const guchar *p = data; @@ -116,6 +120,11 @@ read_raw_inline (const guchar *data, gboolean copy_pixels, int length) if (length >= 0 && length < 12) { /* Not enough buffer to hold the width/height/rowstride */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image data is partially missing")); + return NULL; } @@ -123,9 +132,14 @@ read_raw_inline (const guchar *data, gboolean copy_pixels, int length) width = read_int (&p); height = read_int (&p); - if (rowstride < width) + if (rowstride < width) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image has an incorrect pixel rowstride, perhaps the data was corrupted somehow.")); return NULL; /* bad data from untrusted source. */ - + } + /* rowstride >= width, so we can trust width */ length -= 12; @@ -133,37 +147,71 @@ read_raw_inline (const guchar *data, gboolean copy_pixels, int length) /* There's some better way like G_MAXINT/height > rowstride * but I'm not sure it works, so stick to this for now. */ - if (((double)height) * ((double)rowstride) > (double)G_MAXINT) + if (((double)height) * ((double)rowstride) > (double)G_MAXINT) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image size is impossibly large, perhaps the data was corrupted somehow")); + return NULL; /* overflow */ - + } + if (length >= 0 && length < (height * rowstride + 13)) { /* Not enough buffer to hold the remaining header * information plus the data. */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image data is partially missing, probably it was ocorrupted somehow.")); return NULL; } - + /* Read the remaining 13 bytes of header information */ has_alpha = read_bool (&p) != FALSE; colorspace = read_int (&p); n_channels = read_int (&p); bits_per_sample = read_int (&p); - - if (colorspace != GDK_COLORSPACE_RGB) + + if (colorspace != GDK_COLORSPACE_RGB) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image has an unknown colorspace code (%d), perhaps the image data was corrupted"), + colorspace); return NULL; + } - if (bits_per_sample != 8) + if (bits_per_sample != 8) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image has an improper number of bits per sample (%d), perhaps the image data was corrupted"), + bits_per_sample); return NULL; - - if (has_alpha && n_channels != 4) + } + + if (has_alpha && n_channels != 4) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image has an improper number of channels (%d), perhaps the image data was corrupted"), + n_channels); return NULL; - - if (!has_alpha && n_channels != 3) + } + + if (!has_alpha && n_channels != 3) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image has an improper number of channels (%d), perhaps the image data was corrupted"), + n_channels); return NULL; - + } + if (copy_pixels) { guchar *pixels; gint dest_rowstride; @@ -172,10 +220,19 @@ read_raw_inline (const guchar *data, gboolean copy_pixels, int length) pixbuf = gdk_pixbuf_new (colorspace, has_alpha, bits_per_sample, width, height); - + + if (pixbuf == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Not enough memory to store a %d by %d image; try exiting some applications to free memory."), + width, height); + return NULL; + } + pixels = gdk_pixbuf_get_pixels (pixbuf); dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf); - + for (row = 0; row < height; row++) { memcpy (pixels, p, rowstride); pixels += dest_rowstride; @@ -190,32 +247,42 @@ read_raw_inline (const guchar *data, gboolean copy_pixels, int length) rowstride, NULL, NULL); } - + return pixbuf; } /** * gdk_pixbuf_new_from_inline: - * @data: An inlined GdkPixbuf + * @inline_pixbuf: An inlined GdkPixbuf * @copy_pixels: whether to copy the pixels out of the inline data, or to use them in-place + * @length: length of the inline data + * @error: return location for error * * Create a #GdkPixbuf from a custom format invented to store pixbuf - * data in C program code. This library comes with a program called "make-inline-pixbuf" - * that can write out a variable definition containing an inlined pixbuf. - * This is useful if you want to ship a program with images, but - * don't want to depend on any external files. + * data in C program code. This library comes with a program called + * "make-inline-pixbuf" that can write out a variable definition + * containing an inlined pixbuf. This is useful if you want to ship a + * program with images, but don't want to depend on any external + * files. * * The inline data format contains the pixels in #GdkPixbuf's native * format. Since the inline pixbuf is read-only static data, you * don't need to copy it unless you intend to write to it. * + * If you create a pixbuf from const inline data compiled into your + * program, it's probably safe to ignore errors, since things will + * always succeed. For non-const inline data, you could get out of + * memory. For untrusted inline data located at runtime, you could + * have corrupt inline data in addition. + * * Return value: A newly-created #GdkPixbuf structure with a reference count of - * 1. + * 1, or NULL If error is set. **/ GdkPixbuf* gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf, gboolean copy_pixels, - int length) + int length, + GError **error) { const guchar *p; GdkPixbuf *pixbuf; @@ -225,12 +292,20 @@ gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf, /* not enough bytes to contain even the magic number * and format code. */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image contained no data.")); return NULL; } p = inline_pixbuf; if (read_int (&p) != GDK_PIXBUF_INLINE_MAGIC_NUMBER) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image isn't in the correct format (inline GdkPixbuf format)")); return NULL; } @@ -239,10 +314,15 @@ gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf, switch (format) { case GDK_PIXBUF_INLINE_RAW: - pixbuf = read_raw_inline (p, copy_pixels, length - 8); + pixbuf = read_raw_inline (p, copy_pixels, length - 8, error); break; default: + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("This version of the software is unable to read images with type code %d"), + format); return NULL; } diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c index d861c56112..02a517e436 100644 --- a/gdk-pixbuf/gdk-pixbuf-io.c +++ b/gdk-pixbuf/gdk-pixbuf-io.c @@ -275,8 +275,9 @@ get_libdir (void) /* actually load the image handler - gdk_pixbuf_get_module only get a */ /* reference to the module to load, it doesn't actually load it */ /* perhaps these actions should be combined in one function */ -void -gdk_pixbuf_load_module (GdkPixbufModule *image_module) +gboolean +gdk_pixbuf_load_module (GdkPixbufModule *image_module, + GError **error) { char *module_name; char *path; @@ -285,7 +286,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) gpointer save_sym; char *name; - g_return_if_fail (image_module->module == NULL); + g_return_val_if_fail (image_module->module == NULL, FALSE); name = image_module->module_name; @@ -304,10 +305,14 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) module = g_module_open (path, G_MODULE_BIND_LAZY); if (!module) { - g_warning ("Unable to load module: %s: %s", path, g_module_error ()); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Unable to load image-loading module: %s: %s"), + path, g_module_error ()); g_free (module_name); g_free (path); - return; + return FALSE; } g_free (path); } else { @@ -337,7 +342,9 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->load_animation = load_sym; if (pixbuf_module_symbol (module, name, "image_save", &save_sym)) - image_module->save = save_sym; + image_module->save = save_sym; + + return TRUE; } #else @@ -406,8 +413,9 @@ m_stop_load (tiff); m_load (xpm); m_load_xpm_data (xpm); -void -gdk_pixbuf_load_module (GdkPixbufModule *image_module) +gboolean +gdk_pixbuf_load_module (GdkPixbufModule *image_module, + GError **error) { image_module->module = (void *) 1; @@ -417,7 +425,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->load_increment = mname (png,load_increment); image_module->stop_load = mname (png,stop_load); image_module->save = mname (png,save); - return; + return TRUE; } if (strcmp (image_module->module_name, "bmp") == 0){ @@ -425,7 +433,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->begin_load = mname (bmp,begin_load); image_module->load_increment = mname (bmp,load_increment); image_module->stop_load = mname (bmp,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "wbmp") == 0){ @@ -433,7 +441,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->begin_load = mname (wbmp,begin_load); image_module->load_increment = mname (wbmp,load_increment); image_module->stop_load = mname (wbmp,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "gif") == 0){ @@ -442,7 +450,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->load_increment = mname (gif,load_increment); image_module->stop_load = mname (gif,stop_load); image_module->load_animation = mname (gif,load_animation); - return; + return TRUE; } if (strcmp (image_module->module_name, "ico") == 0){ @@ -450,7 +458,7 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->begin_load = mname (ico,begin_load); image_module->load_increment = mname (ico,load_increment); image_module->stop_load = mname (ico,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "jpeg") == 0){ @@ -459,34 +467,42 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) image_module->load_increment = mname (jpeg,load_increment); image_module->stop_load = mname (jpeg,stop_load); image_module->save = mname (jpeg,save); - return; + return TRUE; } if (strcmp (image_module->module_name, "pnm") == 0){ image_module->load = mname (pnm,load); image_module->begin_load = mname (pnm,begin_load); image_module->load_increment = mname (pnm,load_increment); image_module->stop_load = mname (pnm,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "ras") == 0){ image_module->load = mname (ras,load); image_module->begin_load = mname (ras,begin_load); image_module->load_increment = mname (ras,load_increment); image_module->stop_load = mname (ras,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "tiff") == 0){ image_module->load = mname (tiff,load); image_module->begin_load = mname (tiff,begin_load); image_module->load_increment = mname (tiff,load_increment); image_module->stop_load = mname (tiff,stop_load); - return; + return TRUE; } if (strcmp (image_module->module_name, "xpm") == 0){ image_module->load = mname (xpm,load); image_module->load_xpm_data = mname (xpm,load_xpm_data); - return; + return TRUE; } + + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Image type '%s' is not supported"), + image_module->module_name); + + return FALSE; } @@ -495,7 +511,8 @@ gdk_pixbuf_load_module (GdkPixbufModule *image_module) GdkPixbufModule * -gdk_pixbuf_get_named_module (const char *name) +gdk_pixbuf_get_named_module (const char *name, + GError **error) { int i; @@ -504,11 +521,19 @@ gdk_pixbuf_get_named_module (const char *name) return &(file_formats[i]); } + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Image type '%s' is not supported"), + name); + return NULL; } GdkPixbufModule * -gdk_pixbuf_get_module (guchar *buffer, guint size) +gdk_pixbuf_get_module (guchar *buffer, guint size, + const gchar *filename, + GError **error) { int i; @@ -517,15 +542,30 @@ gdk_pixbuf_get_module (guchar *buffer, guint size) return &(file_formats[i]); } + if (filename) + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Couldn't recognize the image file format for file '%s'"), + filename); + else + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Unrecognized image file format")); + + return NULL; } /** * gdk_pixbuf_new_from_file: * @filename: Name of file to load. + * @error: Return location for an error * * Creates a new pixbuf by loading an image from a file. The file format is - * detected automatically. + * detected automatically. If NULL is returned, then @error will be set. + * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains. * * Return value: A newly-created pixbuf with a reference count of 1, or NULL if * any of several error conditions occurred: the file could not be opened, @@ -533,7 +573,8 @@ gdk_pixbuf_get_module (guchar *buffer, guint size) * allocate the image buffer, or the image file contained invalid data. **/ GdkPixbuf * -gdk_pixbuf_new_from_file (const char *filename) +gdk_pixbuf_new_from_file (const char *filename, + GError **error) { GdkPixbuf *pixbuf; int size; @@ -544,34 +585,82 @@ gdk_pixbuf_new_from_file (const char *filename) g_return_val_if_fail (filename != NULL, NULL); f = fopen (filename, "rb"); - if (!f) + if (!f) { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errno), + _("Failed to open file '%s': %s"), + filename, g_strerror (errno)); return NULL; + } size = fread (&buffer, 1, sizeof (buffer), f); if (size == 0) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image file '%s' contains no data"), + filename); + fclose (f); return NULL; } - image_module = gdk_pixbuf_get_module (buffer, size); - if (!image_module) { - g_warning ("Unable to find handler for file: %s", filename); - fclose (f); - return NULL; - } + image_module = gdk_pixbuf_get_module (buffer, size, filename, error); + if (image_module == NULL) { + fclose (f); + return NULL; + } if (image_module->module == NULL) - gdk_pixbuf_load_module (image_module); + if (!gdk_pixbuf_load_module (image_module, error)) { + fclose (f); + return NULL; + } if (image_module->load == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("Don't know how to load the image in file '%s'"), + filename); + fclose (f); return NULL; } fseek (f, 0, SEEK_SET); - pixbuf = (* image_module->load) (f); + pixbuf = (* image_module->load) (f, error); fclose (f); + if (pixbuf == NULL && error != NULL && *error == NULL) { + /* I don't trust these crufty longjmp()'ing image libs + * to maintain proper error invariants, and I don't + * want user code to segfault as a result. We need to maintain + * the invariant that error gets set if NULL is returned. + */ + + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load image '%s': reason not known, probably a corrupt image file"), + filename); + + } else if (error != NULL && *error != NULL) { + + /* Add the filename to the error message */ + GError *e = *error; + gchar *old; + + old = e->message; + + e->message = g_strdup_printf (_("Failed to load image '%s': %s"), + filename, old); + + g_free (old); + } + return pixbuf; } @@ -591,7 +680,7 @@ gdk_pixbuf_new_from_xpm_data (const char **data) GdkPixbuf *pixbuf; if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) - gdk_pixbuf_load_module (&file_formats[XPM_FILE_FORMAT_INDEX]); + gdk_pixbuf_load_module (&file_formats[XPM_FILE_FORMAT_INDEX], NULL); if (file_formats[XPM_FILE_FORMAT_INDEX].module == NULL) { g_warning ("Can't find gdk-pixbuf module for parsing inline XPM data"); @@ -650,31 +739,26 @@ gdk_pixbuf_real_save (GdkPixbuf *pixbuf, gchar **values, GError **error) { - int i; GdkPixbufModule *image_module = NULL; + + image_module = gdk_pixbuf_get_named_module (type, error); + + if (image_module == NULL) + return FALSE; - for (i = 0; file_formats[i].module_name; i++) { - if (!strcmp (file_formats[i].module_name, type)) { - image_module = &(file_formats[i]); - break; - } - } - - if (!image_module) { + if (image_module->module == NULL) + if (!gdk_pixbuf_load_module (image_module, error)) + return FALSE; + + if (image_module->save == NULL) { g_set_error (error, GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_UNKNOWN_TYPE, - _("This build of gdk-pixbuf does not support saving the image format: %s"), type); + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("This build of gdk-pixbuf does not support saving the image format: %s"), + type); return FALSE; } - - if (image_module->module == NULL) - gdk_pixbuf_load_module (image_module); - - g_return_val_if_fail (image_module->save != NULL, FALSE); - - - + return (* image_module->save) (filehandle, pixbuf, keys, values, error); @@ -691,7 +775,7 @@ gdk_pixbuf_real_save (GdkPixbuf *pixbuf, * * Saves pixbuf to a file in @type, which is currently "jpeg" or * "png". If @error is set, FALSE will be returned. Possible errors include those - * from #GdkPixbufErrorType and those from #GFileErrorType. + * in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain. * * The variable argument list should be NULL-terminated; if not empty, * it should contain pairs of strings that modify the save @@ -747,8 +831,7 @@ gdk_pixbuf_save (GdkPixbuf *pixbuf, * * Saves pixbuf to a file in @type, which is currently "jpeg" or "png". * If @error is set, FALSE will be returned. See gdk_pixbuf_save () for more - * details. Possible errors include those from #GdkPixbufErrorType and - * those from #GFileErrorType. + * details. * * Return value: whether an error was set **/ @@ -772,8 +855,8 @@ gdk_pixbuf_savev (GdkPixbuf *pixbuf, if (f == NULL) { g_set_error (error, - GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_IO, + G_FILE_ERROR, + g_file_error_from_errno (errno), _("Failed to open '%s' for writing: %s"), filename, g_strerror (errno)); return FALSE; @@ -793,8 +876,8 @@ gdk_pixbuf_savev (GdkPixbuf *pixbuf, if (fclose (f) < 0) { g_set_error (error, - GDK_PIXBUF_ERROR, - GDK_PIXBUF_ERROR_IO, + G_FILE_ERROR, + g_file_error_from_errno (errno), _("Failed to close '%s' while writing image, all data may not have been saved: %s"), filename, g_strerror (errno)); return FALSE; diff --git a/gdk-pixbuf/gdk-pixbuf-io.h b/gdk-pixbuf/gdk-pixbuf-io.h index 3ce4d2f733..60046b8e7f 100644 --- a/gdk-pixbuf/gdk-pixbuf-io.h +++ b/gdk-pixbuf/gdk-pixbuf-io.h @@ -55,7 +55,8 @@ struct _GdkPixbufModule { char *module_name; gboolean (* format_check) (guchar *buffer, int size); GModule *module; - GdkPixbuf *(* load) (FILE *f); + GdkPixbuf *(* load) (FILE *f, + GError **error); GdkPixbuf *(* load_xpm_data) (const char **data); /* Incremental loading */ @@ -64,26 +65,33 @@ struct _GdkPixbufModule { ModuleUpdatedNotifyFunc update_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data); + gpointer user_data, + GError **error); void (* stop_load) (gpointer context); gboolean (* load_increment) (gpointer context, const guchar *buf, - guint size); + guint size, + GError **error); /* Animation loading */ - GdkPixbufAnimation *(* load_animation) (FILE *f); + GdkPixbufAnimation *(* load_animation) (FILE *f, + GError **error); gboolean (* save) (FILE *f, GdkPixbuf *pixbuf, gchar **param_keys, gchar **param_values, - GError **err); + GError **error); }; -GdkPixbufModule *gdk_pixbuf_get_module (guchar *buffer, guint size); -GdkPixbufModule *gdk_pixbuf_get_named_module (const char *name); -void gdk_pixbuf_load_module (GdkPixbufModule *image_module); +GdkPixbufModule *gdk_pixbuf_get_module (guchar *buffer, guint size, + const gchar *filename, + GError **error); +GdkPixbufModule *gdk_pixbuf_get_named_module (const char *name, + GError **error); +gboolean gdk_pixbuf_load_module (GdkPixbufModule *image_module, + GError **error); diff --git a/gdk-pixbuf/gdk-pixbuf-loader.c b/gdk-pixbuf/gdk-pixbuf-loader.c index 5f4320f22f..42aec5d4c7 100644 --- a/gdk-pixbuf/gdk-pixbuf-loader.c +++ b/gdk-pixbuf/gdk-pixbuf-loader.c @@ -338,20 +338,32 @@ gdk_pixbuf_loader_animation_done (GdkPixbuf *pixbuf, } static gint -gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) +gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, + const char *image_type, + GError **error) { GdkPixbufLoaderPrivate *priv = loader->private; - if(image_type) - priv->image_module = gdk_pixbuf_get_named_module (image_type); + if (image_type) + { + priv->image_module = gdk_pixbuf_get_named_module (image_type, + error); + } else - priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset); + { + g_return_val_if_fail (priv->header_buf_offset > 0, 0); + priv->image_module = gdk_pixbuf_get_module (priv->header_buf, + priv->header_buf_offset, + NULL, + error); + } if (priv->image_module == NULL) return 0; if (priv->image_module->module == NULL) - gdk_pixbuf_load_module (priv->image_module); + if (!gdk_pixbuf_load_module (priv->image_module, error)) + return 0; if (priv->image_module->module == NULL) return 0; @@ -360,8 +372,12 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) (priv->image_module->stop_load == NULL) || (priv->image_module->load_increment == NULL)) { - g_warning (G_STRLOC ": module %s does not support incremental loading.\n", - priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("Incremental loading of image type '%s' is not supported"), + image_type); + return 0; } @@ -369,16 +385,33 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) gdk_pixbuf_loader_update, gdk_pixbuf_loader_frame_done, gdk_pixbuf_loader_animation_done, - loader); + loader, + error); if (priv->context == NULL) { - g_warning (G_STRLOC ": Failed to begin progressive load"); + /* Defense against broken loaders; DO NOT take this as a GError + * example + */ + if (error && *error == NULL) + { + g_warning ("Bug! loader '%s' didn't set an error on failure", + priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error: Image loader module '%s'" + " failed to begin loading an image, but didn't" + " give a reason for the failure"), + priv->image_module->module_name); + + } + return 0; } if (priv->header_buf_offset - && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset)) + && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset, error)) return priv->header_buf_offset; return 0; @@ -387,7 +420,8 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) static int gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count) + gsize count, + GError **error) { gint n_bytes; GdkPixbufLoaderPrivate *priv = loader->private; @@ -399,7 +433,7 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, if (priv->header_buf_offset >= LOADER_HEADER_SIZE) { - if (gdk_pixbuf_loader_load_module (loader, NULL) == 0) + if (gdk_pixbuf_loader_load_module (loader, NULL, error) == 0) return 0; } @@ -411,11 +445,14 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, * @loader: A pixbuf loader. * @buf: Pointer to image data. * @count: Length of the @buf buffer in bytes. + * @error: return location for errors * - * This will cause a pixbuf loader to parse the next @count bytes of an image. - * It will return TRUE if the data was loaded successfully, and FALSE if an - * error occurred. In the latter case, the loader will be closed, and will not - * accept further writes. + * This will cause a pixbuf loader to parse the next @count bytes of + * an image. It will return TRUE if the data was loaded successfully, + * and FALSE if an error occurred. In the latter case, the loader + * will be closed, and will not accept further writes. If FALSE is + * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR + * domain. * * Return value: #TRUE if the write was successful, or #FALSE if the loader * cannot parse the buffer. @@ -423,7 +460,8 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count) + gsize count, + GError **error) { GdkPixbufLoaderPrivate *priv; @@ -442,7 +480,7 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, { gint eaten; - eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count); + eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count, error); if (eaten <= 0) return FALSE; @@ -451,8 +489,27 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, } if (count > 0 && priv->image_module->load_increment) - return priv->image_module->load_increment (priv->context, buf, count); - + { + gboolean retval; + retval = priv->image_module->load_increment (priv->context, buf, count, + error); + if (!retval && error && *error == NULL) + { + /* Fix up busted image loader */ + g_warning ("Bug! loader '%s' didn't set an error on failure", + priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error: Image loader module '%s'" + " failed to begin loading an image, but didn't" + " give a reason for the failure"), + priv->image_module->module_name); + } + + return retval; + } + return TRUE; } @@ -477,13 +534,22 @@ gdk_pixbuf_loader_new (void) * Return value: A newly-created pixbuf loader. **/ GdkPixbufLoader * -gdk_pixbuf_loader_new_with_type (const char *image_type) +gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error) { GdkPixbufLoader *retval; - + GError *tmp; + retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); - gdk_pixbuf_loader_load_module(retval, image_type); + tmp = NULL; + gdk_pixbuf_loader_load_module(retval, image_type, &tmp); + if (tmp != NULL) + { + g_propagate_error (error, tmp); + g_object_unref (G_OBJECT (retval)); + return NULL; + } return retval; } @@ -579,7 +645,7 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader) /* We have less the 128 bytes in the image. Flush it, and keep going. */ if (priv->image_module == NULL) - gdk_pixbuf_loader_load_module (loader, NULL); + gdk_pixbuf_loader_load_module (loader, NULL, NULL); if (priv->image_module && priv->image_module->stop_load) priv->image_module->stop_load (priv->context); diff --git a/gdk-pixbuf/gdk-pixbuf-loader.h b/gdk-pixbuf/gdk-pixbuf-loader.h index c3d6d6f95b..402b697256 100644 --- a/gdk-pixbuf/gdk-pixbuf-loader.h +++ b/gdk-pixbuf/gdk-pixbuf-loader.h @@ -72,10 +72,12 @@ struct _GdkPixbufLoaderClass GtkType gdk_pixbuf_loader_get_type (void) G_GNUC_CONST; GdkPixbufLoader * gdk_pixbuf_loader_new (void); -GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type); +GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error); gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count); + gsize count, + GError **error); GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader); GdkPixbufAnimation * gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader); void gdk_pixbuf_loader_close (GdkPixbufLoader *loader); diff --git a/gdk-pixbuf/gdk-pixbuf-util.c b/gdk-pixbuf/gdk-pixbuf-util.c index 36fc297504..bee4fb5bb7 100644 --- a/gdk-pixbuf/gdk-pixbuf-util.c +++ b/gdk-pixbuf/gdk-pixbuf-util.c @@ -23,6 +23,7 @@ #include <config.h> #include "gdk-pixbuf-private.h" +#include <string.h> diff --git a/gdk-pixbuf/gdk-pixbuf.h b/gdk-pixbuf/gdk-pixbuf.h index a61dc93660..e877372779 100644 --- a/gdk-pixbuf/gdk-pixbuf.h +++ b/gdk-pixbuf/gdk-pixbuf.h @@ -39,8 +39,8 @@ extern "C" { /* Alpha compositing mode */ typedef enum { - GDK_PIXBUF_ALPHA_BILEVEL, - GDK_PIXBUF_ALPHA_FULL + GDK_PIXBUF_ALPHA_BILEVEL, + GDK_PIXBUF_ALPHA_FULL } GdkPixbufAlphaMode; /* Color spaces; right now only RGB is supported. @@ -71,14 +71,18 @@ typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data); #define GDK_PIXBUF_ERROR gdk_pixbuf_error_quark () typedef enum { - /* some kind of failure reading or writing files */ - GDK_PIXBUF_ERROR_IO, + /* image data hosed */ + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + /* no mem to load image */ + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, /* bad option value passed to save routine */ GDK_PIXBUF_ERROR_BAD_OPTION_VALUE, /* unsupported image type (sort of an ENOSYS) */ GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + /* unsupported operation (load, save) for image type */ + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, GDK_PIXBUF_ERROR_FAILED -} GdkPixbufErrorType; +} GdkPixbufError; GQuark gdk_pixbuf_error_quark () G_GNUC_CONST; @@ -114,7 +118,8 @@ GdkPixbuf *gdk_pixbuf_copy (const GdkPixbuf *pixbuf); /* Simple loading */ -GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename); +GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename, + GError **error); GdkPixbuf *gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, @@ -130,23 +135,24 @@ GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data); /* Read an inline pixbuf */ GdkPixbuf *gdk_pixbuf_new_from_inline (const guchar *inline_pixbuf, gboolean copy_pixels, - int length); + int length, + GError **error); /* Saving */ gboolean gdk_pixbuf_save (GdkPixbuf *pixbuf, const char *filename, - const char *format, - GError **err, + const char *type, + GError **error, ...); gboolean gdk_pixbuf_savev (GdkPixbuf *pixbuf, const char *filename, - const char *format, + const char *type, char **option_keys, char **option_values, - GError **err); + GError **error); /* Adding an alpha channel */ GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color, @@ -248,7 +254,8 @@ typedef enum { GType gdk_pixbuf_animation_get_type (void) G_GNUC_CONST; -GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename); +GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename, + GError **error); GdkPixbufAnimation *gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation); void gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation); diff --git a/gdk-pixbuf/gnome-canvas-pixbuf.c b/gdk-pixbuf/gnome-canvas-pixbuf.c deleted file mode 100644 index a6372b9973..0000000000 --- a/gdk-pixbuf/gnome-canvas-pixbuf.c +++ /dev/null @@ -1,841 +0,0 @@ -/* GNOME libraries - GdkPixbuf item for the GNOME canvas - * - * Copyright (C) 1999 The Free Software Foundation - * - * Author: Federico Mena-Quintero <federico@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <math.h> -#include <libgnomeui/gnome-canvas.h> -#include <libgnomeui/gnome-canvas-util.h> -#include <libart_lgpl/art_rgb_affine.h> -#include <libart_lgpl/art_rgb_rgba_affine.h> -#include "gdk-pixbuf-private.h" -#include "gnome-canvas-pixbuf.h" - - - -/* Private part of the GnomeCanvasPixbuf structure */ -typedef struct { - /* Our gdk-pixbuf */ - GdkPixbuf *pixbuf; - - /* Width value */ - double width; - - /* Height value */ - double height; - - /* X translation */ - double x; - - /* Y translation */ - double y; - - /* Whether dimensions are set and whether they are in pixels or units */ - guint width_set : 1; - guint width_in_pixels : 1; - guint height_set : 1; - guint height_in_pixels : 1; - guint x_in_pixels : 1; - guint y_in_pixels : 1; - - /* Whether the pixbuf has changed */ - guint need_pixbuf_update : 1; - - /* Whether the transformation or size have changed */ - guint need_xform_update : 1; -} PixbufPrivate; - - - -/* Object argument IDs */ -enum { - ARG_0, - ARG_PIXBUF, - ARG_WIDTH, - ARG_WIDTH_SET, - ARG_WIDTH_IN_PIXELS, - ARG_HEIGHT, - ARG_HEIGHT_SET, - ARG_HEIGHT_IN_PIXELS, - ARG_X, - ARG_X_IN_PIXELS, - ARG_Y, - ARG_Y_IN_PIXELS -}; - -static void gnome_canvas_pixbuf_class_init (GnomeCanvasPixbufClass *class); -static void gnome_canvas_pixbuf_init (GnomeCanvasPixbuf *cpb); -static void gnome_canvas_pixbuf_destroy (GtkObject *object); -static void gnome_canvas_pixbuf_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void gnome_canvas_pixbuf_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); - -static void gnome_canvas_pixbuf_update (GnomeCanvasItem *item, double *affine, - ArtSVP *clip_path, int flags); -static void gnome_canvas_pixbuf_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height); -static void gnome_canvas_pixbuf_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf); -static double gnome_canvas_pixbuf_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, - GnomeCanvasItem **actual_item); -static void gnome_canvas_pixbuf_bounds (GnomeCanvasItem *item, - double *x1, double *y1, double *x2, double *y2); - -static GnomeCanvasItemClass *parent_class; - - - -/** - * gnome_canvas_pixbuf_get_type: - * @void: - * - * Registers the #GnomeCanvasPixbuf class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #GnomeCanvasPixbuf class. - **/ -GtkType -gnome_canvas_pixbuf_get_type (void) -{ - static GtkType canvas_pixbuf_type = 0; - - if (!canvas_pixbuf_type) { - static const GtkTypeInfo canvas_pixbuf_info = { - "GnomeCanvasPixbuf", - sizeof (GnomeCanvasPixbuf), - sizeof (GnomeCanvasPixbufClass), - (GtkClassInitFunc) gnome_canvas_pixbuf_class_init, - (GtkObjectInitFunc) gnome_canvas_pixbuf_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - canvas_pixbuf_type = gtk_type_unique (gnome_canvas_item_get_type (), - &canvas_pixbuf_info); - } - - return canvas_pixbuf_type; -} - -/* Class initialization function for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_class_init (GnomeCanvasPixbufClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type ()); - - gtk_object_add_arg_type ("GnomeCanvasPixbuf::pixbuf", - GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_PIXBUF); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_WIDTH); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width_set", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WIDTH_SET); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::width_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WIDTH_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_HEIGHT); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height_set", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HEIGHT_SET); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::height_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HEIGHT_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::x", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_X); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::x_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_X_IN_PIXELS); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::y", - GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_Y); - gtk_object_add_arg_type ("GnomeCanvasPixbuf::y_in_pixels", - GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_Y_IN_PIXELS); - - - object_class->destroy = gnome_canvas_pixbuf_destroy; - object_class->set_arg = gnome_canvas_pixbuf_set_arg; - object_class->get_arg = gnome_canvas_pixbuf_get_arg; - - item_class->update = gnome_canvas_pixbuf_update; - item_class->draw = gnome_canvas_pixbuf_draw; - item_class->render = gnome_canvas_pixbuf_render; - item_class->point = gnome_canvas_pixbuf_point; - item_class->bounds = gnome_canvas_pixbuf_bounds; -} - -/* Object initialization function for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_init (GnomeCanvasPixbuf *gcp) -{ - PixbufPrivate *priv; - - priv = g_new0 (PixbufPrivate, 1); - gcp->priv = priv; - - priv->width = 0.0; - priv->height = 0.0; - priv->x = 0.0; - priv->y = 0.0; -} - -/* Destroy handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_destroy (GtkObject *object) -{ - GnomeCanvasItem *item; - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (GNOME_IS_CANVAS_PIXBUF (object)); - - item = GNOME_CANVAS_ITEM (object); - gcp = (GNOME_CANVAS_PIXBUF (object)); - priv = gcp->priv; - - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - if (priv->pixbuf) - gdk_pixbuf_unref (priv->pixbuf); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Set_arg handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - GdkPixbuf *pixbuf; - double val; - - item = GNOME_CANVAS_ITEM (object); - gcp = GNOME_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (arg_id) { - case ARG_PIXBUF: - pixbuf = GTK_VALUE_POINTER (*arg); - if (pixbuf != priv->pixbuf) { - if (pixbuf) { - g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB); - g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4); - g_return_if_fail (pixbuf->bits_per_sample == 8); - - gdk_pixbuf_ref (pixbuf); - } - - if (priv->pixbuf) - gdk_pixbuf_unref (priv->pixbuf); - - priv->pixbuf = pixbuf; - } - - priv->need_pixbuf_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH: - val = GTK_VALUE_DOUBLE (*arg); - g_return_if_fail (val >= 0.0); - priv->width = val; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH_SET: - priv->width_set = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_WIDTH_IN_PIXELS: - priv->width_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT: - val = GTK_VALUE_DOUBLE (*arg); - g_return_if_fail (val >= 0.0); - priv->height = val; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT_SET: - priv->height_set = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_HEIGHT_IN_PIXELS: - priv->height_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_X: - priv->x = GTK_VALUE_DOUBLE (*arg); - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_X_IN_PIXELS: - priv->x_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_Y: - priv->y = GTK_VALUE_DOUBLE (*arg); - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - case ARG_Y_IN_PIXELS: - priv->y_in_pixels = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - priv->need_xform_update = TRUE; - gnome_canvas_item_request_update (item); - break; - - default: - break; - } -} - -/* Get_arg handler for the pixbuf canvasi item */ -static void -gnome_canvas_pixbuf_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = GNOME_CANVAS_PIXBUF (object); - priv = gcp->priv; - - switch (arg_id) { - case ARG_PIXBUF: - GTK_VALUE_POINTER (*arg) = priv->pixbuf; - break; - - case ARG_WIDTH: - GTK_VALUE_DOUBLE (*arg) = priv->width; - break; - - case ARG_WIDTH_SET: - GTK_VALUE_BOOL (*arg) = priv->width_set; - break; - - case ARG_WIDTH_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->width_in_pixels; - break; - - case ARG_HEIGHT: - GTK_VALUE_DOUBLE (*arg) = priv->height; - break; - - case ARG_HEIGHT_SET: - GTK_VALUE_BOOL (*arg) = priv->height_set; - break; - - case ARG_HEIGHT_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->height_in_pixels; - break; - - case ARG_X: - GTK_VALUE_DOUBLE (*arg) = priv->x; - break; - - case ARG_X_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->x_in_pixels; - break; - - case ARG_Y: - GTK_VALUE_DOUBLE (*arg) = priv->y; - break; - - case ARG_Y_IN_PIXELS: - GTK_VALUE_BOOL (*arg) = priv->y_in_pixels; - break; - - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - - - -/* Bounds and utilities */ - -/* Computes the amount by which the unit horizontal and vertical vectors will be - * scaled by an affine transformation. - */ -static void -compute_xform_scaling (double *affine, ArtPoint *i_c, ArtPoint *j_c) -{ - ArtPoint orig, orig_c; - ArtPoint i, j; - - /* Origin */ - - orig.x = 0.0; - orig.y = 0.0; - art_affine_point (&orig_c, &orig, affine); - - /* Horizontal and vertical vectors */ - - i.x = 1.0; - i.y = 0.0; - art_affine_point (i_c, &i, affine); - i_c->x -= orig_c.x; - i_c->y -= orig_c.y; - - j.x = 0.0; - j.y = 1.0; - art_affine_point (j_c, &j, affine); - j_c->x -= orig_c.x; - j_c->y -= orig_c.y; -} - -/* computes the addtional resolution dependent affine needed to - * fit the image within its viewport defined by x,y,width and height - * args - */ -static void -compute_viewport_affine (GnomeCanvasPixbuf *gcp, double *viewport_affine, double *i2c) -{ - PixbufPrivate *priv; - ArtPoint i_c, j_c; - double i_len, j_len; - double si_len, sj_len; - double ti_len, tj_len; - double scale[6], translate[6]; - double w, h; - - priv = gcp->priv; - - /* Compute scaling vectors and required width/height */ - - compute_xform_scaling (i2c, &i_c, &j_c); - - i_len = sqrt (i_c.x * i_c.x + i_c.y * i_c.y); - j_len = sqrt (j_c.x * j_c.x + j_c.y * j_c.y); - - if (priv->width_set) - w = priv->width; - else - w = priv->pixbuf->width; - - if (priv->height_set) - h = priv->height; - else - h = priv->pixbuf->height; - - /* Convert i_len and j_len into scaling factors */ - - if (priv->width_in_pixels) { - if (i_len > GNOME_CANVAS_EPSILON) - si_len = 1.0 / i_len; - else - si_len = 0.0; - } else - si_len = 1.0; - - si_len *= w / priv->pixbuf->width; - - if (priv->height_in_pixels) { - if (j_len > GNOME_CANVAS_EPSILON) - sj_len = 1.0 / j_len; - else - sj_len = 0.0; - } else - sj_len = 1.0; - - sj_len *= h / priv->pixbuf->height; - - /* Calculate translation offsets */ - - if (priv->x_in_pixels) { - if (i_len > GNOME_CANVAS_EPSILON) - ti_len = 1.0 / i_len; - else - ti_len = 0.0; - } else - ti_len = 1.0; - - ti_len *= priv->x; - - if (priv->y_in_pixels) { - if (j_len > GNOME_CANVAS_EPSILON) - tj_len = 1.0 / j_len; - else - tj_len = 0.0; - } else - tj_len = 1.0; - - tj_len *= priv->y; - - /* Compute the final affine */ - - art_affine_scale (scale, si_len, sj_len); - art_affine_translate (translate, ti_len, tj_len); - art_affine_multiply (viewport_affine, scale, translate); -} - -/* Computes the affine transformation with which the pixbuf needs to be - * transformed to render it on the canvas. This is not the same as the - * item_to_canvas transformation because we may need to scale the pixbuf - * by some other amount. - */ -static void -compute_render_affine (GnomeCanvasPixbuf *gcp, double *render_affine, double *i2c) -{ - double viewport_affine[6]; - - compute_viewport_affine (gcp, viewport_affine, i2c); - art_affine_multiply (render_affine, viewport_affine, i2c); -} - -/* Recomputes the bounding box of a pixbuf canvas item. The horizontal and - * vertical dimensions may be specified in units or pixels, separately, so we - * have to compute the components individually for each dimension. - */ -static void -recompute_bounding_box (GnomeCanvasPixbuf *gcp) -{ - GnomeCanvasItem *item; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - ArtDRect rect; - - item = GNOME_CANVAS_ITEM (gcp); - priv = gcp->priv; - - if (!priv->pixbuf) { - item->x1 = item->y1 = item->x2 = item->y2 = 0.0; - return; - } - - rect.x0 = 0.0; - rect.x1 = priv->pixbuf->width; - - rect.y0 = 0.0; - rect.y1 = priv->pixbuf->height; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - art_drect_affine_transform (&rect, &rect, render_affine); - - item->x1 = floor (rect.x0); - item->y1 = floor (rect.y0); - item->x2 = ceil (rect.x1); - item->y2 = ceil (rect.y1); -} - - - -/* Update sequence */ - -/* Update handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (parent_class->update) - (* parent_class->update) (item, affine, clip_path, flags); - - if (((flags & GNOME_CANVAS_UPDATE_VISIBILITY) - && !(GTK_OBJECT_FLAGS (item) & GNOME_CANVAS_ITEM_VISIBLE)) - || (flags & GNOME_CANVAS_UPDATE_AFFINE) - || priv->need_pixbuf_update - || priv->need_xform_update) - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - - /* If we need a pixbuf update, or if the item changed visibility to - * shown, recompute the bounding box. - */ - if (priv->need_pixbuf_update - || priv->need_xform_update - || ((flags & GNOME_CANVAS_UPDATE_VISIBILITY) - && (GTK_OBJECT_FLAGS (gcp) & GNOME_CANVAS_ITEM_VISIBLE)) - || (flags & GNOME_CANVAS_UPDATE_AFFINE)) { - recompute_bounding_box (gcp); - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); - priv->need_pixbuf_update = FALSE; - priv->need_xform_update = FALSE; - } -} - - - -/* Rendering */ - -/* This is private to libart, but we need it. Sigh. */ -extern void art_rgb_affine_run (int *p_x0, int *p_x1, int y, int src_width, int src_height, - const double affine[6]); - -/* Fills the specified buffer with the transformed version of a pixbuf */ -static void -transform_pixbuf (guchar *dest, int x, int y, int width, int height, int rowstride, - GdkPixbuf *pixbuf, double *affine) -{ - int xx, yy; - double inv[6]; - guchar *src, *d; - ArtPoint src_p, dest_p; - int run_x1, run_x2; - int src_x, src_y; - int i; - - art_affine_invert (inv, affine); - - for (yy = 0; yy < height; yy++) { - dest_p.y = y + yy + 0.5; - - run_x1 = x; - run_x2 = x + width; - art_rgb_affine_run (&run_x1, &run_x2, yy + y, - pixbuf->width, pixbuf->height, - inv); - - d = dest + yy * rowstride + (run_x1 - x) * 4; - - for (xx = run_x1; xx < run_x2; xx++) { - dest_p.x = xx + 0.5; - art_affine_point (&src_p, &dest_p, inv); - src_x = floor (src_p.x); - src_y = floor (src_p.y); - - src = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * pixbuf->n_channels; - - for (i = 0; i < pixbuf->n_channels; i++) - *d++ = *src++; - - if (!pixbuf->has_alpha) - *d++ = 255; /* opaque */ - } - } -} - -/* Draw handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_draw (GnomeCanvasItem *item, GdkDrawable *drawable, - int x, int y, int width, int height) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - guchar *buf; - GdkPixbuf *pixbuf; - ArtIRect p_rect, a_rect, d_rect; - int w, h; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) - return; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - - /* Compute the area we need to repaint */ - - p_rect.x0 = item->x1; - p_rect.y0 = item->y1; - p_rect.x1 = item->x2; - p_rect.y1 = item->y2; - - a_rect.x0 = x; - a_rect.y0 = y; - a_rect.x1 = x + width; - a_rect.y1 = y + height; - - art_irect_intersect (&d_rect, &p_rect, &a_rect); - if (art_irect_empty (&d_rect)) - return; - - /* Create a temporary buffer and transform the pixbuf there */ - - w = d_rect.x1 - d_rect.x0; - h = d_rect.y1 - d_rect.y0; - - buf = g_new0 (guchar, w * h * 4); - transform_pixbuf (buf, - d_rect.x0, d_rect.y0, - w, h, - w * 4, - priv->pixbuf, render_affine); - - pixbuf = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, TRUE, 8, w, h, w * 4, NULL, NULL); - - gdk_pixbuf_render_to_drawable_alpha (pixbuf, drawable, - 0, 0, - d_rect.x0 - x, d_rect.y0 - y, - w, h, - GDK_PIXBUF_ALPHA_BILEVEL, - 128, - GDK_RGB_DITHER_MAX, - d_rect.x0, d_rect.y0); - - gdk_pixbuf_unref (pixbuf); - g_free (buf); -} - -/* Render handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_render (GnomeCanvasItem *item, GnomeCanvasBuf *buf) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6]; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) - return; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - gnome_canvas_buf_ensure_buf (buf); - - if (priv->pixbuf->has_alpha) - art_rgb_rgba_affine (buf->buf, - buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, - buf->buf_rowstride, - priv->pixbuf->pixels, - priv->pixbuf->width, priv->pixbuf->height, - priv->pixbuf->rowstride, - render_affine, - ART_FILTER_NEAREST, - NULL); - else - art_rgb_affine (buf->buf, - buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1, - buf->buf_rowstride, - priv->pixbuf->pixels, - priv->pixbuf->width, priv->pixbuf->height, - priv->pixbuf->rowstride, - render_affine, - ART_FILTER_NEAREST, - NULL); - - buf->is_bg = FALSE; -} - - - -/* Point handler for the pixbuf canvas item */ -static double -gnome_canvas_pixbuf_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, - GnomeCanvasItem **actual_item) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], render_affine[6], inv[6]; - ArtPoint c, p; - int px, py; - double no_hit; - guchar *src; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - *actual_item = item; - - no_hit = item->canvas->pixels_per_unit * 2 + 10; - - if (!priv->pixbuf) - return no_hit; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_render_affine (gcp, render_affine, i2c); - art_affine_invert (inv, render_affine); - - c.x = cx; - c.y = cy; - art_affine_point (&p, &c, inv); - px = p.x; - py = p.y; - - if (px < 0 || px >= priv->pixbuf->width || py < 0 || py >= priv->pixbuf->height) - return no_hit; - - if (!priv->pixbuf->has_alpha) - return 0.0; - - src = priv->pixbuf->pixels + py * priv->pixbuf->rowstride + px * priv->pixbuf->n_channels; - - if (src[3] < 128) - return no_hit; - else - return 0.0; -} - - - -/* Bounds handler for the pixbuf canvas item */ -static void -gnome_canvas_pixbuf_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2) -{ - GnomeCanvasPixbuf *gcp; - PixbufPrivate *priv; - double i2c[6], viewport_affine[6]; - ArtDRect rect; - - gcp = GNOME_CANVAS_PIXBUF (item); - priv = gcp->priv; - - if (!priv->pixbuf) { - *x1 = *y1 = *x2 = *y2 = 0.0; - return; - } - - rect.x0 = 0.0; - rect.x1 = priv->pixbuf->width; - - rect.y0 = 0.0; - rect.y1 = priv->pixbuf->height; - - gnome_canvas_item_i2c_affine (item, i2c); - compute_viewport_affine (gcp, viewport_affine, i2c); - art_drect_affine_transform (&rect, &rect, viewport_affine); - - *x1 = rect.x0; - *y1 = rect.y0; - *x2 = rect.x1; - *y2 = rect.y1; -} diff --git a/gdk-pixbuf/gnome-canvas-pixbuf.h b/gdk-pixbuf/gnome-canvas-pixbuf.h deleted file mode 100644 index 822f5899f5..0000000000 --- a/gdk-pixbuf/gnome-canvas-pixbuf.h +++ /dev/null @@ -1,64 +0,0 @@ -/* GNOME libraries - GdkPixbuf item for the GNOME canvas - * - * Copyright (C) 1999 The Free Software Foundation - * - * Author: Federico Mena-Quintero <federico@gimp.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef GNOME_CANVAS_PIXBUF_H -#define GNOME_CANVAS_PIXBUF_H - -#include <libgnome/gnome-defs.h> -#include <libgnomeui/gnome-canvas.h> - -BEGIN_GNOME_DECLS - - - -#define GNOME_TYPE_CANVAS_PIXBUF (gnome_canvas_pixbuf_get_type ()) -#define GNOME_CANVAS_PIXBUF(obj) (GTK_CHECK_CAST ((obj), \ - GNOME_TYPE_CANVAS_PIXBUF, GnomeCanvasPixbuf)) -#define GNOME_CANVAS_PIXBUF_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ - GNOME_TYPE_CANVAS_PIXBUF, GnomeCanvasPixbufClass)) -#define GNOME_IS_CANVAS_PIXBUF(obj) (GTK_CHECK_TYPE ((obj), GNOME_TYPE_CANVAS_PIXBUF)) -#define GNOME_IS_CANVAS_PIXBUF_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \ - GNOME_TYPE_CANVAS_PIXBUF)) - - -typedef struct _GnomeCanvasPixbuf GnomeCanvasPixbuf; -typedef struct _GnomeCanvasPixbufClass GnomeCanvasPixbufClass; - -struct _GnomeCanvasPixbuf { - GnomeCanvasItem item; - - /* Private data */ - gpointer priv; -}; - -struct _GnomeCanvasPixbufClass { - GnomeCanvasItemClass parent_class; -}; - - -GtkType gnome_canvas_pixbuf_get_type (void) G_GNUC_CONST; - - - -END_GNOME_DECLS - -#endif diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c index 18ef7bc904..b090957beb 100644 --- a/gdk-pixbuf/io-bmp.c +++ b/gdk-pixbuf/io-bmp.c @@ -176,17 +176,19 @@ gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc - anim_done_func, gpointer user_data); + anim_done_func, gpointer user_data, + GError **error); void gdk_pixbuf__bmp_image_stop_load(gpointer data); gboolean gdk_pixbuf__bmp_image_load_increment(gpointer data, guchar * buf, - guint size); + guint size, + GError **error); /* Shared library entry point --> This should be removed when generic_image_load enters gdk-pixbuf-io. */ -GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f) +GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f, GError **error) { guchar membuf[4096]; size_t length; @@ -195,15 +197,22 @@ GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f) GdkPixbuf *pb; State = - gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL, NULL, NULL); + gdk_pixbuf__bmp_image_begin_load(NULL, NULL, NULL, NULL, NULL, + error); + if (State == NULL) + return NULL; + while (feof(f) == 0) { length = fread(membuf, 1, 4096, f); if (length > 0) - (void) - gdk_pixbuf__bmp_image_load_increment(State, - membuf, - length); + if (!gdk_pixbuf__bmp_image_load_increment(State, + membuf, + length, + error)) { + gdk_pixbuf__bmp_image_stop_load (State); + return NULL; + } } if (State->pixbuf != NULL) @@ -309,7 +318,8 @@ gdk_pixbuf__bmp_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc - anim_done_func, gpointer user_data) + anim_done_func, gpointer user_data, + GError **error) { struct bmp_progressive_state *context; @@ -695,8 +705,10 @@ void DoCompressedByte(struct bmp_progressive_state *context, guchar ** buf, * * append image data onto inrecrementally built output image */ -gboolean gdk_pixbuf__bmp_image_load_increment(gpointer data, guchar * buf, - guint size) +gboolean gdk_pixbuf__bmp_image_load_increment(gpointer data, + guchar * buf, + guint size, + GError **error) { struct bmp_progressive_state *context = (struct bmp_progressive_state *) data; diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c index 681e915da1..e61f41fb87 100644 --- a/gdk-pixbuf/io-gif.c +++ b/gdk-pixbuf/io-gif.c @@ -180,6 +180,9 @@ struct _GifContext gint draw_xpos; gint draw_ypos; gint draw_pass; + + /* error pointer */ + GError **error; }; static int GetDataBlock (GifContext *, unsigned char *); @@ -204,7 +207,7 @@ gif_read (GifContext *context, guchar *buffer, size_t len) count += len; g_print ("Fsize :%d\tcount :%d\t", len, count); #endif - retval = (fread(buffer, len, 1, context->file) != 0); + retval = (fread(buffer, len, 1, context->file) != 0); #ifdef IO_GIFDEBUG if (len < 100) { for (i = 0; i < len; i++) @@ -212,6 +215,7 @@ gif_read (GifContext *context, guchar *buffer, size_t len) } g_print ("\n"); #endif + return retval; } else { #ifdef IO_GIFDEBUG @@ -416,10 +420,21 @@ gif_lzw_fill_buffer (GifContext *context) if (context->code_done) { if (context->code_curbit >= context->code_lastbit) { - g_message ("GIF: ran off the end of by bits\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("GIF file was missing some data (perhaps it was truncated somehow?)")); + return -2; } - g_message ("trying to read more data after we've done stuff\n"); + /* Is this supposed to be an error or what? */ + /* g_message ("trying to read more data after we've done stuff\n"); */ + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error in the GIF loader (%s)"), + G_STRLOC); + return -2; } @@ -563,8 +578,10 @@ lzw_read_byte (GifContext *context) *(context->lzw_sp)++ = context->lzw_table[1][code]; if (code == context->lzw_table[0][code]) { - /*g_message (_("GIF: circular table entry BIG ERROR\n"));*/ - /*gimp_quit ();*/ + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Circular table entry in GIF file")); return -2; } code = context->lzw_table[0][code]; @@ -890,12 +907,18 @@ gif_init (GifContext *context) char version[4]; if (!gif_read (context, buf, 6)) { - /* Unable to read magic number */ + /* Unable to read magic number, + * gif_read() should have set error + */ return -1; } if (strncmp ((char *) buf, "GIF", 3) != 0) { /* Not a GIF file */ + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("File does not appear to be a GIF file")); return -1; } @@ -904,12 +927,17 @@ gif_init (GifContext *context) if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0)) { /* bad version number, not '87a' or '89a' */ + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Version %s of the GIF file format is not supported"), + version); return -1; } /* read the screen descriptor */ if (!gif_read (context, buf, 7)) { - /* Failed to read screen descriptor */ + /* Failed to read screen descriptor, error set */ return -1; } @@ -950,6 +978,12 @@ gif_get_frame_info (GifContext *context) if (context->frame_height > context->height) { /* we don't want to resize things. So we exit */ context->state = GIF_DONE; + + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("GIF animation contained a frame with an incorrect size")); + return -2; } @@ -1092,7 +1126,7 @@ new_context (void) } /* Shared library entry point */ GdkPixbuf * -gdk_pixbuf__gif_image_load (FILE *file) +gdk_pixbuf__gif_image_load (FILE *file, GError **error) { GifContext *context; GdkPixbuf *pixbuf; @@ -1101,7 +1135,8 @@ gdk_pixbuf__gif_image_load (FILE *file) context = new_context (); context->file = file; - + context->error = error; + gif_main_loop (context); pixbuf = context->pixbuf; @@ -1115,7 +1150,8 @@ gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { GifContext *context; @@ -1123,6 +1159,7 @@ gdk_pixbuf__gif_image_begin_load (ModulePreparedNotifyFunc prepare_func, count = 0; #endif context = new_context (); + context->error = error; context->prepare_func = prepare_func; context->update_func = update_func; context->frame_done_func = frame_done_func; @@ -1148,11 +1185,14 @@ gdk_pixbuf__gif_image_stop_load (gpointer data) } gboolean -gdk_pixbuf__gif_image_load_increment (gpointer data, guchar *buf, guint size) +gdk_pixbuf__gif_image_load_increment (gpointer data, guchar *buf, guint size, + GError **error) { gint retval; GifContext *context = (GifContext *) data; + context->error = error; + if (context->amount_needed == 0) { /* we aren't looking for some bytes. */ /* we can use buf now, but we don't want to keep it around at all. @@ -1206,7 +1246,8 @@ gdk_pixbuf__gif_image_load_increment (gpointer data, guchar *buf, guint size) } GdkPixbufAnimation * -gdk_pixbuf__gif_image_load_animation (FILE *file) +gdk_pixbuf__gif_image_load_animation (FILE *file, + GError **error) { GifContext *context; GdkPixbufAnimation *animation; @@ -1214,6 +1255,9 @@ gdk_pixbuf__gif_image_load_animation (FILE *file) g_return_val_if_fail (file != NULL, NULL); context = new_context (); + + context->error = error; + context->animation = g_object_new (GDK_TYPE_PIXBUF_ANIMATION, NULL); context->animation->n_frames = 0; diff --git a/gdk-pixbuf/io-ico.c b/gdk-pixbuf/io-ico.c index 83e2cf93bd..a85fee2806 100644 --- a/gdk-pixbuf/io-ico.c +++ b/gdk-pixbuf/io-ico.c @@ -158,16 +158,18 @@ gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data); + gpointer user_data, + GError **error); void gdk_pixbuf__ico_image_stop_load(gpointer data); -gboolean gdk_pixbuf__ico_image_load_increment(gpointer data, guchar * buf, guint size); +gboolean gdk_pixbuf__ico_image_load_increment(gpointer data, guchar * buf, guint size, + GError **error); /* Shared library entry point --> Can go when generic_image_load enters gdk-pixbuf-io */ GdkPixbuf * -gdk_pixbuf__ico_image_load(FILE * f) +gdk_pixbuf__ico_image_load(FILE * f, GError **error) { guchar *membuf; size_t length; @@ -175,7 +177,11 @@ gdk_pixbuf__ico_image_load(FILE * f) GdkPixbuf *pb; - State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL, NULL, NULL); + State = gdk_pixbuf__ico_image_begin_load(NULL, NULL, NULL, + NULL, NULL, error); + if (State == NULL) + return NULL; + membuf = g_malloc(4096); g_assert(membuf != NULL); @@ -183,8 +189,11 @@ gdk_pixbuf__ico_image_load(FILE * f) while (feof(f) == 0) { length = fread(membuf, 1, 4096, f); if (length > 0) - gdk_pixbuf__ico_image_load_increment(State, membuf, length); - + if (!gdk_pixbuf__ico_image_load_increment(State, membuf, length, + error)) { + gdk_pixbuf__ico_image_stop_load (State); + return NULL; + } } g_free(membuf); if (State->pixbuf != NULL) @@ -370,7 +379,8 @@ gdk_pixbuf__ico_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { struct ico_progressive_state *context; @@ -633,7 +643,8 @@ static void OneLine(struct ico_progressive_state *context) * append image data onto inrecrementally built output image */ gboolean -gdk_pixbuf__ico_image_load_increment(gpointer data, guchar * buf, guint size) +gdk_pixbuf__ico_image_load_increment(gpointer data, guchar * buf, guint size, + GError **error) { struct ico_progressive_state *context = (struct ico_progressive_state *) data; diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index 623077738d..332de30c99 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -74,6 +74,7 @@ typedef my_source_mgr * my_src_ptr; struct error_handler_data { struct jpeg_error_mgr pub; sigjmp_buf setjmp_buffer; + GError **error; }; /* progressive loader context */ @@ -92,30 +93,51 @@ typedef struct { struct error_handler_data jerr; } JpegProgContext; -GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f); +GdkPixbuf *gdk_pixbuf__jpeg_image_load (FILE *f, GError **error); gpointer gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc func, ModuleUpdatedNotifyFunc func2, ModuleFrameDoneNotifyFunc func3, ModuleAnimationDoneNotifyFunc func4, - gpointer user_data); + gpointer user_data, + GError **error); void gdk_pixbuf__jpeg_image_stop_load (gpointer context); -gboolean gdk_pixbuf__jpeg_image_load_increment(gpointer context, guchar *buf, guint size); +gboolean gdk_pixbuf__jpeg_image_load_increment(gpointer context, guchar *buf, guint size, + GError **error); static void fatal_error_handler (j_common_ptr cinfo) { - /* FIXME: - * We should somehow signal what error occurred to the caller so the - * caller can handle the error message */ struct error_handler_data *errmgr; - + char buffer[JMSG_LENGTH_MAX]; + errmgr = (struct error_handler_data *) cinfo->err; - cinfo->err->output_message (cinfo); + + /* Create the message */ + (* cinfo->err->format_message) (cinfo, buffer); + + /* broken check for *error == NULL for robustness against + * crappy JPEG library + */ + if (errmgr->error && *errmgr->error == NULL) { + g_set_error (errmgr->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Error interpreting JPEG image file (%s)"), + buffer); + } + siglongjmp (errmgr->setjmp_buffer, 1); - /* incase the jmp buf isn't initted? */ - exit(1); + g_assert_not_reached (); +} + +static void +output_message_handler (j_common_ptr cinfo) +{ + /* This method keeps libjpeg from dumping crap to stderr */ + + /* do nothing */ } /* Destroy notification function for the pixbuf */ @@ -158,7 +180,7 @@ explode_gray_into_buf (struct jpeg_decompress_struct *cinfo, /* Shared library entry point */ GdkPixbuf * -gdk_pixbuf__jpeg_image_load (FILE *f) +gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) { gint w, h, i; guchar *pixels = NULL; @@ -175,7 +197,10 @@ gdk_pixbuf__jpeg_image_load (FILE *f) /* setup error handler */ cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = fatal_error_handler; + jerr.pub.output_message = output_message_handler; + jerr.error = error; + if (sigsetjmp (jerr.setjmp_buffer, 1)) { /* Whoops there was a jpeg error */ if (pixels) @@ -199,6 +224,17 @@ gdk_pixbuf__jpeg_image_load (FILE *f) pixels = malloc (h * w * 3); if (!pixels) { jpeg_destroy_decompress (&cinfo); + + /* broken check for *error == NULL for robustness against + * crappy JPEG library + */ + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to load image, try exiting some applications to free memory")); + } + return NULL; } @@ -286,7 +322,8 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { JpegProgContext *context; my_source_mgr *src; @@ -308,7 +345,9 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func, context->cinfo.err = jpeg_std_error (&context->jerr.pub); context->jerr.pub.error_exit = fatal_error_handler; - + context->jerr.pub.output_message = output_message_handler; + context->jerr.error = error; + src = (my_src_ptr) context->cinfo.src; src->pub.init_source = init_source; src->pub.fill_input_buffer = fill_input_buffer; @@ -318,6 +357,8 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func, src->pub.bytes_in_buffer = 0; src->pub.next_input_byte = NULL; + context->jerr.error = NULL; + return (gpointer) context; } @@ -364,7 +405,8 @@ gdk_pixbuf__jpeg_image_stop_load (gpointer data) * append image data onto inrecrementally built output image */ gboolean -gdk_pixbuf__jpeg_image_load_increment (gpointer data, guchar *buf, guint size) +gdk_pixbuf__jpeg_image_load_increment (gpointer data, guchar *buf, guint size, + GError **error) { JpegProgContext *context = (JpegProgContext *)data; struct jpeg_decompress_struct *cinfo; @@ -382,6 +424,8 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, guchar *buf, guint size) cinfo = &context->cinfo; + context->jerr.error = error; + /* XXXXXXX (drmike) - loop(s) below need to be recoded now I * have a grasp of what the flow needs to be! */ @@ -641,12 +685,13 @@ gdk_pixbuf__jpeg_image_save (FILE *f, g_return_val_if_fail (pixels != NULL, FALSE); /* allocate a small buffer to convert image data */ - buf = malloc (w * 3 * sizeof (guchar)); - g_return_val_if_fail (buf != NULL, FALSE); + buf = g_malloc (w * 3 * sizeof (guchar)); /* set up error handling */ jerr.pub.error_exit = fatal_error_handler; - + jerr.pub.output_message = output_message_handler; + jerr.error = error; + cinfo.err = jpeg_std_error (&(jerr.pub)); if (sigsetjmp (jerr.setjmp_buffer, 1)) { jpeg_destroy_compress (&cinfo); diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c index 33fa2cf68f..bd945f7943 100644 --- a/gdk-pixbuf/io-png.c +++ b/gdk-pixbuf/io-png.c @@ -140,6 +140,38 @@ setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr, #endif } +static void +png_simple_error_callback(png_structp png_save_ptr, + png_const_charp error_msg) +{ + GError **error; + + error = png_get_error_ptr(png_save_ptr); + + /* I don't trust libpng to call the error callback only once, + * so check for already-set error + */ + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Fatal error saving PNG image file: %s"), + error_msg); + } +} + +static void +png_simple_warning_callback(png_structp png_save_ptr, + png_const_charp warning_msg) +{ + /* Don't print anything; we should not be dumping junk to + * stderr, since that may be bad for some apps. If it's + * important enough to display, we need to add a GError + * **warning return location wherever we have an error return + * location. + */ +} + /* Destroy notification function for the pixbuf */ static void free_buffer (guchar *pixels, gpointer data) @@ -149,7 +181,7 @@ free_buffer (guchar *pixels, gpointer data) /* Shared library entry point */ GdkPixbuf * -gdk_pixbuf__png_image_load (FILE *f) +gdk_pixbuf__png_image_load (FILE *f, GError **error) { png_structp png_ptr; png_infop info_ptr, end_info; @@ -159,7 +191,10 @@ gdk_pixbuf__png_image_load (FILE *f) png_bytepp rows; guchar *pixels; - png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, + error, + png_simple_error_callback, + png_simple_warning_callback); if (!png_ptr) return NULL; @@ -197,6 +232,16 @@ gdk_pixbuf__png_image_load (FILE *f) pixels = malloc (w * h * bpp); if (!pixels) { + /* Check error NULL, normally this would be broken, + * but libpng makes me want to code defensively. + */ + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to load PNG file")); + } + png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); return NULL; } @@ -273,6 +318,7 @@ struct _LoadContext { guint fatal_error_occurred : 1; + GError **error; }; gpointer @@ -280,7 +326,8 @@ gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { LoadContext* lc; @@ -297,6 +344,7 @@ gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func, lc->first_pass_seen_in_chunk = -1; lc->last_pass_seen_in_chunk = -1; lc->max_row_seen_in_chunk = -1; + lc->error = error; /* Create the main PNG context struct */ @@ -308,13 +356,15 @@ gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func, if (lc->png_read_ptr == NULL) { g_free(lc); + /* error callback should have set the error */ return NULL; } - + if (setjmp (lc->png_read_ptr->jmpbuf)) { if (lc->png_info_ptr) png_destroy_read_struct(&lc->png_read_ptr, NULL, NULL); g_free(lc); + /* error callback should have set the error */ return NULL; } @@ -325,6 +375,7 @@ gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func, if (lc->png_info_ptr == NULL) { png_destroy_read_struct(&lc->png_read_ptr, NULL, NULL); g_free(lc); + /* error callback should have set the error */ return NULL; } @@ -335,6 +386,11 @@ gdk_pixbuf__png_image_begin_load (ModulePreparedNotifyFunc prepare_func, png_end_callback); + /* We don't want to keep modifying error after returning here, + * it may no longer be valid. + */ + lc->error = NULL; + return lc; } @@ -352,7 +408,8 @@ gdk_pixbuf__png_image_stop_load (gpointer context) } gboolean -gdk_pixbuf__png_image_load_increment(gpointer context, guchar *buf, guint size) +gdk_pixbuf__png_image_load_increment(gpointer context, guchar *buf, guint size, + GError **error) { LoadContext* lc = context; @@ -364,17 +421,20 @@ gdk_pixbuf__png_image_load_increment(gpointer context, guchar *buf, guint size) lc->first_pass_seen_in_chunk = -1; lc->last_pass_seen_in_chunk = -1; lc->max_row_seen_in_chunk = -1; + lc->error = error; /* Invokes our callbacks as needed */ if (setjmp (lc->png_read_ptr->jmpbuf)) { + lc->error = NULL; return FALSE; } else { png_process_data(lc->png_read_ptr, lc->png_info_ptr, buf, size); } - if (lc->fatal_error_occurred) + if (lc->fatal_error_occurred) { + lc->error = NULL; return FALSE; - else { + } else { if (lc->first_row_seen_in_chunk >= 0) { /* We saw at least one row */ gint pass_diff = lc->last_pass_seen_in_chunk - lc->first_pass_seen_in_chunk; @@ -417,6 +477,8 @@ gdk_pixbuf__png_image_load_increment(gpointer context, guchar *buf, guint size) lc->notify_user_data); } } + + lc->error = NULL; return TRUE; } @@ -437,7 +499,6 @@ png_info_callback (png_structp png_read_ptr, if (lc->fatal_error_occurred) return; - setup_png_transformations(lc->png_read_ptr, lc->png_info_ptr, @@ -458,6 +519,13 @@ png_info_callback (png_structp png_read_ptr, if (lc->pixbuf == NULL) { /* Failed to allocate memory */ lc->fatal_error_occurred = TRUE; + if (lc->error && *lc->error == NULL) { + g_set_error (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to store a %ld by %ld image; try exiting some applications to reduce memory usage"), + width, height); + } return; } @@ -521,8 +589,17 @@ png_error_callback(png_structp png_read_ptr, lc = png_get_error_ptr(png_read_ptr); lc->fatal_error_occurred = TRUE; - - fprintf(stderr, "Fatal error loading PNG: %s\n", error_msg); + + /* I don't trust libpng to call the error callback only once, + * so check for already-set error + */ + if (lc->error && *lc->error == NULL) { + g_set_error (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Fatal error reading PNG image file: %s"), + error_msg); + } } static void @@ -532,12 +609,18 @@ png_warning_callback(png_structp png_read_ptr, LoadContext* lc; lc = png_get_error_ptr(png_read_ptr); - - fprintf(stderr, "Warning loading PNG: %s\n", warning_msg); + + /* Don't print anything; we should not be dumping junk to + * stderr, since that may be bad for some apps. If it's + * important enough to display, we need to add a GError + * **warning return location wherever we have an error return + * location. + */ } /* Save */ + gboolean gdk_pixbuf__png_image_save (FILE *f, GdkPixbuf *pixbuf, @@ -545,8 +628,6 @@ gdk_pixbuf__png_image_save (FILE *f, gchar **values, GError **error) { - /* FIXME error handling is broken */ - png_structp png_ptr; png_infop info_ptr; guchar *ptr; @@ -583,7 +664,9 @@ gdk_pixbuf__png_image_save (FILE *f, pixels = gdk_pixbuf_get_pixels (pixbuf); png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); + error, + png_simple_error_callback, + png_simple_warning_callback); g_return_val_if_fail (png_ptr != NULL, FALSE); @@ -599,8 +682,8 @@ gdk_pixbuf__png_image_save (FILE *f, png_init_io (png_ptr, f); if (has_alpha) { png_set_IHDR (png_ptr, info_ptr, w, h, bpc, - PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); #ifdef WORDS_BIGENDIAN png_set_swap_alpha (png_ptr); #else @@ -608,9 +691,23 @@ gdk_pixbuf__png_image_save (FILE *f, #endif } else { png_set_IHDR (png_ptr, info_ptr, w, h, bpc, - PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); data = malloc (w * 3 * sizeof (char)); + + if (data == NULL) { + /* Check error NULL, normally this would be broken, + * but libpng makes me want to code defensively. + */ + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to save PNG file")); + } + png_destroy_write_struct (&png_ptr, (png_infopp) NULL); + return FALSE; + } } sig_bit.red = bpc; sig_bit.green = bpc; diff --git a/gdk-pixbuf/io-pnm.c b/gdk-pixbuf/io-pnm.c index c91658cfd4..c352d611f8 100644 --- a/gdk-pixbuf/io-pnm.c +++ b/gdk-pixbuf/io-pnm.c @@ -76,17 +76,21 @@ typedef struct { gboolean got_header; /* have we loaded pnm header? */ guint scan_state; + + GError **error; } PnmLoaderContext; -GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f); +GdkPixbuf *gdk_pixbuf__pnm_image_load (FILE *f, GError **error); gpointer gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc func, ModuleUpdatedNotifyFunc func2, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data); + gpointer user_data, + GError **error); void gdk_pixbuf__pnm_image_stop_load (gpointer context); -gboolean gdk_pixbuf__pnm_image_load_increment (gpointer context, guchar *buf, guint size); +gboolean gdk_pixbuf__pnm_image_load_increment (gpointer context, guchar *buf, guint size, + GError **error); static void explode_bitmap_into_buf (PnmLoaderContext *context); static void explode_gray_into_buf (PnmLoaderContext *context); @@ -178,7 +182,7 @@ explode_gray_into_buf (PnmLoaderContext *context) /* skip over whitespace and comments in input buffer */ static gint -pnm_skip_whitespace (PnmIOBuffer *inbuf) +pnm_skip_whitespace (PnmIOBuffer *inbuf, GError **error) { register guchar *inptr; guchar *inend; @@ -208,7 +212,7 @@ pnm_skip_whitespace (PnmIOBuffer *inbuf) /* read next number from buffer */ static gint -pnm_read_next_value (PnmIOBuffer *inbuf, guint *value) +pnm_read_next_value (PnmIOBuffer *inbuf, guint *value, GError **error) { register guchar *inptr, *word, *p; guchar *inend, buf[128]; @@ -220,7 +224,7 @@ pnm_read_next_value (PnmIOBuffer *inbuf, guint *value) g_return_val_if_fail (value != NULL, PNM_FATAL_ERR); /* skip white space */ - if ((retval = pnm_skip_whitespace (inbuf)) != PNM_OK) + if ((retval = pnm_skip_whitespace (inbuf, error)) != PNM_OK) return retval; inend = inbuf->byte + inbuf->nbytes; @@ -237,8 +241,13 @@ pnm_read_next_value (PnmIOBuffer *inbuf, guint *value) /* get the value */ *value = strtol (buf, &endptr, 10); - if (*endptr != '\0') + if (*endptr != '\0') { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM loader expected to find an integer, but didn't")); return PNM_FATAL_ERR; + } inbuf->byte = p; inbuf->nbytes = (guint) (inend - p); @@ -263,8 +272,13 @@ pnm_read_header (PnmLoaderContext *context) if (inbuf->nbytes < 2) return PNM_SUSPEND; - if (*inbuf->byte != 'P') + if (*inbuf->byte != 'P') { + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM file has an incorrect initial byte")); return PNM_FATAL_ERR; + } inbuf->byte++; inbuf->nbytes--; @@ -289,6 +303,10 @@ pnm_read_header (PnmLoaderContext *context) context->type = PNM_FORMAT_PPM_RAW; break; default: + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM file is not in a recognized PNM subformat")); return PNM_FATAL_ERR; } @@ -303,13 +321,19 @@ pnm_read_header (PnmLoaderContext *context) /* read the pixmap width */ guint width = 0; - retval = pnm_read_next_value (inbuf, &width); + retval = pnm_read_next_value (inbuf, &width, + context->error); - if (retval != PNM_OK) + if (retval != PNM_OK) return retval; - if (!width) + if (!width) { + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM file has an image width of 0")); return PNM_FATAL_ERR; + } context->width = width; } @@ -318,13 +342,19 @@ pnm_read_header (PnmLoaderContext *context) /* read the pixmap height */ guint height = 0; - retval = pnm_read_next_value (inbuf, &height); + retval = pnm_read_next_value (inbuf, &height, + context->error); if (retval != PNM_OK) return retval; - if (!height) + if (!height) { + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM file has an image height of 0")); return PNM_FATAL_ERR; + } context->height = height; } @@ -335,13 +365,19 @@ pnm_read_header (PnmLoaderContext *context) case PNM_FORMAT_PGM: case PNM_FORMAT_PGM_RAW: if (!context->maxval) { - retval = pnm_read_next_value (inbuf, &context->maxval); + retval = pnm_read_next_value (inbuf, &context->maxval, + context->error); if (retval != PNM_OK) return retval; - if (context->maxval == 0) + if (context->maxval == 0) { + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Maximum color value in PNM file is 0")); return PNM_FATAL_ERR; + } } break; default: @@ -375,7 +411,10 @@ pnm_read_raw_scanline (PnmLoaderContext *context) numpix = inbuf->nbytes / 3; break; default: - g_warning ("io-pnm.c: Illegal raw pnm type!\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Raw PNM image type is invalid")); return PNM_FATAL_ERR; } @@ -400,7 +439,10 @@ pnm_read_raw_scanline (PnmLoaderContext *context) offset = context->output_col * 3; break; default: - g_warning ("io-pnm.c: Illegal raw pnm type!\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Raw PNM image type is invalid")); return PNM_FATAL_ERR; } @@ -429,7 +471,11 @@ pnm_read_raw_scanline (PnmLoaderContext *context) } break; default: - g_warning ("Invalid raw pnm format!"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Raw PNM image type is invalid")); + return PNM_FATAL_ERR; } inbuf->byte += numbytes; @@ -485,7 +531,11 @@ pnm_read_ascii_scanline (PnmLoaderContext *context) break; default: - g_warning ("Can't happen\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM image format is invalid")); + return PNM_FATAL_ERR; } @@ -499,7 +549,8 @@ pnm_read_ascii_scanline (PnmLoaderContext *context) } for (i = context->scan_state; i < numval; i++) { - retval = pnm_read_next_value (inbuf, &value); + retval = pnm_read_next_value (inbuf, &value, + context->error); if (retval != PNM_OK) { /* save state and return */ context->scan_state = i; @@ -522,7 +573,11 @@ pnm_read_ascii_scanline (PnmLoaderContext *context) *dptr++ = (guchar)(255 * value / context->maxval); break; default: - g_warning ("io-pnm.c: Illegal ascii pnm type!\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("PNM image format is invalid")); + return PNM_FATAL_ERR; break; } } @@ -577,7 +632,11 @@ pnm_read_scanline (PnmLoaderContext *context) return retval; break; default: - g_warning ("Cannot load these image types (yet)\n"); + g_set_error (context->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("PNM image loader does not support this PNM subformat")); + return PNM_FATAL_ERR; } @@ -586,7 +645,7 @@ pnm_read_scanline (PnmLoaderContext *context) /* Shared library entry point */ GdkPixbuf * -gdk_pixbuf__pnm_image_load (FILE *f) +gdk_pixbuf__pnm_image_load (FILE *f, GError **error) { PnmLoaderContext context; PnmIOBuffer *inbuf; @@ -608,6 +667,7 @@ gdk_pixbuf__pnm_image_load (FILE *f) context.got_header = FALSE; context.did_prescan = FALSE; context.scan_state = 0; + context.error = error; inbuf = &context.inbuf; @@ -647,7 +707,8 @@ gdk_pixbuf__pnm_image_load (FILE *f) /* scan until we hit image data */ if (!context.did_prescan) { - retval = pnm_skip_whitespace (inbuf); + retval = pnm_skip_whitespace (inbuf, + context.error); if (retval == PNM_FATAL_ERR) return NULL; else if (retval == PNM_SUSPEND) @@ -675,7 +736,7 @@ gdk_pixbuf__pnm_image_load (FILE *f) } else if (retval == PNM_FATAL_ERR) { if (context.pixbuf) gdk_pixbuf_unref (context.pixbuf); - g_warning ("io-pnm.c: error reading rows..\n"); + return NULL; } } @@ -703,7 +764,8 @@ gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { PnmLoaderContext *context; @@ -722,6 +784,8 @@ gdk_pixbuf__pnm_image_begin_load (ModulePreparedNotifyFunc prepared_func, context->inbuf.nbytes = 0; context->inbuf.byte = NULL; + + context->error = error; return (gpointer) context; } @@ -752,7 +816,8 @@ gdk_pixbuf__pnm_image_stop_load (gpointer data) * append image data onto inrecrementally built output image */ gboolean -gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size) +gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size, + GError **error) { PnmLoaderContext *context = (PnmLoaderContext *)data; PnmIOBuffer *inbuf; @@ -764,6 +829,8 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size) g_return_val_if_fail (context != NULL, FALSE); g_return_val_if_fail (buf != NULL, FALSE); + + context->error = error; bufhd = buf; inbuf = &context->inbuf; @@ -811,7 +878,8 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size) /* scan until we hit image data */ if (!context->did_prescan) { - retval = pnm_skip_whitespace (inbuf); + retval = pnm_skip_whitespace (inbuf, + context->error); if (retval == PNM_FATAL_ERR) return FALSE; @@ -850,7 +918,6 @@ gdk_pixbuf__pnm_image_load_increment (gpointer data, guchar *buf, guint size) } else if (retval == PNM_FATAL_ERR) { if (context->pixbuf) gdk_pixbuf_unref (context->pixbuf); - g_warning ("io-pnm.c: error reading rows.\n"); return FALSE; } else if (retval == PNM_OK) { /* send updated signal */ diff --git a/gdk-pixbuf/io-ras.c b/gdk-pixbuf/io-ras.c index e70f4c9e0d..dbcf7bc149 100644 --- a/gdk-pixbuf/io-ras.c +++ b/gdk-pixbuf/io-ras.c @@ -98,14 +98,16 @@ gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data); + gpointer user_data, + GError **error); void gdk_pixbuf__ras_image_stop_load(gpointer data); -gboolean gdk_pixbuf__ras_image_load_increment(gpointer data, guchar * buf, guint size); +gboolean gdk_pixbuf__ras_image_load_increment(gpointer data, guchar * buf, guint size, + GError **error); /* Shared library entry point */ -GdkPixbuf *gdk_pixbuf__ras_image_load(FILE * f) +GdkPixbuf *gdk_pixbuf__ras_image_load(FILE * f, GError **error) { guchar *membuf; size_t length; @@ -113,7 +115,8 @@ GdkPixbuf *gdk_pixbuf__ras_image_load(FILE * f) GdkPixbuf *pb; - State = gdk_pixbuf__ras_image_begin_load(NULL, NULL, NULL, NULL, NULL); + State = gdk_pixbuf__ras_image_begin_load(NULL, NULL, NULL, + NULL, NULL, error); membuf = g_malloc(4096); @@ -121,8 +124,12 @@ GdkPixbuf *gdk_pixbuf__ras_image_load(FILE * f) while (feof(f) == 0) { length = fread(membuf, 1, 4096, f); - (void)gdk_pixbuf__ras_image_load_increment(State, membuf, length); - } + if (!gdk_pixbuf__ras_image_load_increment(State, membuf, length, + error)) { + gdk_pixbuf__ras_image_stop_load (State); + return NULL; + } + } g_free(membuf); if (State->pixbuf != NULL) gdk_pixbuf_ref(State->pixbuf); @@ -213,7 +220,8 @@ gdk_pixbuf__ras_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { struct ras_progressive_state *context; @@ -385,7 +393,8 @@ static void OneLine(struct ras_progressive_state *context) * append image data onto inrecrementally built output image */ gboolean -gdk_pixbuf__ras_image_load_increment(gpointer data, guchar * buf, guint size) +gdk_pixbuf__ras_image_load_increment(gpointer data, guchar * buf, guint size, + GError **error) { struct ras_progressive_state *context = (struct ras_progressive_state *) data; diff --git a/gdk-pixbuf/io-tiff.c b/gdk-pixbuf/io-tiff.c index fdf5174632..6157147427 100644 --- a/gdk-pixbuf/io-tiff.c +++ b/gdk-pixbuf/io-tiff.c @@ -148,7 +148,8 @@ gdk_pixbuf__tiff_image_begin_load (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { TiffData *context; gint fd; diff --git a/gdk-pixbuf/io-wbmp.c b/gdk-pixbuf/io-wbmp.c index f8411ae269..bbca3e1a17 100644 --- a/gdk-pixbuf/io-wbmp.c +++ b/gdk-pixbuf/io-wbmp.c @@ -67,16 +67,18 @@ gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func, ModuleUpdatedNotifyFunc updated_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc - anim_done_func, gpointer user_data); + anim_done_func, gpointer user_data, + GError **error); void gdk_pixbuf__wbmp_image_stop_load(gpointer data); gboolean gdk_pixbuf__wbmp_image_load_increment(gpointer data, guchar * buf, - guint size); + guint size, + GError **error); /* Shared library entry point --> This should be removed when generic_image_load enters gdk-pixbuf-io. */ -GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f) +GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f, GError **error) { size_t length; char membuf[4096]; @@ -84,14 +86,19 @@ GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f) GdkPixbuf *pb; - State = gdk_pixbuf__wbmp_image_begin_load(NULL, NULL, NULL, NULL, NULL); + State = gdk_pixbuf__wbmp_image_begin_load(NULL, NULL, NULL, NULL, NULL, + error); + if (State == NULL) + return NULL; + while (feof(f) == 0) { length = fread(membuf, 1, 4096, f); if (length > 0) gdk_pixbuf__wbmp_image_load_increment(State, membuf, - length); + length, + error); } if (State->pixbuf != NULL) @@ -111,10 +118,11 @@ GdkPixbuf *gdk_pixbuf__wbmp_image_load(FILE * f) gpointer gdk_pixbuf__wbmp_image_begin_load(ModulePreparedNotifyFunc prepared_func, - ModuleUpdatedNotifyFunc updated_func, - ModuleFrameDoneNotifyFunc frame_done_func, - ModuleAnimationDoneNotifyFunc - anim_done_func, gpointer user_data) + ModuleUpdatedNotifyFunc updated_func, + ModuleFrameDoneNotifyFunc frame_done_func, + ModuleAnimationDoneNotifyFunc + anim_done_func, gpointer user_data, + GError **error) { struct wbmp_progressive_state *context; @@ -221,7 +229,7 @@ get_mbi(struct wbmp_progressive_state *context, guchar **buf, guint *buf_size, i * append image data onto inrecrementally built output image */ gboolean gdk_pixbuf__wbmp_image_load_increment(gpointer data, guchar * buf, - guint size) + guint size, GError **error) { struct wbmp_progressive_state *context = (struct wbmp_progressive_state *) data; diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c index 17e2a43f40..b762c87054 100644 --- a/gdk-pixbuf/io-xpm.c +++ b/gdk-pixbuf/io-xpm.c @@ -27,6 +27,7 @@ #include <stdlib.h> #include <string.h> #include <glib.h> +#include <unistd.h> #include "gdk-pixbuf-private.h" #include "gdk-pixbuf-io.h" @@ -1400,7 +1401,8 @@ gdk_pixbuf__xpm_image_begin_load (ModulePreparedNotifyFunc prepare_func, ModuleUpdatedNotifyFunc update_func, ModuleFrameDoneNotifyFunc frame_done_func, ModuleAnimationDoneNotifyFunc anim_done_func, - gpointer user_data) + gpointer user_data, + GError **error) { XPMContext *context; gint fd; diff --git a/gdk-pixbuf/make-inline-pixbuf.c b/gdk-pixbuf/make-inline-pixbuf.c index daf0a7e20b..445fbd88a9 100644 --- a/gdk-pixbuf/make-inline-pixbuf.c +++ b/gdk-pixbuf/make-inline-pixbuf.c @@ -187,15 +187,16 @@ main (int argc, char **argv) while (i < argc) { GdkPixbuf *pixbuf; + GError *error; g_assert ((i + 1) < argc); - - pixbuf = gdk_pixbuf_new_from_file (argv[i+1]); + + error = NULL; + pixbuf = gdk_pixbuf_new_from_file (argv[i+1], &error); if (pixbuf == NULL) { - fprintf (stderr, "Failed to open image file `%s': %s\n", - argv[i+1], strerror (errno)); + fprintf (stderr, "%s\n", error->message); exit (1); } diff --git a/gdk/gdkpixmap.c b/gdk/gdkpixmap.c index 6a2c82c5cf..2a318651fd 100644 --- a/gdk/gdkpixmap.c +++ b/gdk/gdkpixmap.c @@ -473,7 +473,7 @@ gdk_pixmap_colormap_create_from_xpm (GdkWindow *window, if (colormap == NULL) colormap = gdk_drawable_get_colormap (window); - pixbuf = gdk_pixbuf_new_from_file (filename); + pixbuf = gdk_pixbuf_new_from_file (filename, NULL); if (!pixbuf) return NULL; diff --git a/gtk/gdk-pixbuf-loader.c b/gtk/gdk-pixbuf-loader.c index 5f4320f22f..42aec5d4c7 100644 --- a/gtk/gdk-pixbuf-loader.c +++ b/gtk/gdk-pixbuf-loader.c @@ -338,20 +338,32 @@ gdk_pixbuf_loader_animation_done (GdkPixbuf *pixbuf, } static gint -gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) +gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, + const char *image_type, + GError **error) { GdkPixbufLoaderPrivate *priv = loader->private; - if(image_type) - priv->image_module = gdk_pixbuf_get_named_module (image_type); + if (image_type) + { + priv->image_module = gdk_pixbuf_get_named_module (image_type, + error); + } else - priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset); + { + g_return_val_if_fail (priv->header_buf_offset > 0, 0); + priv->image_module = gdk_pixbuf_get_module (priv->header_buf, + priv->header_buf_offset, + NULL, + error); + } if (priv->image_module == NULL) return 0; if (priv->image_module->module == NULL) - gdk_pixbuf_load_module (priv->image_module); + if (!gdk_pixbuf_load_module (priv->image_module, error)) + return 0; if (priv->image_module->module == NULL) return 0; @@ -360,8 +372,12 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) (priv->image_module->stop_load == NULL) || (priv->image_module->load_increment == NULL)) { - g_warning (G_STRLOC ": module %s does not support incremental loading.\n", - priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("Incremental loading of image type '%s' is not supported"), + image_type); + return 0; } @@ -369,16 +385,33 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) gdk_pixbuf_loader_update, gdk_pixbuf_loader_frame_done, gdk_pixbuf_loader_animation_done, - loader); + loader, + error); if (priv->context == NULL) { - g_warning (G_STRLOC ": Failed to begin progressive load"); + /* Defense against broken loaders; DO NOT take this as a GError + * example + */ + if (error && *error == NULL) + { + g_warning ("Bug! loader '%s' didn't set an error on failure", + priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error: Image loader module '%s'" + " failed to begin loading an image, but didn't" + " give a reason for the failure"), + priv->image_module->module_name); + + } + return 0; } if (priv->header_buf_offset - && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset)) + && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset, error)) return priv->header_buf_offset; return 0; @@ -387,7 +420,8 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, const char *image_type) static int gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count) + gsize count, + GError **error) { gint n_bytes; GdkPixbufLoaderPrivate *priv = loader->private; @@ -399,7 +433,7 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, if (priv->header_buf_offset >= LOADER_HEADER_SIZE) { - if (gdk_pixbuf_loader_load_module (loader, NULL) == 0) + if (gdk_pixbuf_loader_load_module (loader, NULL, error) == 0) return 0; } @@ -411,11 +445,14 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, * @loader: A pixbuf loader. * @buf: Pointer to image data. * @count: Length of the @buf buffer in bytes. + * @error: return location for errors * - * This will cause a pixbuf loader to parse the next @count bytes of an image. - * It will return TRUE if the data was loaded successfully, and FALSE if an - * error occurred. In the latter case, the loader will be closed, and will not - * accept further writes. + * This will cause a pixbuf loader to parse the next @count bytes of + * an image. It will return TRUE if the data was loaded successfully, + * and FALSE if an error occurred. In the latter case, the loader + * will be closed, and will not accept further writes. If FALSE is + * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR + * domain. * * Return value: #TRUE if the write was successful, or #FALSE if the loader * cannot parse the buffer. @@ -423,7 +460,8 @@ gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count) + gsize count, + GError **error) { GdkPixbufLoaderPrivate *priv; @@ -442,7 +480,7 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, { gint eaten; - eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count); + eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count, error); if (eaten <= 0) return FALSE; @@ -451,8 +489,27 @@ gdk_pixbuf_loader_write (GdkPixbufLoader *loader, } if (count > 0 && priv->image_module->load_increment) - return priv->image_module->load_increment (priv->context, buf, count); - + { + gboolean retval; + retval = priv->image_module->load_increment (priv->context, buf, count, + error); + if (!retval && error && *error == NULL) + { + /* Fix up busted image loader */ + g_warning ("Bug! loader '%s' didn't set an error on failure", + priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error: Image loader module '%s'" + " failed to begin loading an image, but didn't" + " give a reason for the failure"), + priv->image_module->module_name); + } + + return retval; + } + return TRUE; } @@ -477,13 +534,22 @@ gdk_pixbuf_loader_new (void) * Return value: A newly-created pixbuf loader. **/ GdkPixbufLoader * -gdk_pixbuf_loader_new_with_type (const char *image_type) +gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error) { GdkPixbufLoader *retval; - + GError *tmp; + retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); - gdk_pixbuf_loader_load_module(retval, image_type); + tmp = NULL; + gdk_pixbuf_loader_load_module(retval, image_type, &tmp); + if (tmp != NULL) + { + g_propagate_error (error, tmp); + g_object_unref (G_OBJECT (retval)); + return NULL; + } return retval; } @@ -579,7 +645,7 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader) /* We have less the 128 bytes in the image. Flush it, and keep going. */ if (priv->image_module == NULL) - gdk_pixbuf_loader_load_module (loader, NULL); + gdk_pixbuf_loader_load_module (loader, NULL, NULL); if (priv->image_module && priv->image_module->stop_load) priv->image_module->stop_load (priv->context); diff --git a/gtk/gdk-pixbuf-loader.h b/gtk/gdk-pixbuf-loader.h index c3d6d6f95b..402b697256 100644 --- a/gtk/gdk-pixbuf-loader.h +++ b/gtk/gdk-pixbuf-loader.h @@ -72,10 +72,12 @@ struct _GdkPixbufLoaderClass GtkType gdk_pixbuf_loader_get_type (void) G_GNUC_CONST; GdkPixbufLoader * gdk_pixbuf_loader_new (void); -GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type); +GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error); gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, const guchar *buf, - gsize count); + gsize count, + GError **error); GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader); GdkPixbufAnimation * gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader); void gdk_pixbuf_loader_close (GdkPixbufLoader *loader); diff --git a/gtk/gtkiconfactory.c b/gtk/gtkiconfactory.c index 249568ce50..f6541a3d3e 100644 --- a/gtk/gtkiconfactory.c +++ b/gtk/gtkiconfactory.c @@ -27,6 +27,7 @@ #include "gtkiconfactory.h" #include "stock-icons/gtkstockpixbufs.h" #include "gtkstock.h" +#include "gtkintl.h" #include <stdlib.h> #include <errno.h> #include <ctype.h> @@ -214,7 +215,7 @@ sized_icon_set_from_inline (const guchar *inline_data, set = gtk_icon_set_new (); - source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1); + source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1, NULL); g_assert (source.pixbuf); @@ -236,7 +237,7 @@ unsized_icon_set_from_inline (const guchar *inline_data) set = gtk_icon_set_new (); - source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1); + source.pixbuf = gdk_pixbuf_new_from_inline (inline_data, FALSE, -1, NULL); g_assert (source.pixbuf); @@ -651,6 +652,7 @@ find_and_prep_icon_source (GtkIconSet *icon_set, if (source->pixbuf == NULL) { + GError *error; gchar *full; g_assert (source->filename); @@ -659,8 +661,9 @@ find_and_prep_icon_source (GtkIconSet *icon_set, full = gtk_rc_find_pixmap_in_path (NULL, source->filename); else full = g_strdup (source->filename); - - source->pixbuf = gdk_pixbuf_new_from_file (full); + + error = NULL; + source->pixbuf = gdk_pixbuf_new_from_file (full, &error); g_free (full); @@ -669,7 +672,8 @@ find_and_prep_icon_source (GtkIconSet *icon_set, /* Remove this icon source so we don't keep trying to * load it. */ - g_warning ("Failed to load icon '%s'", source->filename); + g_warning (_("Error loading icon: %s"), error->message); + g_error_free (error); icon_set->sources = g_slist_remove (icon_set->sources, source); diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c index 504b2a2e11..a4de696dd0 100644 --- a/gtk/gtkimage.c +++ b/gtk/gtkimage.c @@ -255,7 +255,7 @@ gtk_image_set_from_file (GtkImage *image, if (filename == NULL) return; - pixbuf = gdk_pixbuf_new_from_file (filename); + pixbuf = gdk_pixbuf_new_from_file (filename, NULL); if (pixbuf == NULL) return; diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 627341f431..143f822f32 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -1508,16 +1508,19 @@ gtk_text_buffer_emit_tag(GtkTextBuffer *buffer, const GtkTextIter *start, const GtkTextIter *end) { + GtkTextIter start_tmp = *start; + GtkTextIter end_tmp = *end; + g_return_if_fail(tag != NULL); - - gtk_text_iter_reorder (start, end); + + gtk_text_iter_reorder (&start_tmp, &end_tmp); if (apply) gtk_signal_emit (GTK_OBJECT(buffer), signals[APPLY_TAG], - tag, start, end); + tag, &start_tmp, &end_tmp); else gtk_signal_emit (GTK_OBJECT(buffer), signals[REMOVE_TAG], - tag, start, end); + tag, &start_tmp, &end_tmp); } diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index e061e1978e..70ac5f19e8 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -62,9 +62,6 @@ struct _GtkTextRealIter and ditto for char offsets. */ gint segment_byte_offset; gint segment_char_offset; - /* Pads are here for binary-compatible expansion space. */ - gpointer pad1; - guint pad2; }; /* These "set" functions should not assume any fields @@ -158,7 +155,10 @@ gtk_text_iter_make_surreal(const GtkTextIter *_iter) "was created.\nYou must use marks, character numbers, " "or line numbers to preserve a position across buffer " "modifications.\nYou can apply tags and insert marks " - "without invalidating your iterators, however."); + "without invalidating your iterators,\n" + "but any mutation that affects 'indexable' buffer contents " + "(contents that can be referred to by character offset)\n" + "will invalidate all outstanding iterators"); return NULL; } @@ -2048,6 +2048,55 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count) } } +#if 0 + +/* These two can't be implemented efficiently (always have to use + * a linear scan, since that's the only way to find all the non-text + * segments) + */ + +/** + * gtk_text_iter_forward_text_chars: + * @iter: a #GtkTextIter + * @count: number of chars to move + * + * Moves forward by @count text characters (pixbufs, widgets, + * etc. do not count as characters for this). Equivalent to moving + * through the results of gtk_text_iter_get_text(), rather than + * gtk_text_iter_get_slice(). + * + * Return value: whether @iter moved and is dereferenceable + **/ +gboolean +gtk_text_iter_forward_text_chars (GtkTextIter *iter, + gint count) +{ + + + +} + +/** + * gtk_text_iter_forward_text_chars: + * @iter: a #GtkTextIter + * @count: number of chars to move + * + * Moves backward by @count text characters (pixbufs, widgets, + * etc. do not count as characters for this). Equivalent to moving + * through the results of gtk_text_iter_get_text(), rather than + * gtk_text_iter_get_slice(). + * + * Return value: whether @iter moved and is dereferenceable + **/ +gboolean +gtk_text_iter_backward_text_chars (GtkTextIter *iter, + gint count) +{ + + +} +#endif + /** * gtk_text_iter_forward_line: * @iter: an iterator @@ -2527,7 +2576,11 @@ gtk_text_iter_forward_to_newline(GtkTextIter *iter) /* Move to end of next line. */ if (gtk_text_iter_forward_line(iter)) { - gtk_text_iter_forward_to_newline(iter); + /* We don't want to move past all + * empty lines. + */ + if (gtk_text_iter_get_char (iter) != '\n') + gtk_text_iter_forward_to_newline(iter); return TRUE; } else @@ -2760,12 +2813,46 @@ gtk_text_iter_backward_find_char (GtkTextIter *iter, return FALSE; } +static void +forward_chars_with_skipping (GtkTextIter *iter, + gint count, + gboolean skip_invisible, + gboolean skip_nontext) +{ + + gint i; + + g_return_if_fail (count >= 0); + + i = count; + + while (i > 0) + { + gboolean ignored = FALSE; + + if (skip_nontext && + gtk_text_iter_get_char (iter) == gtk_text_unknown_char) + ignored = TRUE; + + if (!ignored && + skip_invisible && + gtk_text_btree_char_is_invisible (iter)) + ignored = TRUE; + + gtk_text_iter_next_char (iter); + + if (!ignored) + --i; + } +} + static gboolean lines_match (const GtkTextIter *start, const gchar **lines, gboolean visible_only, gboolean slice, - GtkTextIter *match_start) + GtkTextIter *match_start, + GtkTextIter *match_end) { GtkTextIter next; gchar *line_text; @@ -2773,13 +2860,14 @@ lines_match (const GtkTextIter *start, gint offset; if (*lines == NULL || **lines == '\0') - return TRUE; + { + if (match_end) + *match_end = *start; + return TRUE; + } next = *start; gtk_text_iter_forward_line (&next); - - gtk_text_iter_spew (start, "start"); - gtk_text_iter_spew (&next, "next"); /* No more text in buffer, but *lines is nonempty */ if (gtk_text_iter_equal (start, &next)) @@ -2795,9 +2883,7 @@ lines_match (const GtkTextIter *start, line_text = gtk_text_iter_get_slice (start, &next); } else - { - /* FIXME */ - g_warning ("Searching for non-slice text is currently broken (you must include 'unknown char' for pixmaps in order to match them)"); + { if (visible_only) line_text = gtk_text_iter_get_visible_text (start, &next); else @@ -2834,22 +2920,28 @@ lines_match (const GtkTextIter *start, if (match_start) { *match_start = next; - gtk_text_iter_forward_chars (match_start, offset); + + forward_chars_with_skipping (match_start, offset, + visible_only, !slice); } /* Go to end of search string */ offset += g_utf8_strlen (*lines, -1); - gtk_text_iter_forward_chars (&next, offset); + forward_chars_with_skipping (&next, offset, + visible_only, !slice); g_free (line_text); ++lines; + if (match_end) + *match_end = next; + /* pass NULL for match_start, since we don't need to find the * start again. */ - return lines_match (&next, lines, visible_only, slice, NULL); + return lines_match (&next, lines, visible_only, slice, NULL, match_end); } /* strsplit() that retains the delimiter as part of the string. */ @@ -2909,10 +3001,12 @@ strbreakup (const char *string, } gboolean -gtk_text_iter_forward_search (GtkTextIter *iter, - const char *str, - gboolean visible_only, - gboolean slice) +gtk_text_iter_forward_search (const GtkTextIter *iter, + const gchar *str, + gboolean visible_only, + gboolean slice, + GtkTextIter *match_start, + GtkTextIter *match_end) { gchar **lines = NULL; GtkTextIter match; @@ -2937,12 +3031,18 @@ gtk_text_iter_forward_search (GtkTextIter *iter, * gtk_text_iter_get_text() is called repeatedly on * a single line. */ + GtkTextIter end; + if (lines_match (&search, (const gchar**)lines, - visible_only, slice, &match)) + visible_only, slice, &match, &end)) { retval = TRUE; - *iter = match; + if (match_start) + *match_start = match; + + if (match_end) + *match_end = end; break; } @@ -2963,8 +3063,8 @@ gtk_text_iter_backward_search (GtkTextIter *iter, g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (str != NULL, FALSE); - - + + } /* @@ -3057,9 +3157,9 @@ gtk_text_iter_compare(const GtkTextIter *lhs, const GtkTextIter *rhs) } gboolean -gtk_text_iter_in_region (const GtkTextIter *iter, - const GtkTextIter *start, - const GtkTextIter *end) +gtk_text_iter_in_range (const GtkTextIter *iter, + const GtkTextIter *start, + const GtkTextIter *end) { return gtk_text_iter_compare(iter, start) >= 0 && gtk_text_iter_compare(iter, end) < 0; @@ -3313,6 +3413,8 @@ gtk_text_iter_check (const GtkTextIter *iter) /* We are going to check our class invariants for the Iter class. */ + g_assert (sizeof (GtkTextIter) == sizeof (GtkTextRealIter)); + if (real->chars_changed_stamp != gtk_text_btree_get_chars_changed_stamp(real->tree)) g_error("iterator check failed: invalid iterator"); diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h index 45dde30b29..8e6eeaecdd 100644 --- a/gtk/gtktextiter.h +++ b/gtk/gtktextiter.h @@ -46,15 +46,14 @@ struct _GtkTextIter { gpointer dummy2; gint dummy3; gint dummy4; - gint dummy10; - gint dummy11; gint dummy5; gint dummy6; - gpointer dummy7; - gpointer dummy8; - gint dummy9; - gpointer pad1; - guint pad2; + gint dummy7; + gint dummy8; + gpointer dummy9; + gpointer dummy10; + gint dummy11; + gint dummy12; }; @@ -164,6 +163,7 @@ void gtk_text_iter_set_line_offset (GtkTextIter *iter, void gtk_text_iter_forward_to_end (GtkTextIter *iter); gboolean gtk_text_iter_forward_to_newline (GtkTextIter *iter); + /* returns TRUE if a toggle was found; NULL for the tag pointer means "any tag toggle", otherwise the next toggle of the specified tag is located. */ @@ -183,10 +183,12 @@ gboolean gtk_text_iter_backward_find_char (GtkTextIter *iter, GtkTextCharPredicate pred, gpointer user_data); -gboolean gtk_text_iter_forward_search (GtkTextIter *iter, - const char *str, - gboolean visible_only, - gboolean slice); +gboolean gtk_text_iter_forward_search (const GtkTextIter *iter, + const gchar *str, + gboolean visible_only, + gboolean slice, + GtkTextIter *match_start, + GtkTextIter *match_end); gboolean gtk_text_iter_backward_search (GtkTextIter *iter, const char *str, @@ -200,7 +202,7 @@ gboolean gtk_text_iter_equal (const GtkTextIter *lhs, const GtkTextIter *rhs); gint gtk_text_iter_compare (const GtkTextIter *lhs, const GtkTextIter *rhs); -gboolean gtk_text_iter_in_region (const GtkTextIter *iter, +gboolean gtk_text_iter_in_range (const GtkTextIter *iter, const GtkTextIter *start, const GtkTextIter *end); diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 6e5b661084..9bec94ce6e 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -38,7 +38,7 @@ #include "gtktexttypes.h" #include <string.h> -#define FOCUS_EDGE_WIDTH 25 +#define FOCUS_EDGE_WIDTH 1 #define DRAG_THRESHOLD 8 #define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window) @@ -1906,7 +1906,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event) if (gtk_text_buffer_get_selection_bounds (text_view->buffer, &start, &end) && - gtk_text_iter_in_region (&iter, &start, &end)) + gtk_text_iter_in_range (&iter, &start, &end)) { text_view->drag_start_x = event->x; text_view->drag_start_y = event->y; @@ -3202,7 +3202,7 @@ gtk_text_view_drag_motion (GtkWidget *widget, if (gtk_text_buffer_get_selection_bounds (text_view->buffer, &start, &end) && - gtk_text_iter_in_region (&newplace, &start, &end)) + gtk_text_iter_in_range (&newplace, &start, &end)) { /* We're inside the selection. */ gdk_drag_status (context, 0, time); diff --git a/gtk/testtext.c b/gtk/testtext.c index 16e7172b76..a362fd9be1 100644 --- a/gtk/testtext.c +++ b/gtk/testtext.c @@ -1299,8 +1299,6 @@ buffer_search_forward (Buffer *buffer, const char *str, { GtkTextIter iter; GtkTextIter start, end; - gint char_len; - int i = 0; GtkWidget *dialog; /* remove tag from whole buffer */ @@ -1313,22 +1311,17 @@ buffer_search_forward (Buffer *buffer, const char *str, "insert")); - char_len = g_utf8_strlen (str, -1); - - if (char_len > 0) + if (*str != '\0') { - while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE)) + GtkTextIter match_start, match_end; + + while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE, + &match_start, &match_end)) { - GtkTextIter end = iter; - - gtk_text_iter_forward_chars (&end, char_len); - gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag, - &iter, &end); + &match_start, &match_end); - iter = end; - - ++i; + iter = match_end; } } diff --git a/tests/testtext.c b/tests/testtext.c index 16e7172b76..a362fd9be1 100644 --- a/tests/testtext.c +++ b/tests/testtext.c @@ -1299,8 +1299,6 @@ buffer_search_forward (Buffer *buffer, const char *str, { GtkTextIter iter; GtkTextIter start, end; - gint char_len; - int i = 0; GtkWidget *dialog; /* remove tag from whole buffer */ @@ -1313,22 +1311,17 @@ buffer_search_forward (Buffer *buffer, const char *str, "insert")); - char_len = g_utf8_strlen (str, -1); - - if (char_len > 0) + if (*str != '\0') { - while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE)) + GtkTextIter match_start, match_end; + + while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE, + &match_start, &match_end)) { - GtkTextIter end = iter; - - gtk_text_iter_forward_chars (&end, char_len); - gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag, - &iter, &end); + &match_start, &match_end); - iter = end; - - ++i; + iter = match_end; } } |