1

这假设这两个会话在多用户桌面环境中的同一个盒子上。这是我的 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 获取阴影用户屏幕的原始图像,然后将该图像转储到窗口中。这使用了大量的 CPU。我可以理解为什么考虑到我每厘米都在处理大图像。

有没有更有效的方法来做到这一点?VNC 本质上会捕获用户的屏幕并通过网络发送(当然是压缩的),但不会使用几乎一样多的 CPU。

4

1 回答 1

1

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

于 2013-07-15T23:31:36.487 回答