是否有更有效的方式来影响用户的X11会话而不是我正在做的事情? (C \ XLIB)

时间:2013-07-11 16:57:16

标签: c linux xlib x11

这假设两个会话在多用户桌面环境中位于同一个框中。这是我的C代码:

int main(int argc, char* argv[]) {
   Display *d_remote; /* - Display of User you are shadowing - */
   Display *d_local; /* - Your display */
   XImage *img; /* - Used to hold the pixles of the shadowed user's display - */
   Window w, pointer_root, pointer_child;
   XEvent e;
   int s;
   int pointerX, pointerY, winX, winY;
   unsigned int mask;

   //Open your display, if you cant set to NULL 
   d_local = XOpenDisplay(NULL);

   if(d_local == NULL) {
    printf("Error opening 'local' display\n");
    exit(1);
   }

   //Set the XAUTHORITY to teh argument provided.  This is the XAUTHORITY for the remote display
   setenv("XAUTHORITY", argv[2],1);
   d_remote = XOpenDisplay(argv[1]);

   if(d_remote == NULL) {
    printf("Error opening 'remote' display %s\n", argv[1]);
    exit(1);
   }


   //Get the size of the remote display
   Window root_remote = RootWindow(d_remote,0);
   XWindowAttributes attr;
   XGetWindowAttributes(d_remote,root_remote,&attr);
   img = XGetImage(d_remote,RootWindow(d_remote,0),0,0,attr.width,attr.height,XAllPlanes(),ZPixmap);

   printf("attr.width = %d, attr.height=%d\n", attr.width, attr.height);

   //Create the window on your display
   s = DefaultScreen(d_local);
   w = XCreateSimpleWindow(d_local, RootWindow(d_local, s), 10, 10, 100, 100, 1,
                           BlackPixel(d_local, s), WhitePixel(d_local, s));

   XSelectInput(d_local, w, ExposureMask | KeyPressMask);
   XMapWindow(d_local, w);

   while (1) {

      /* - Get the image from the remote display and push it to the local window - */
      img = XGetImage(d_remote,RootWindow(d_remote,0),0,0,attr.width,attr.height,XAllPlanes(),ZPixmap);
      XPutImage(d_local, w, DefaultGC(d_local,0), img, 10, 10, 0, 0, attr.width, attr.height);

      XQueryPointer(d_remote, RootWindow(d_remote,0), &pointer_root, &pointer_child, &pointerX, &pointerY, &winX, &winY, &mask);

      XFillRectangle(d_local, w, DefaultGC(d_local, s), pointerX-10, pointerY-10, 10, 10);
      XFlush(d_local);
      usleep(10);
   }

   XCloseDisplay(d_local);
   XCloseDisplay(d_remote);
   return 0;
}

我基本上循环,使用XGetImage获取被遮蔽的用户屏幕的原始图像,然后将该图像转储到Window中。这是使用大量的CPU。我可以理解为什么考虑到我每隔一分钟操纵一次大图像。

有更有效的方法吗? VNC本质上捕获用户的屏幕并通过线路发送(当然是压缩的),但不会使用几乎相同的CPU。

1 个答案:

答案 0 :(得分:1)

您可以使用DAMAGE extension在屏幕更新时以及屏幕的哪个部分发生变化时收到通知,因此如果没有任何变化,您不需要每10微秒抓取整个屏幕(这很多)如果显示器以60 Hz的刷新率运行,则用户可以看到更改的频率,如果所有更改都是显示时钟的10x10像素区域,也不需要抓取整个屏幕。