// change the video mode to one of the available resolution codes, currently: // 0 - 640x480, Fullscreen // 1 - Windowed scale x1 (320x240) // 2 - Windowed scale x2 (640x480) // 3 - Windowed scale x3 (960x720) bool Graphics::SetResolution(int r, bool restoreOnFailure) { stat("Graphics::SetResolution(%d)", r); if (r == current_res) return 0; int old_res = current_res; #ifdef IPHONE restoreOnFailure = false; if (SelectResolution()) { staterr("SelectResolution() failed!"); return 1; } #else int factor; if (r == 0) { is_fullscreen = true; factor = 2; } else { is_fullscreen = false; factor = r; } stat("Setting scaling %d and fullscreen=%s", factor, is_fullscreen ? "yes":"no"); NXSurface::SetScale(factor); #endif if (Graphics::InitVideo()) { staterr("Switch to resolution %d failed!", r); if (restoreOnFailure) { staterr("Trying to recover old mode %d.", r, old_res); if (Graphics::SetResolution(old_res, false)) { staterr("Fatal error: vidmode recovery failed!!!"); } } return 1; } if (Graphics::FlushAll()) return 1; return 0; }
Bool ResolutionSetResolution(uint32 width, uint32 height) { ResolutionInfoX11Type *resInfoX = &resolutionInfoX11; Bool ret; ASSERT(resolutionInfo.canSetResolution); XGrabServer(resInfoX->display); if (resInfoX->canUseVMwareCtrl) { /* * If so, use the VMWARE_CTRL extension to provide a custom resolution * which we'll find as an exact match from XRRConfigSizes() (unless * the resolution is too large). * * As such, we don't care if this succeeds or fails, we'll make a best * effort attempt to change resolution anyway. * * On vmwgfx, this is routed through the X server down to the * kernel modesetting system to provide a preferred mode with * correcte width and height. */ VMwareCtrl_SetRes(resInfoX->display, DefaultScreen(resInfoX->display), width, height); } /* * Use legacy RandR (vmwlegacy) or RandR12 (vmwgfx) to select the * desired mode. */ ret = SelectResolution(width, height); XUngrabServer(resInfoX->display); XFlush(resInfoX->display); return ret; }
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 }