LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 4088|回复: 5

Xlib实用编程之——在窗口里呈现xpm图片

[复制链接]
发表于 2006-9-29 09:33:29 | 显示全部楼层 |阅读模式
首先安装imagemagick软件包,其中的convert命令十分强大,可以把任意格式的图片文件转换为xpm文件格式。
假设有个test.bmp文件,我们可以用convert test.bmp test.xpm把它转换为xpm文件,因为Xlib默认支持的文件格式只有xpm所以我们只能这样做。得到的test.xpm实际是个文本文件,定义了的是一个字符串指针数组。
因为Xlib没有提供可以直接存取xpm文件的函数,所以我们还需要安装两个软件包libxpm4以及libxpm-dev。
然后写如下的代码

  1. /***************
  2. file xpmtest1.c
  3. ***************/
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <X11/Xlib.h> /* defines common Xlib functions and structs. */
  8. #include <X11/xpm.h>
  9. #include "test.xpm"


  10. int main (int argc, char *argv[] )
  11. {
  12.         char *EnvDisp = NULL;
  13.         /* this variable will contain the pointer to the Display structure */
  14.         /* returned when opening a connection. */
  15.         Display* display;

  16.         //处理DISPLAY环境变量
  17.         if ( (EnvDisp = getenv("DISPLAY")) == NULL)
  18.         {
  19.                 display = XOpenDisplay(":0.0");
  20.         }
  21.         else
  22.         {
  23.                 display = XOpenDisplay(EnvDisp);
  24.         }
  25.         if (display == NULL) {
  26.                 fprintf(stderr, "Cannot connect to X server %s\n", EnvDisp?EnvDisp:"localhost:0.0");
  27.                 exit (-1);
  28.         }
  29. //检查SCREEN的属性
  30.         /* this variable will be used to store the "default" screen of the */
  31.         /* X server. usually an X server has only one screen, so we're only */
  32.         /* interested in that screen. */
  33.         int screen_num;
  34.         /* these variables will store the size of the screen, in pixels. */
  35.         int screen_width;
  36.         int screen_height;
  37.         /* this variable will be used to store the ID of the root window of our */
  38.         /* screen. Each screen always has a root window that covers the whole */
  39.         /* screen, and always exists. */
  40.         Window root_window;
  41.         /* these variables will be used to store the IDs of the black and white */
  42.         /* colors of the given screen. More on this will be explained later. */
  43.         unsigned long white_pixel;
  44.         unsigned long black_pixel;
  45.         /* check the number of the default screen for our X server. */
  46.         screen_num = DefaultScreen(display);
  47.         /* find the width of the default screen of our X server, in pixels. */
  48.         screen_width = DisplayWidth(display, screen_num);
  49.         /* find the height of the default screen of our X server, in pixels. */
  50.         screen_height = DisplayHeight(display, screen_num);
  51.         /* find the ID of the root window of the screen. */
  52.         root_window = RootWindow(display, screen_num);
  53.         /* find the value of a white pixel on this screen. */
  54.         white_pixel = WhitePixel(display, screen_num);
  55.         /* find the value of a black pixel on this screen. */
  56.         black_pixel = BlackPixel(display, screen_num);
  57.        
  58.         fprintf(stdout, "Width x Height:%dx%d\n",
  59.                 screen_width, screen_height);
  60.         Window win;
  61.         int win_x = 0;
  62.         int win_y = 0;
  63.         int win_border_width = 0;
  64.        
  65.         /* create the window, as specified earlier. */
  66.         win = XCreateSimpleWindow(display,
  67.                 root_window,
  68.                 win_x, win_y,
  69.                 screen_width, screen_height,
  70.                 win_border_width,
  71.                 black_pixel,
  72.                 white_pixel);
  73.        
  74.         XMapWindow(display, win);
  75.        
  76. //加载相应的背景图片
  77.         GC gc;
  78.         XGCValues values ;
  79.         //values = CapButt | JoinBevel;
  80.         unsigned long valuemask = GCCapStyle | GCJoinStyle;
  81.         gc = XCreateGC(display, win, valuemask, &values);
  82.         if( gc < 0)
  83.         {
  84.                 fprintf(stderr, "GC can't be created\n");                       
  85.         }
  86.         XSetForeground(display, gc,        black_pixel);
  87.         XSetBackground(display, gc, white_pixel);

  88.         Pixmap pxmap;
  89.         XpmAttributes xpmattr;
  90.         memset(&xpmattr, 0, sizeof(xpmattr));
  91.         int rc;
  92.         rc = XpmCreatePixmapFromData(display, win, test, &pxmap, NULL, &xpmattr);
  93.         printf("XpmCreatePixmapFromData() return %d\n", rc);
  94.         XCopyArea(display, pxmap, win, gc, 0, 0, xpmattr.width, xpmattr.height, 0, 0);

  95. //处理事件
  96.         XSelectInput(display, win, ExposureMask | KeyReleaseMask);
  97.         XEvent an_event;
  98.         while(1)
  99.         {
  100.                 XNextEvent(display, &an_event);
  101.                 switch( an_event.type)
  102.                 {
  103.                         case Expose:
  104.                                 if( an_event.xexpose.count > 0)
  105.                                         break;
  106.                                 XCopyArea(display, pxmap, win, gc, 0, 0, xpmattr.width, xpmattr.height, 0, 0);
  107.                                 break;
  108.                         case KeyRelease:
  109.                                 printf("keycode %d\n", an_event.xkey.keycode);
  110.                                 printf("keystate %d\n",an_event.xkey.state);
  111.                                 break;                               
  112.                         default:
  113.                                 break;
  114.                 }
  115.         }       

  116.         XFreePixmap(display, pxmap);
  117.         XCloseDisplay(display);        

  118. }
