[cairo] XCopyArea and Cairo - trying to implement scrolling

Richard Billington billingt at AI.SRI.COM
Fri May 15 19:39:56 PDT 2015

So I've had an interesting time. I've parsed your message as essentially 
saying either

  * re-implement xcopyarea using cairo constructs
  * OR, continue to use xcopyarea and handle the resulting
    graphics-expose event with a cairo-based function

I've tried re-implementing xcopyarea, and it resulted in a bad-match X 
error based on something that gets put on the event queue - hard to tell 
what because as soon as the error occurs it locks keboard input to X up :-(

I've also noticed that the when scrolling I get "no-exposure" events, so 
that means even if I implemented a cairo-based handler for 
graphics-expose event, it wouldn't be called when scrolling.

So I explored the "function"s being used. That is, before calling 
xcopyarea, the function "property" of the xlib graphics context is set 
to a value from 0 to 15. The function I'd used successfully with the 
purely xlib implementation was "GXandReverse" (defined as logically "src 
AND NOT dst"). With a window rendered using Cairo, this resulted in odd 
scrolling, the worst of which was that the background went from white to 
black, but it had additional problems. I surmise this is because the 
colors have an alpha channel and so the logical combination has a 
different result, but I really haven't thought it through. Instead, I 
experimented and found that using "GXxor" (defined logically as "src XOR 
dst") worked much better, thought it seems to smear text one pixel to 
the right, though graphics scroll fine.

Any comments or observations greatly appreciated. Still hacking away at 

On 05/15/2015 01:47 AM, Chris Wilson wrote:
> On Thu, May 14, 2015 at 08:34:00PM -0700, Richard Billington wrote:
>> I'm trying to translate a backend from using Xlib calls to using
>> Cairo, where reasonable. The drawing operations I'm doing (text and
>> graphics) are ignoring the xlib gcontext, and instead using the
>> cairo context. However, when I try to use my cairo implementation of
>> an xcopyarea-like function, I get some kind of event generated which
>> I don't know how to handle. If I try to use xcopyarea (the xlib
>> implementation), it "works" except that the background is always
>> black, not the background it ought to be.
>> I can go into more specifics, but I'm just wondering if there's any
>> standard way of doing this. I found an archived discussion from many
>> years ago about this subject, but I can't tell if there were
>> patches/reimplementations done to better accommodate this nor if
>> there's a standard approach.
> Sure, the crux of the issue is that the self-copy case remains undefined
> (it more or less boils down to not all hardware truly supports it). The
> easiest no-nonsense definition would be that the source is treated as
> static from the instance of being bound to the context (that is if it
> maps to the cairo_get_target, then we immediately take a copy[-on-write?]).
> That is overkill and prevents some optimisations for e.g. converting a
> 	cairo_set_source_surface(cairo_get_target(), 10, 10);
> 	cairo_rectangle();
> 	cairo_fill();
> into a XCopyArea, so finding the right balance is hard (but I think that
> is the right definition for the API!).
> On the other hand, with the hypothetical cairo-surface API you would be
> able to do the transformation into XCopyArea easily (since the definition
> there would be an implicit copy-on-write for the source being passed
> into the operation, and not at the context).
> However, that all has to be compared to
> expose-event (or preferrably repaint function after accumulating
> exposures):
> 	/* use double buffering */
> 	cairo_create(xlib_surface);
> 	cairo_rectangle(redraw_x, redraw_y, redraw_w, redraw_h);
> 	cairo_clip();
> 	cairo_push_group_with_context(CAIRO_CONTENT_COLOR);
> 	.... bunch of rendering ...
> 	cairo_pop_group_to_source();
> 	cairo_paint();
> 	cairo_destroy();
> 	cairo_surface_flush(xlib_surface);
> and now in your scroll function you are free to use XCopyArea on the
> underlying drawable. For completeness after using XCopyArea, call
> cairo_surface_mark_dirty().
> -Chris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20150515/6913aca8/attachment.html>

More information about the cairo mailing list