Exemple #1
0
Bool
ResolutionSetTopology(unsigned int ndisplays,
                      DisplayTopologyInfo *topology)
{
#ifdef NO_MULTIMON
   return FALSE;
#else
   ResolutionInfoX11Type *resInfoX = &resolutionInfoX11;
   Bool success = FALSE;
   unsigned int i;
   xXineramaScreenInfo *displays = NULL;
   short maxX = 0;
   short maxY = 0;
   int minX = 0x7FFF;
   int minY = 0x7FFF;

   ASSERT(resolutionInfo.canSetTopology);

   /*
    * Allocate xXineramaScreenInfo array & translate from DisplayTopologyInfo.
    * Iterate over displays looking for minimum, maximum dimensions.
    * Warn if min isn't at (0,0).
    * Transform to (0,0).
    * Call out to VMwareCtrl_SetTopology.
    * Set new jumbotron resolution.
    */

   displays = malloc(sizeof *displays * ndisplays);
   if (!displays) {
      goto out;
   }

   for (i = 0; i < ndisplays; i++) {
      displays[i].x_org = topology[i].x;
      displays[i].y_org = topology[i].y;
      displays[i].width = topology[i].width;
      displays[i].height = topology[i].height;

      maxX = MAX(maxX, displays[i].x_org + displays[i].width);
      maxY = MAX(maxY, displays[i].y_org + displays[i].height);
      minX = MIN(minX, displays[i].x_org);
      minY = MIN(minY, displays[i].y_org);
   }

   if (minX != 0 || minY != 0) {
      g_warning("The bounding box of the display topology does not have an "
                "origin of (0,0)\n");
   }

   /*
    * Transform the topology so that the bounding box has an origin of (0,0). Since the
    * host is already supposed to pass a normalized topology, this should not have any
    * effect.
    */
   for (i = 0; i < ndisplays; i++) {
      displays[i].x_org -= minX;
      displays[i].y_org -= minY;
   }

   /*
    * Grab server to avoid potential races between setting GUI topology
    * and setting FB topology.
    */
   XGrabServer(resInfoX->display);

   /*
    * First, call vmwarectrl to update the connection info
    * and resolution capabilities of connected monitors,
    * according to the host GUI layout on vmwgfx. On vmwlegacy this
    * sets the driver's exported Xinerama topology.
    *
    * For vmwgfx, this might be replaced with a direct kernel driver call
    * in upcoming versions.
    */
   if (resInfoX->canUseVMwareCtrlTopologySet) {
      if (!VMwareCtrl_SetTopology(resInfoX->display,
				  DefaultScreen(resInfoX->display),
                                  displays, ndisplays)) {
         g_debug("Failed to set topology in the driver.\n");
         goto out;
      }
   }

   if (resInfoX->canUseRandR12) {
       /*
	* For vmwgfx, use RandR12 to set the FB layout to a 1:1 mapping
	* of the host GUI layout.
	*/
      success = RandR12_SetTopology(resInfoX->display,
                                    DefaultScreen(resInfoX->display),
                                    resInfoX->rootWindow,
                                    ndisplays, displays,
                                    maxX - minX, maxY - minY);
   } else if (resInfoX->canUseVMwareCtrlTopologySet) {
      /*
       * For vmwlegacy, use legacy RandR to set the backing framebuffer
       * size. We don't do this unless we were able to set a new
       * topology using vmwarectrl.
       */
      if (!SelectResolution(maxX - minX, maxY - minY)) {
         g_debug("Failed to set new resolution.\n");
         goto out;
      }

      success = TRUE;
   }

out:
   XUngrabServer(resInfoX->display);
   XFlush(resInfoX->display);

   free(displays);
   return success;
#endif
}
int
main (int argc, char **argv)
{
   Display *dpy;
   char *displayName = NULL;
   int screen;
   int major, minor;

   dpy = XOpenDisplay(displayName);
   if (!dpy) {
      printf("Could not open default X Display\n");
      exit(EXIT_FAILURE);
   }
   screen = DefaultScreen(dpy);

   if (VMwareCtrl_QueryVersion(dpy, &major, &minor)) {
      printf("Got Extension version %d.%d\n", major, minor);
   } else {
      printf("VMWARE_CTRL Extension not found.\n");
      exit(EXIT_FAILURE);
   }

   if (argc >= 2) {
      if (strcmp(argv[1], "setres") == 0) {
         int x, y;
         if (argc < 4) {
            printf("Setres needs x and y too\n");
            exit(EXIT_FAILURE);
         }

         x = atoi(argv[2]);
         y = atoi(argv[3]);

         if (VMwareCtrl_SetRes(dpy, screen, x, y)) {
            printf("Set Res was successful\n");
         } else {
            printf("Set Res failed\n");
         }
      } else if (strcmp(argv[1], "settopology") == 0) {
         xXineramaScreenInfo extents[2];

         if (major == 0 && minor < 2) {
            printf("VMWARE_CTRL version >= 0.2 is required\n");
            exit(EXIT_FAILURE);
         }

         printf("Requesting hard-coded topology\n");

         extents[0].x_org = 0;
         extents[0].y_org = 0;
         extents[0].width = 800;
         extents[0].height = 600;
         extents[1].x_org = 800;
         extents[1].y_org = 0;
         extents[1].width = 800;
         extents[1].height = 600;
         if (VMwareCtrl_SetTopology(dpy, screen, extents, 2)) {
            printf("SetTopology was successful\n");
         } else {
            printf("SetTopology failed\n");
         }
      }
   }

   return EXIT_SUCCESS;
}