Re: Paint a image in Cairo surface X11
Uli Schlachter <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
Hi, Am 05.02.2016 um 15:13 schrieb Alex Vazquez: > I have a problem when I paint a image using Cairo and X11. > The test is simple I try paint a image in a X11 Windows using Cairo. > If the size of surface is less that size of image, X11 don't show the > image but If the size of surface is bigger that the size of image X11 > show fine the image. > > Why is happen? In X11, you have to handle redraws (Expose events). For example, with your version, remove the code that handles a ButtonPress and switch to another window, move it above of your window and then switch back to your window. The content of the window will be lost. > How can i fix this problem? Redraw when the server tells you to. > I add a test where you can test this problem. Thanks, attached is a fixed version (well, I am lazy; an Expose event contains information about which part of the window needs to be redrawn; the code just redraws everything). Cheers, Uli P.S.: No idea why this has something to do with the size of the image for you. If you want me to guess it is because with a larger it takes a tiny bit longer to upload the image and thus the race against the window manager more often ends with "paint only after the window is shown". P.P.S.: The program still exits by segfaulting, just as your version... -- - Captain, I think I should tell you I've never actually landed a starship before. - That's all right, Lieutenant, neither have I. -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo
cairo_xlib_simple.c
(text/x-csrc, 2.5 KB)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static void cairo_close_x11_surface();
static Display *dsp;
static cairo_surface_t *sfc;
static cairo_surface_t *image;
static void do_redraw(void)
{
cairo_t *ctx;
ctx = cairo_create(sfc);
cairo_set_source_surface (ctx, image, 0, 0);
cairo_paint (ctx);
printf("Size: %dx%d\n",
cairo_image_surface_get_width (image),
cairo_image_surface_get_height (image));
cairo_destroy(ctx);
XFlush(dsp);
}
static void cairo_check_event(cairo_surface_t *sfc, int block)
{
XEvent e;
for (;;)
{
///if (block || XPending(cairo_xlib_surface_get_display(sfc)))
XNextEvent(cairo_xlib_surface_get_display(sfc), &e);
//else
// return 0;
switch (e.type)
{
case ConfigureNotify:
cairo_xlib_surface_set_size(sfc, e.xconfigure.width, e.xconfigure.height);
break;
case Expose:
if (e.xexpose.count == 0)
do_redraw();
break;
case ButtonPress:
cairo_close_x11_surface();
break;
default:
break;
}
}
}
/*! Open an X11 window and create a cairo surface base on that window.
* @param x Width of window.
* @param y Height of window.
* @return Returns a pointer to a valid Xlib cairo surface. The function does
* not return on error (exit(3)).
*/
cairo_surface_t *cairo_create_x11_surface0(int x, int y)
{
//Display *dsp;
Drawable da;
int screen;
if ((dsp = XOpenDisplay(NULL)) == NULL)
exit(1);
screen = DefaultScreen(dsp);
da = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, x, y, 0, 0, 0);
XSelectInput(dsp, da, ButtonPressMask | ButtonReleaseMask | ExposureMask | StructureNotifyMask);
XMapWindow(dsp, da);
XFlush(dsp);
XSync(dsp, screen);
sfc = cairo_xlib_surface_create(dsp, da, DefaultVisual(dsp, screen), x, y);
return sfc;
}
/*! Destroy cairo Xlib surface and close X connection.
*/
void cairo_close_x11_surface()
{
Display *dsp = cairo_xlib_surface_get_display(sfc);
cairo_surface_destroy(sfc);
XCloseDisplay(dsp);
}
int main(int argc, char **argv)
{
int iwidth,iheight;
if (argc < 3)
{
printf("./cairo_xlib_simple [Width] [Height]\n");
return 1;
}
iwidth = atoi(argv[1]);
iheight = atoi(argv[2]);
image = cairo_image_surface_create_from_png ("photo.png");
sfc = cairo_create_x11_surface0(iwidth, iheight);
cairo_check_event(sfc, 1);
cairo_close_x11_surface(sfc);
return 0;
}