复制代码

用gcc xpmtest1.c -o xpmtest -lX11 -lXpm
运行它,看看发生了什么。
发表于 2006-9-30 10:17:51 | 显示全部楼层
应该是件有趣的事情

但我编译的时候出现selectlang未声明的错误。它在这里:
        int rc;
        rc = XpmCreatePixmapFromData(display, win, selectlang, &pxmap, NULL, &xpmattr);
        printf("XpmCreatePixmapFromData() return %d\n", rc);
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-30 10:20:59 | 显示全部楼层
不好意思,这句应改为
rc = XpmCreatePixmapFromData(display, win, test, &pxmap, NULL, &xpmattr);
回复 支持 反对

使用道具 举报

发表于 2008-7-28 13:48:04 | 显示全部楼层
错误: test.xpm:没有该文件或目录
这是怎么回事啊,还有XpmCreatePixmapFromData第三个参数怎么设置啊,
大侠我是菜鸟啊,现在要求用xlib写一个显示图片的程序,刚用GTK写了一个用Xlib不知道用什么加载图片,大侠帮忙
回复 支持 反对

使用道具 举报

发表于 2008-7-28 16:32:28 | 显示全部楼层
Post by atlantic.china;1879430
错误: test.xpm:没有该文件或目录
这是怎么回事啊,还有XpmCreatePixmapFromData第三个参数怎么设置啊,
大侠我是菜鸟啊,现在要求用xlib写一个显示图片的程序,刚用GTK写了一个用Xlib不知道用什么加载图片,大侠帮忙

也许你应该准备一个 xpm 文件,test.xpm,或者尝试包含已经存在的文件。
回复 支持 反对

使用道具 举报

发表于 2008-7-29 16:35:17 | 显示全部楼层
Post by herberteuler;1879476
也许你应该准备一个 xpm 文件,test.xpm,或者尝试包含已经存在的文件。
嗯,我一开始压根不知道Xpm什么玩意,现在知道我用Convert命令转换图片为Xpm,呵呵,谢谢楼上
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表