Re: Exposing, panning, and obscured window



dov imagic weizmann ac il writes:

> Hello,
> 
> I'm working on an image display widget that has interaction and speed
> similar to that of gimp's excellent image display. I hope that this
> widget may be the bases of several image display programs, e.g. the
> fax viewing program, and some scientific visualization programs that
> I need at work.
> 
> My problem has to do with panning and exposing. They way the widget
> works is as follows:
> 
> The illustration below shows a panning of the widget in the y-direction.
> 
>      0  +------------------------------------+
>         |				     |  
>      dy	|====================================|
> 	|				     |
> 	|				     |
> 	|				     |
> 	|				     |
>      h	+------------------------------------+
>       
>       
> The widget has just received a motion event of dy in the y-direction
> with the middle mouse button pressed. The image needs to be panned
> which is done in two steps:
> 
>     1. A gdk_draw_pixmap() call with the source and the destination
>        pixmaps being the window. The y-coordinates for source and
>        destination are:
>        
>           source:   0, h-dy
> 	  dest:     dy, h
> 	  
>     2. Rendering the rectangle between 0 and h and then writing it to
>        to the window through gdk_pixbuf_render_to_drawable() .
>        
> This all works fine. The problem happens when part of the window is 
> obscured:
> 
> 				      |
>      0  +-----------------------------|   Obscuring 
>         |			      |   window
>      dy	|=============================|
> 	|			      +-------------
> 	|				     |
> 	|				     |
> 	|				     |
>      h	+------------------------------------+
> 
>      
> The problem now is that the gdk_draw_pixmap step will partly take
> information that is behind the obscuring window. The result is 
> that below the obscuring window will be a grey stripe that is dy
> high.
> 
> Is there any way of getting a list of all the rectangles that are
> obscuring the image widget? Or is there any other way of how to
> avoid this problem? Of course it would be possible to render the
> whole image periodically, but it seems that this is a waste of
> resources. Is there any other way?
> 
> Note that you don't get an exposure event in this case as all
> changes take place within the image widget.

The standard way for GTK+-1.2 is to turn on the graphics expose
flag on the GC you are using for gdk_draw_pixbuf. Then graphics
expose events will be generated for the obscured areas. GDK
converts the graphics expose events to normal expose events,
so you don't need to worry about them.

But there is a problem with race conditons - if you scroll again
before you get the graphics expose things will be messed up.

You can mostly (but not completely) eliminate the race conditions by,
after you scroll, calling gdk_event_get_graphics_expose() until it
returns NULL and dispatching the resulting queue.

This is what text widget does, and you can look at that as an example.

The real right thing to do to get around the race conditions is to
keep a queue of translations with the X serial numbers and use that to
translate incoming graphics expose events, but that has to really be
done at the GDK level, not at the app level.

in GTK+-1.3 I tried to hide this all from the programmer. The really
easy way to do the scrolling is to just create a big window to hold
your image and move that around behind the viewport window.  GTK+-1.3
will automatically do the necessary tricks if your window is bigger
than the maximum size of an X window.

In GTK+-1.3 you can also use gdk_window_scroll() to scroll a window,
properly turning on graphics exposes, translating coordinates, etc.

Regards,
                                        Owen




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