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;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.