xlib一夜学习体会

原来认为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.    
  8.     XTextProperty wmName;  
  9.     XTextProperty wmCommand;  
  10.     XWindowAttributes attr;  
  11.    
  12.     int status = XGetWMName(g->display, rootWindow, &wmName);  
  13.    
  14.     XGetWindowAttributes(g->display,rootWindow, &attr);  
  15.    
  16. //if (attr.map_state == IsViewable)   
  17. {  
  18.   if (status && wmName.value && wmName.nitems)  
  19.   {  
  20.    int i;  
  21.    char **list;  
  22.    status = XmbTextPropertyToTextList(g->display, &wmName, &list, &i);  
  23.    if (status >= Success && i && *list)  
  24.    {  
  25.     printf("Found window with name: %s \n",(char*) *list);  
  26.     if(winflag==0)  
  27.     {  
  28.      if((!strcmp((char*) *list,winname1)) | (!strcmp((char*) *list,winname2)))  
  29.      {  
  30.       printf("Found window with name: %s ------------\n",(char*) *list);  
  31.       win1=rootWindow;  
  32.       winflag=1;  
  33.      }  
  34.     }  
  35.     else if(winflag==1)  
  36.     {  
  37.      if(!strcmp((char*) *list,winname2)|(!strcmp((char*) *list,winname1)))  
  38.      {  
  39.       printf("Found window with name: %s -------------\n",(char*) *list);  
  40.       win2=rootWindow;  
  41.      }  
  42.     }  
  43.    }  
  44.    
  45.    status = XGetCommand(g->display, rootWindow, &list, &i);  
  46.    if (status >= Success && i && *list)  
  47.    {  
  48.     //printf("---and Command: %s \n", (char*) *list);   
  49.    }  
  50.    
  51.    Window tf;  
  52.    status = XGetTransientForHint(g->display, rootWindow, &tf);  
  53.    if (status >= Success && tf)  
  54.    {  
  55.     //printf("TF set! \n");   
  56.    }  
  57.    
  58.    XWMHints *pHints = XGetWMHints(g->display, rootWindow);  
  59.    if (pHints)  
  60.    {  
  61.     //printf("Flags: %d " , pHints->flags);   
  62.     //printf( "Window group:%lx \n" , pHints->window_group);   
  63.    }  
  64.   }  
  65. }  
  66.     status = XQueryTree(g->display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);  
  67.     if (status == 0)  
  68.     {  
  69.         // Could not query window tree further, aborting   
  70.         return;  
  71.     }  
  72.    
  73.     if (nNumChildren == 0)  
  74.     {  
  75.         // No more children found. Aborting   
  76.         return;  
  77.     }  
  78.    
  79.     int i=0;  
  80.    
  81.     for (i = 0; i < nNumChildren; i++)  
  82.     {  
  83.      findwindow(g, children[i]);  
  84.     }  
  85.    
  86.     XFree((char*) children);  
  87. }  
void findwindow(Ghandles *g, Window rootWindow)
{
    Window parent;
    Window *children;
    Window *child;
    unsigned int nNumChildren;
 
    XTextProperty wmName;
    XTextProperty wmCommand;
    XWindowAttributes attr;
 
    int status = XGetWMName(g->display, rootWindow, &wmName);
 
    XGetWindowAttributes(g->display,rootWindow, &attr);
 
//if (attr.map_state == IsViewable)
{
  if (status && wmName.value && wmName.nitems)
  {
   int i;
   char **list;
   status = XmbTextPropertyToTextList(g->display, &wmName, &list, &i);
   if (status >= Success && i && *list)
   {
    printf("Found window with name: %s \n",(char*) *list);
    if(winflag==0)
    {
     if((!strcmp((char*) *list,winname1)) | (!strcmp((char*) *list,winname2)))
     {
      printf("Found window with name: %s ------------\n",(char*) *list);
      win1=rootWindow;
      winflag=1;
     }
    }
    else if(winflag==1)
    {
     if(!strcmp((char*) *list,winname2)|(!strcmp((char*) *list,winname1)))
     {
      printf("Found window with name: %s -------------\n",(char*) *list);
      win2=rootWindow;
     }
    }
   }
 
   status = XGetCommand(g->display, rootWindow, &list, &i);
   if (status >= Success && i && *list)
   {
    //printf("---and Command: %s \n", (char*) *list);
   }
 
   Window tf;
   status = XGetTransientForHint(g->display, rootWindow, &tf);
   if (status >= Success && tf)
   {
    //printf("TF set! \n");
   }
 
   XWMHints *pHints = XGetWMHints(g->display, rootWindow);
   if (pHints)
   {
    //printf("Flags: %d " , pHints->flags);
    //printf( "Window group:%lx \n" , pHints->window_group);
   }
  }
}
    status = XQueryTree(g->display, rootWindow, &rootWindow, &parent, &children, &nNumChildren);
    if (status == 0)
    {
        // Could not query window tree further, aborting
        return;
    }
 
    if (nNumChildren == 0)
    {
        // No more children found. Aborting
        return;
    }
 
    int i=0;
 
    for (i = 0; i < nNumChildren; i++)
    {
     findwindow(g, children[i]);
    }
 
    XFree((char*) children);
}

还可以实现窗口 切换.... xlib唯一和GTK+ 不同的地方, 就是可以控制底层的一些东西, 其它概念拆不多.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值