[cairo] xcb surface example?
Uli Schlachter
psychon at znc.in
Sat Jul 4 06:51:25 PDT 2015
Am 29.06.2015 um 21:53 schrieb Bryce Harrington:
> On Fri, Jun 26, 2015 at 08:09:36PM +0200, Uli Schlachter wrote:
>> Am 26.06.2015 um 13:31 schrieb Andreas Lobinger:
>>> Hello colleagues,
>>
>> Hi,
>>
>>> is there a good, known example of the cairo XcbSurface available? On the
>>> http://cairographics.org/examples/ page there is a link to
>>> git clone git://git.thisnukes4u.net/cairo-xcb-demo.git
>>> which seems to be outdated.
>>
>> What exactly do you need? There is mostly just a single useful function in
>> cairo-xcb. :-)
>>
>> Anyway, attached is a quick example that I hacked together. Hopefully it can
>> help you.
>
> I've added this as a new link at the end of our cookbook:
>
> http://cairographics.org/cookbook/
>
> ...and removed the linkrot from our examples page.
>
> Uli, would you mind specifying what license should be listed for your
> code? (Fwiw, the blur.c code appears to be using an MIT-ish license.)
Feel free to consider this WTFPL 2.0 (or any other license you like). I
seriously doubt this would even be covered by copyright at all. I still don't
think this is really a good example.
Hm... The find_visual() function originally comes from awesome
(awesome.naquadah.org), so I guess this makes this code GPLv2. Still, I don't
think this function is covered by copyright either.
[...]
>> #include <xcb/xcb.h>
>> #include <cairo-xcb.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> static xcb_visualtype_t *find_visual(xcb_connection_t *c, xcb_visualid_t visual)
>> {
>> xcb_screen_iterator_t screen_iter = xcb_setup_roots_iterator(xcb_get_setup(c));
>>
>> for (; screen_iter.rem; xcb_screen_next(&screen_iter)) {
>> xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen_iter.data);
>> for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
>> xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
>> for (; visual_iter.rem; xcb_visualtype_next(&visual_iter))
>> if (visual == visual_iter.data->visual_id)
>> return visual_iter.data;
>> }
>> }
>>
>> return NULL;
>> }
>>
>> int main()
>> {
>> xcb_connection_t *c;
>> xcb_screen_t *screen;
>> xcb_window_t window;
>> uint32_t mask[2];
>> xcb_visualtype_t *visual;
>> xcb_generic_event_t *event;
>> cairo_surface_t *surface;
>> cairo_t *cr;
>>
>> c = xcb_connect(NULL, NULL);
>> if (xcb_connection_has_error(c)) {
>> fprintf(stderr, "Could not connect to X11 server");
>> return 1;
>> }
>>
>> mask[0] = 1;
>> mask[1] = XCB_EVENT_MASK_EXPOSURE;
>> screen = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
>> window = xcb_generate_id(c);
>> xcb_create_window(c, XCB_COPY_FROM_PARENT, window, screen->root,
>> 20, 20, 150, 150, 0,
>> XCB_WINDOW_CLASS_INPUT_OUTPUT,
>> screen->root_visual,
>> XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
>> mask);
>> xcb_map_window(c, window);
>>
>> visual = find_visual(c, screen->root_visual);
>> if (visual == NULL) {
>> fprintf(stderr, "Some weird internal error...?!");
>> xcb_disconnect(c);
>> return 1;
>> }
>> surface = cairo_xcb_surface_create(c, window, visual, 150, 150);
>> cr = cairo_create(surface);
>>
>> xcb_flush(c);
>> while ((event = xcb_wait_for_event(c))) {
>> switch (event->response_type & ~0x80) {
>> case XCB_EXPOSE:
>> /* Should check if this is the last expose event in the
>> * sequence, but I'm too lazy right now...
>> */
The above could be implemented by adding
if (((xcb_expose_event_t *) event)->count != 0)
break;
(If the field is non-null, at least that many more expose events follow
containing other rectangles that need to be redrawn. By checking for zero, this
does less redraws.)
>> cairo_set_source_rgb(cr, 0, 1, 0);
>> cairo_paint(cr);
>>
>> cairo_set_source_rgb(cr, 1, 0, 0);
>> cairo_move_to(cr, 0, 0);
>> cairo_line_to(cr, 150, 0);
>> cairo_line_to(cr, 150, 150);
>> cairo_close_path(cr);
>> cairo_fill(cr);
>>
>> cairo_set_source_rgb(cr, 0, 0, 1);
>> cairo_set_line_width(cr, 20);
>> cairo_move_to(cr, 0, 150);
>> cairo_line_to(cr, 150, 0);
>> cairo_stroke(cr);
>>
>> cairo_surface_flush(surface);
>> break;
>> }
>> free(event);
>> xcb_flush(c);
>> }
>> cairo_surface_finish(surface);
This is missing a call to
cairo_surface_destroy(surface);
>> xcb_disconnect(c);
>> return 0;
>> }
Cheers,
Uli
--
Who needs a ~/.signature anyway?
More information about the cairo
mailing list