x11制作显示窗口图片

代码是用libpng和x11在窗口中显示一张图片,希望对你们有所帮助。

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>    
#include <unistd.h>    
#include <png.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>

Window create_simple_window(Display* display, int width, int height, int x, int y)
{

  int screen_num = DefaultScreen(display);

  int win_border_width = 2;

  Window win;


  win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
                            x, y, width, height, win_border_width,
                            BlackPixel(display, screen_num),
                            WhitePixel(display, screen_num));

  /* make the window actually appear on the screen. */

  XMapWindow(display, win);

  /* flush all pending requests to the X server. */

  XFlush(display);

  return win;

}

GC create_gc(Display* display, Window win, int reverse_video)

{

  GC gc;                /* handle of newly created GC.  */

  unsigned long valuemask = 0;      /* which values in 'values' to  */

                    /* check when creating the GC.  */

  XGCValues values;         /* initial values for the GC.   */

  unsigned int line_width = 2;      /* line width for the GC.       */

  int line_style = LineSolid;       /* style for lines drawing and  */

  int cap_style = CapButt;      /* style of the line's edje and */

  int join_style = JoinBevel;       /*  joined lines.       */

  int screen_num = DefaultScreen(display);

  gc = XCreateGC(display, win, valuemask, &values);

  if (gc < 0) {

    fprintf(stderr, "XCreateGC: \n");

  }

  /* allocate foreground and background colors for this GC. */

  if (reverse_video) {

    XSetForeground(display, gc, WhitePixel(display, screen_num));

    XSetBackground(display, gc, BlackPixel(display, screen_num));

  }

  else {

    XSetForeground(display, gc, BlackPixel(display, screen_num));

    XSetBackground(display, gc, WhitePixel(display, screen_num));

  }


  XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);


  XSetFillStyle(display, gc, FillSolid);

  return gc;

}

static void TeardownPng (png_structp png, png_infop info)
{

        if (png) {

                png_infop *realInfo = (info? &info: NULL);

                png_destroy_read_struct (&png, realInfo, NULL);

        }

}

void LoadPng (FILE *file, unsigned char** data, char **clipData, unsigned int *width, unsigned int *height, unsigned int *rowbytes)

{

        size_t size = 0,  clipSize = 0;

        png_structp png = NULL;

        png_infop info = NULL;

        unsigned char **rowPointers = NULL;

        int depth = 0,
            colortype = 0,
            interlace = 0,
            compression = 0,
            filter = 0;

        unsigned clipRowbytes = 0;


png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

info = png_create_info_struct (png);

        png_init_io (png, file);

        png_read_info (png, info);

        png_get_IHDR (png, info, (png_uint_32*)width, (png_uint_32*)height, &depth, &colortype, &interlace, &compression, &filter);



        *rowbytes = png_get_rowbytes (png, info);

        if (colortype == PNG_COLOR_TYPE_RGB) {

                // X hates 24bit images - pad to RGBA
                png_set_filler (png, 0xff, PNG_FILLER_AFTER);

                *rowbytes = (*rowbytes * 4) / 3;

        }

        png_set_bgr (png);


        *width = png_get_image_width (png, info);

        *height = png_get_image_height (png, info);

        size = *height * *rowbytes;

        clipRowbytes = *rowbytes/32;

        if (*rowbytes % 32)

                ++clipRowbytes;

        clipSize = clipRowbytes * *height;

        // This gets freed by XDestroyImage

        *data = (unsigned char*) malloc (sizeof (png_byte) * size);

        rowPointers = (unsigned char**) malloc (*height * sizeof (unsigned char*));

        png_bytep cursor = *data;

    int i=0,x=0,y=0;

        for (i=0; i<*height; ++i, cursor += *rowbytes)

                rowPointers[i] = cursor;

        png_read_image (png, rowPointers);

        *clipData = (char*) calloc (clipSize, sizeof(unsigned char));

        if (colortype == PNG_COLOR_TYPE_RGB) {

                memset (*clipData, 0xff, clipSize);

        } else {

                // Set up bitmask for clipping fully transparent areas

                for (y=0; y<*height; ++y, cursor+=*rowbytes) {

                        for (x=0; x<*rowbytes; x+=4) {

                                // Set bit in mask when alpha channel is nonzero

                                if(rowPointers[y][x+3])

                                        (*clipData)[(y*clipRowbytes) + (x/32)] |= (1 << ((x/4)%8));

                        }

                }

        }

        TeardownPng (png, info);

    free (rowPointers);

}

void
main(int argc, char* argv[])

{

	Display* display; 

	int screen_num;   

	Window win;     
	unsigned int display_width, display_height; 
	unsigned int width, height; 
	char *display_name = getenv("DISPLAY");

	GC gc;   

	/*  in our window.               */
	unsigned width_ = 0, height_ = 0;

	unsigned char *data = NULL;
	char *clip = NULL;
	unsigned rowbytes = 0;
	unsigned long *image, *mask;

	/* open connection with the X server. */

	display = XOpenDisplay(display_name);

	if (display == NULL) {

	fprintf(stderr, "%s: cannot connect to X server '%s'\n",
	argv[0], display_name);

	exit(1);

	}

	/* get the geometry of the default screen for our display. */
	screen_num = DefaultScreen(display);

	display_width = DisplayWidth(display, screen_num);

	display_height = DisplayHeight(display, screen_num);

	/* make the new window occupy 1/9 of the screen's size. */

	width = (display_width / 3);

	height = (display_height / 3);

	printf("window width - '%d'; height - '%d'\n", width, height);

	win = create_simple_window(display, width, height, 0, 0);
	

	
	
	gc = create_gc(display, win, 0);

	XSync(display, False);

	/* catch expose events */

	XSelectInput(display, win, ExposureMask);

	/* wait for the expose event */

	XEvent ev;

	XNextEvent(display, &ev);

	// Load image

        FILE *file = fopen ("./timg.png", "r");

        if (!file)

                return;

        LoadPng (file, &data, &clip, &width_, &height_, &rowbytes);

        if (!data)
        	 return;
XImage *ximage = XCreateImage (display, DefaultVisual (display, DefaultScreen (display)), DefaultDepth(display, DefaultScreen (display)), ZPixmap, 0, (char*)data, width_, height_, 8, rowbytes);

        if (ximage) {

                XPutImage (display, win, gc, ximage, 0, 0, 0, 0, width_, height_);

        } else {

                free (data);

        }
	
	while(1)
	{
		XNextEvent(display, &ev);
		if ( ev.type ==  Expose)
		{
			XPutImage (display, win, gc, ximage, 0, 0, 0, 0, width_, height_);
			XFlush(display);
		
		}
	
	
	
	}	
	free (clip);
	XFlush(display);

	XSync(display, False);
	XCloseDisplay(display);

}

makefile

tupian: gtk3.c
	gcc gtk3.c -g  -o  tupian -L/opt/X11/lib -lX11 -lXext `pkg-config --cflags --libs gtk+-3.0` -I `pkg-config libpng15 zlib --libs --cflags`

需要安装libpng库和zlib。这是教程


猜你喜欢

转载自blog.csdn.net/lyw13522476337/article/details/80860686