Re: Problem with gdk_image_get() failing

On 5 Jan 2001, Owen Taylor wrote:

> Tim Janik <timj gtk org> writes:
> > On Tue, 19 Dec 2000, Ramiro Estrugo wrote:
> > 
> > > I talked to Owen about it on irc about and he accepted the patch.  I
> > > committed it to the 1.2 branch.
> > > 
> > > To track this problem for 2.0, I filed a bug:
> > > 
> > >
> > 
> > basically both functions, gdk_image_get() and pixbuf_from_drawable() are
> > pretty broken and have to be redone before release.
> > i ran into similar problems with deskguide which does contain fairly
> > stable code to shoot images at this point, though it doesn't yet come
> > with the speed-optimized versions of rgbconvert().
> > 
> > help here is apprechiated if someone has the guts to backport the
> > deskguide screenshooting code into gdk/gdk-pixbuf.
> OK, I'll take this one on.

ok, that'd be cool.

> It would be useful if you could quickly list the things you remembered
> fixing.

good, lemme start from the prototypes in gwmthumbnail.c:

first, we need a function as flexible as:

void            gdk_pixbuf_copy_from_image       (GdkPixbuf   *pixbuf,
                                                  guint        dest_x,
                                                  guint        dest_y,
                                                  GdkImage    *image,
                                                  guint        src_x,
                                                  guint        src_y,
                                                  guint        width,
                                                  guint        height,
                                                  GdkColormap *cmap);

to cover up any needs that may possibly occour, i.e. be able to copy
any region specified as source through (x,y,w,h) into an existing
pixbuf at a given position.

GdkPixbuf*      gdk_pixbuf_from_image            (GdkImage    *image,
                                                  guint        x,
                                                  guint        y,
                                                  guint        width,
                                                  guint        height,
                                                  GdkColormap *cmap);
just a conveninece variant.

GdkImage*       gdk_image_get                    (GdkWindow *window,
                                                  gint       x,
                                                  gint       y,
                                                  gint       width,
                                                  gint       height);
GdkColormap*    gdk_window_get_colormap          (GdkWindow *window);
GdkVisual*      gdk_window_get_visual            (GdkWindow *window);

these i had to reimplement for the thumbnailing code to behave sanely
when windows/colormaps etc. prematurely die, i.e. these functions will
now return NULL instead of puking/halting if window or substructures
thereof aren't valid on the server.
basically, we have two choices here, either use the thumbnailing variants
that guard every X call with gdk traps, or use a server grab across
the thumbnailing code. i decided against a server grab because
1) i didn't want to block other clients more than is really neccessary
2) these functions should probably behave sanely in other circumstances
   (non-thumbnailing applications) as well

gdk_image_get() uses a small hack with the variable image_put_normal
to get a hand on a prototype declared statically within gdk only.

GdkImage*       gdk_image_new_shared_with_pixmap (GdkWindow  *window,
                                                  gint        width,
                                                  gint        height,
                                                  GdkPixmap **pixmap_p);

this functions isn't present as such in the gdk API, we need a fucntion
that basically gives us XShmCreatePixmap() semantics for optimized
also it works around gdk_use_xshm which has basically broken logic
in gdk.
for permanent thumbnailing and under certain loads, XShmCreateImage() might
fail for quite a couple of times, but later on become usable again, so:
                  /* EINVAL indicates, most likely, that the segment we asked for
                   * is bigger than SHMMAX, so we don't treat it as a permanently
                   * fatal error. ENOSPC and ENOMEM may also indicate this, but
                   * more likely are permanent errors.
                  if (errno != EINVAL)
                      g_warning ("shmget failed!");
                      gdk_use_xshm = False;
is far too restrictive, in fact permanent errors are quite unlikely from
my experience and for deskguide, having a temporary error disable shm
imaging for the rest of the runtime was simply not accebtable.

iirc, there were also some issues with the pixbuf's rgb conversion code,
which is why
static void
_pixbuf_rgbconvert (GdkImage    *image,
                    guint8      *pixels,
                    gint         rowstride,
                    gboolean     has_alpha,
                    gint         x,
                    gint         y,
                    gint         width,
                    gint         height,
                    GdkColormap *cmap)
static void
_pixbuf_convert_real_slow (GdkImage    *image,
                           guint8      *pixels,
                           gint         rowstride,
                           gboolean     has_alpha,
                           gint         x_off,
                           gint         y_off,
                           gint         width,
                           gint         height,
                           GdkColormap *cmap)
looks somewhat different from the gdk-pixbuf variant.
the hardest part here is probably to code up the optimized variants
that are present in gdk-pixbuf but are lacking from the thumbnailing code.

i think that's it, the fixedup/new gdk functions are seperated appropriately
in gwmthumbnail.c and should be straight forward from the existing gdk code
and the above mentioned considerations.

>                                         Owen


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]