xlib一夜学习体会
Tofloor
poster avatar
z85525006
deepin
2012-06-09 17:45
Author
原来认为xlib有多神奇,原来和GTK+一样,操作非常方便.
有鼠标事件,暴露事件,键盘事件等等....
只要看API,就可以一步步的操作.
xlib和window SDK有的一比,写界面都很繁琐,相比之下,我感觉xlib写界面和其它程序要比SDK简单的多.

我感觉学 XLIB 的人也没有什么,就 和学GTK+ 的人没有什么区别.
xlib 可以画 button, listview, treeview, 等等一些常用控件. 一定没有人喜欢这样干.
xlib也可以截图..
XGetWindowAttributes 可以获取窗口的属性.当然也可以获取其它窗口的.
int x, y;
    窗口的位置,相对于它的父窗口。
int width, height;
    窗口的宽和高(单位,像素)。
int border_width
    窗口的边框宽度
Window root;
    根窗口,也就是我们的窗口在那个窗口里被显示了。
XQueryTree() 这个函数可以返回一大堆的东西给你.

struct _global_handles{
Display *display;
unsigned int screen;
Window root_win;
};

typedef struct _global_handles Ghandles; 这个是 g 类型结构体.

status = XQueryTree(g->display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);

这个例子 他 实现的是一个递归查询 窗口.
  1. void findwindow(Ghandles *g, Window rootWindow)
  2. {
  3.     Window parent;
  4.     Window *children;
  5.     Window *child;
  6.     unsigned int nNumChildren;
  7.     XTextProperty wmName;
  8.     XTextProperty wmCommand;
  9.     XWindowAttributes attr;
  10.     int status = XGetWMName(g->display, rootWindow, &wmName);
  11.     XGetWindowAttributes(g->display,rootWindow, &attr);
  12. //if (attr.map_state == IsViewable)
  13. {
  14.   if (status && wmName.value && wmName.nitems)
  15.   {
  16.    int i;
  17.    char **list;
  18.    status = XmbTextPropertyToTextList(g->display, &wmName, &list, &i);
  19.    if (status >= Success && i && *list)
  20.    {
  21.     printf("Found window with name: %s \n",(char*) *list);
  22.     if(winflag==0)
  23.     {
  24.      if((!strcmp((char*) *list,winname1)) | (!strcmp((char*) *list,winname2)))
  25.      {
  26.       printf("Found window with name: %s ------------\n",(char*) *list);
  27.       win1=rootWindow;
  28.       winflag=1;
  29.      }
  30.     }
  31.     else if(winflag==1)
  32.     {
  33.      if(!strcmp((char*) *list,winname2)|(!strcmp((char*) *list,winname1)))
  34.      {
  35.       printf("Found window with name: %s -------------\n",(char*) *list);
  36.       win2=rootWindow;
  37.      }
  38.     }
  39.    }
  40.    status = XGetCommand(g->display, rootWindow, &list, &i);
  41.    if (status >= Success && i && *list)
  42.    {
  43.     //printf("---and Command: %s \n", (char*) *list);
  44.    }
  45.    Window tf;
  46.    status = XGetTransientForHint(g->display, rootWindow, &tf);
  47.    if (status >= Success && tf)
  48.    {
  49.     //printf("TF set! \n");
  50.    }
  51.    XWMHints *pHints = XGetWMHints(g->display, rootWindow);
  52.    if (pHints)
  53.    {
  54.     //printf("Flags: %d " , pHints->flags);
  55.     //printf( "Window group:%lx \n" , pHints->window_group);
  56.    }
  57.   }
  58. }
  59.     status = XQueryTree(g->display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
  60.     if (status == 0)
  61.     {
  62.         // Could not query window tree further, aborting
  63.         return;
  64.     }
  65.     if (nNumChildren == 0)
  66.     {
  67.         // No more children found. Aborting
  68.         return;
  69.     }
  70.     int i=0;
  71.     for (i = 0; i < nNumChildren; i++)
  72.     {
  73.      findwindow(g, children[i]);
  74.     }
  75.     XFree((char*) children);
  76. }
Copy the Code
还可以实现窗口 切换.... xlib唯一和GTK+ 不同的地方, 就是可以控制底层的一些东西, 其它概念拆不多.
  1. /*
  2. * Xlib 学习
  3. *
  4. *
  5. * XEvent  
  6. * XMotion
  7. *
  8. *
  9. *
  10. *
  11. * 编译基于Xlib的程序需要与Xlib库连接。可以使用下面的命令行:
  12.   cc prog.c -o prog -lX11
  13.   如果编译器报告找不到X11库,可以试着加上"-L"标志,像这样:
  14.    cc prog.c -o prog -L/usr/X11/lib -lX11
  15.    或者这样(针对使用X11的版本6)
  16.    cc prog.c -o prog -L/usr/X11R6/lib -lX11
  17.    在SunOs 4 系统上,X的库被放到了 /usr/openwin/lib
  18.    cc prog.c -o prog -L/usr/openwin/lib -lX11
  19. *
  20. * GC-图形上下文.[图形,文本等, 绘制,前景,背景,使用什么颜色,使用什么字体等等.]
  21. * 对象句柄:例如: 窗口,绘图区和光标-相应的函数就会返回一个句柄.
  22. * 释放内存: XFree()
  23. * 事件: XEvent,(联合体), XMotion, XButon.
  24. * */
  25. /*
  26. *      
  27. Display* display;   
  28. display = XOpenDisplay("simey:0");
  29. if (NULL == display){
  30. fprintf(stderr, "连接不上X Server %s\n", "simey:0");
  31. exit(-1);
  32. }
  33. 关闭X服务器连接
  34. XCloseDisplay(display)
  35. * */
  36. #include
  37. #include
  38. #include
  39. #include
  40. #include
  41. int main(int argc, char *argv[])
  42. {
  43.      
  44.      Display* display;
  45.      display = XOpenDisplay("simey:0");
  46.      
  47.      if (NULL == display){
  48.           fprintf(stderr, "连接不上X Server %s\n", "simey:0");
  49.           exit(-1);
  50.      }
  51.      int screen_num;
  52.      int screen_width;
  53.      int screen_height;
  54.      Window root_window;
  55.      
  56.      unsigned long white_pixel;
  57.      unsigned long black_pixel;
  58.      
  59.      screen_num = DefaultScreen(display);
  60.      
  61.      screen_width = DisplayWidth(display, screen_num);
  62.      screen_height = DisplayHeight(display, screen_num);
  63.          
  64.      puts("测试输出:");
  65.      printf("句柄:%x宽度:%d高度:%d\n",
  66.             screen_num, screen_width, screen_height);
  67.          
  68.      root_window = RootWindow(display, screen_num);
  69.      white_pixel = WhitePixel(display, screen_num);
  70.      black_pixel = BlackPixel(display, screen_num);
  71.      
  72.      Window win;
  73.      int win_width;
  74.      int win_height;
  75.      int win_x;
  76.      int win_y;     
  77.      int win_border_width;
  78.      int win_border_height;
  79.          
  80.      int width;
  81.      int height;
  82.      
  83.      win_x = win_y = win_border_width= win_border_height = 0;
  84.      win_width = DisplayWidth(display, screen_num);
  85.      win_height = DisplayHeight(display, screen_num);
  86.      
  87.      width = (win_width / 3);
  88.      height = (win_height / 3);
  89.      win_border_width = 2;
  90.      
  91.      /*创建一个窗口*/     
  92.      win = XCreateSimpleWindow(
  93.           display,
  94.           RootWindow(display, screen_num),
  95.           win_x, win_y,
  96.           width, height,
  97.           win_border_width, win_border_height,
  98.           WhitePixel(display, screen_num)
  99.           );
  100.      /*注册事件*/
  101.      /* XSelectInput(display, win, ExposureMask); */
  102.      /*ExposureMask在头文件"X.h"中被定义,如果我们想注册更多的事件类型,我们可以使用逻辑"or"*/
  103.      
  104.      XSelectInput(display, win,
  105.                   ExposureMask | ButtonPressMask |
  106.                   ButtonReleaseMask | ButtonPress |
  107.                   ButtonRelease | EnterWindowMask |
  108.                   LeaveWindowMask | EnterNotify |
  109.                   LeaveNotify
  110.           );
  111.      /*鼠标的进入和离开 Enter Leave和GTK很像.*/
  112.      
  113.      XMapWindow(display, win);
  114.      
  115.      /*画笔*/
  116.      GC gc;
  117.      XGCValues values;
  118.      unsigned long valuemask = 0;
  119.      /* XGCValues values = CapButt | JoinBevel; */
  120.      /* unsigned long valuemask = GCCapStyle | GCJoinStyle; */
  121.      gc = XCreateGC(display, win, valuemask, &values);
  122.      XSync(display, False);
  123.      if (gc < 0)
  124.      {
  125.           fprintf(stderr, "XCreateGC:\n");
  126.      }
  127.      /*画画.*/
  128.      
  129.      XSetBackground(display, gc, WhitePixel(display, screen_num));/*设置背景颜色*/
  130.      XSetForeground(display, gc, BlackPixel(display, screen_num));/*设置前景色*/
  131.      unsigned int line_width = 2;
  132.      int line_style = LineSolid;
  133.      int cap_style = CapButt;
  134.      int join_style = JoinBevel;
  135.      XSetLineAttributes(display, gc,
  136.                         line_width, line_style, cap_style, join_style);
  137.      XSetFillStyle(display, gc, FillSolid);
  138.      
  139.      /* sleep(14); */
  140.      XEvent an_event;
  141.      /*事件循环*/
  142.      while (1)
  143.      {
  144.           XNextEvent(display, &an_event);
  145.           /*这里就是判断所有事件*/
  146.          
  147.           switch(an_event.type)
  148.           {
  149.                
  150.           case KeyPress:
  151.                printf("键盘被按下");
  152.                break;
  153.           case Expose: /*重绘*/
  154.                if(an_event.xexpose.count > 0)     
  155.                {
  156.                     break;
  157.                }
  158.                XDrawLine(display, win, gc, 0, 100, 400, 100);
  159.                XDrawPoint(display, win, gc, 5, 5);
  160.                XDrawRectangle(display, win, gc, 120, 150, 50, 60);     
  161.                XFillRectangle(display, win, gc, 60, 150, 50, 60);
  162.                /*刷新*/
  163.                XFlush(display);
  164.                printf("正在重绘事件\n");
  165.                break;
  166.           case ButtonPress: /*按下事件*/
  167.                /* int x; */
  168.                /* int y; */
  169.                /* x = an_event.xbutton.x; */
  170.                /* y = an_event.xbutton.window; */               
  171.                switch(an_event.xbutton.button){
  172.                case Button1:
  173.                     XDrawRectangle(display, win, gc, 120, 150, 50, 60);     
  174.                     puts("鼠标左键按下");
  175.                     break;
  176.                case Button2:     
  177.                     puts("button2...");
  178.                     break;
  179.                default:
  180.                     break;
  181.                }
  182.           }               
  183.          
  184.      }
  185.      /*关闭X服务器连接*/
  186.      XCloseDisplay(display);
  187.      return 0;
  188. }
  189. /*
  190.   Display* display
  191.   指向显示结构的指针
  192.   Window parent
  193.   新窗口的父窗口的ID。
  194.   int x
  195.   窗口的左上X坐标(单位为屏幕像素)
  196.   int y
  197.   窗口的左上Y坐标(单位为屏幕像素)
  198.   unsigned int width
  199.   窗口的宽度(单位为屏幕像素)
  200.   unsigned int height
  201.   窗口的高度(单位为屏幕像素)
  202.   unsigned int border_width
  203.   窗口的边框宽度(单位为屏幕像素)
  204.   unsigned long border
  205.   用来绘制窗口边框的颜色
  206.   unsigned long background
  207.   用来绘制窗口背景的颜色
  208. * */
  209. /*
  210.   在事件结构里,通过"an_event.xbutton"来获得事件的类型,另外它还包括下面这些有趣的内容:
  211.   Window window
  212.   事件发送的目标窗口的ID(如果我们为多个窗口注册了事件)
  213.   int x, y
  214.   从窗口的左上坐标算起,鼠标键按下时光标在窗口中的坐标
  215.   int button
  216.   鼠标上那个标号的按钮被按下了,值可能是Button1,Button2,Button3
  217.   Time time
  218.   事件被放进队列的时间。可以被用来实现双击的处理
  219. * */
  220. /*
  221.   鼠标光标的进入和离开事件
  222.   另一个程序通常会感兴趣的事件是,有关鼠标光标进入一个窗口的领域以及离开那个窗口的领域的事件。有些程序利用该事件来告诉用户程序现在在焦点里面。为了注册这种事件,我们将会在函数XSelectInput()里注册几个面具。
  223.   EnterWindowMask
  224.   通知我们鼠标光标进入了我们的窗口中的任意一个
  225.   LeaveWindowMask
  226.   通知我们鼠标光标离开了我们的窗口中的任意一个
  227.   我们的事件循环中的分支检查将检查以下的事件类型
  228.   EnterNotify
  229.   鼠标光标进入了我们的窗口
  230.   LeaveNotify
  231.   鼠标光标离开了我们的窗口
  232.   这些事件类型的数据结构通过例如"an_event.xcrossing"来访问,它还包含以下有趣的成员变量:
  233.   Window window
  234.   事件发送的目标窗口的ID(如果我们为多个窗口注册了事件)
  235.   Window subwindow
  236.   在一个进入事件中,它的意思是从那个子窗口进入我们的窗口,在一个离开事件中,它的意思是进入了那个子窗口,如果是"none",它的意思是从外面进入了我们的窗口。
  237.   int x, y
  238.   从窗口的左上坐标算起,事件产生时鼠标光标在窗口中的坐标
  239.   int mode
  240.   鼠标上那个标号的按钮被按下了,值可能是Button1,Button2,Button3
  241.   Time time
  242.   事件被放进队列的时间。可以被用来实现双击的处理
  243.   unsigned int state
  244.   这个事件发生时鼠标按钮(或是键盘键)被按下的情况 - 如果有的话。这个成员使用按位或的方式来表示
  245.   Button1Mask
  246.   Button2Mask
  247.   Button3Mask
  248.   Button4Mask
  249.   ShiftMask
  250.   LockMask
  251.   ControlMask
  252.   Mod1Mask
  253.   Mod2Mask
  254.   Mod3Mask
  255.   Mod4Mask
  256.   Bool focus
  257.   当值是True的时候说明窗口获得了键盘焦点,False反之
  258. * */
  259. /*
  260. * 键盘键按下和松开事件
  261. 如果我们程序控制的窗口获得了键盘焦点,它就可以接受按键的按下和松开事件。为了注册这些事件的类型,我们就需要通过函数XSelectInput()来注册下面的面具。
  262. KeyPressMask
  263. 通知我们的程序什么时候按键被按下了
  264. KeyPressMask
  265. 通知我们的程序什么时候按键被松开了
  266. 我们的事件循环中的分支检查将检查以下的事件类型
  267. Window window
  268. 事件发送的目标窗口的ID(如果我们为多个窗口注册了事件)
  269. unsigned int keycode
  270. 被按下(或松开)的键的编码。这是一些X内部编码,应该被翻译成一个键盘键符号才能方便使用,将会在下面介绍。
  271. int x, y
  272. 从窗口的左上坐标算起,事件产生时鼠标光标在窗口中的坐标
  273. Time time
  274. 事件被放进队列的时间。可以被用来实现双击的处理
  275. unsigned int state
  276. 这个事件发生时鼠标按钮(或是键盘键)被按下的情况 - 如果有的话。这个成员使用按位或的方式来表示
  277. Button1Mask
  278. Button2Mask
  279. Button3Mask
  280. Button4Mask
  281. ShiftMask
  282. LockMask
  283. ControlMask
  284. Mod1Mask
  285. Mod2Mask
  286. Mod3Mask
  287. Mod4Mask
Copy the Code

1.tar.gz
Reply Favorite View the author
All Replies
z85525006
deepin
2012-06-09 17:54
#1
专心搞好一个,再搞另一个.
学过GTK+的,学xlib非常 快... ..
学几天或者一个晚上, 对照API,就可以干事情啦. 然后看看其它的源码,学习一下, OK.
Reply View the author
z85525006
deepin
2012-06-09 20:34
#2
XQueryPointer  
Bool XQueryPointer(display, w, root_return, child_return, root_x_return, root_y_return,
                     win_x_return, win_y_return, mask_return)
      Display *display;
      Window w;
      Window *root_return, *child_return;
      int *root_x_return, *root_y_return;
      int *win_x_return, *win_y_return;
      unsigned int *mask_return;
Reply View the author