116fd1166Smrg/* 216fd1166Smrg * Copyright 2007 by VMware, Inc. 316fd1166Smrg * 416fd1166Smrg * Permission is hereby granted, free of charge, to any person obtaining a 516fd1166Smrg * copy of this software and associated documentation files (the "Software"), 616fd1166Smrg * to deal in the Software without restriction, including without limitation 716fd1166Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 816fd1166Smrg * and/or sell copies of the Software, and to permit persons to whom the 916fd1166Smrg * Software is furnished to do so, subject to the following conditions: 1016fd1166Smrg * 1116fd1166Smrg * The above copyright notice and this permission notice shall be included in 1216fd1166Smrg * all copies or substantial portions of the Software. 1316fd1166Smrg * 1416fd1166Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1516fd1166Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1616fd1166Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1716fd1166Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1816fd1166Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1916fd1166Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2016fd1166Smrg * OTHER DEALINGS IN THE SOFTWARE. 2116fd1166Smrg * 2216fd1166Smrg * Except as contained in this notice, the name of the copyright holder(s) 2316fd1166Smrg * and author(s) shall not be used in advertising or otherwise to promote 2416fd1166Smrg * the sale, use or other dealings in this Software without prior written 2516fd1166Smrg * authorization from the copyright holder(s) and author(s). 2616fd1166Smrg */ 2716fd1166Smrg 2816fd1166Smrg/* 2916fd1166Smrg * vmwaremodes.c -- 3016fd1166Smrg * 313bfa90b6Smrg * Provide additional modes for the driver. 3216fd1166Smrg */ 3316fd1166Smrg 343bfa90b6Smrg#ifdef HAVE_CONFIG_H 353bfa90b6Smrg#include "config.h" 363bfa90b6Smrg#endif 3716fd1166Smrg#include "xf86.h" 383bfa90b6Smrg#ifdef HAVE_XORG_SERVER_1_2_0 393bfa90b6Smrg#include <xf86Modes.h> 403bfa90b6Smrg#endif 413bfa90b6Smrg#include "vm_basic_types.h" 423bfa90b6Smrg#include "vmware.h" 430b7217d9Smrg#include "common_compat.h" 4416fd1166Smrg 4516fd1166Smrg#ifndef M_T_DRIVER 4616fd1166Smrg# define M_T_DRIVER 0x40 /* Supplied by the driver (EDID, etc) */ 4716fd1166Smrg#endif 4816fd1166Smrg 4916fd1166Smrg#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER 5016fd1166Smrg#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 5116fd1166Smrg 523bfa90b6Smrg#define VMW_DEFLT_MODE_NAME "vmwlegacy-default-%dx%d" 5316fd1166Smrg 5416fd1166Smrg/* 5516fd1166Smrg *----------------------------------------------------------------------------- 5616fd1166Smrg * 573bfa90b6Smrg * vmwareAddDefaultMode -- 5816fd1166Smrg * 593bfa90b6Smrg * Add a default mode with the current screen dimensions. 6016fd1166Smrg * 6116fd1166Smrg * Results: 623bfa90b6Smrg * The default mode. 6316fd1166Smrg * 6416fd1166Smrg * Side effects: 6516fd1166Smrg * None. 6616fd1166Smrg * 6716fd1166Smrg *----------------------------------------------------------------------------- 6816fd1166Smrg */ 6916fd1166Smrg 7016fd1166Smrgvoid 713bfa90b6SmrgvmwareAddDefaultMode(ScrnInfoPtr pScrn, uint32 dwidth, uint32 dheight) 7216fd1166Smrg{ 733bfa90b6Smrg DisplayModePtr *monitorModes = &pScrn->monitor->Modes; 743bfa90b6Smrg DisplayModePtr modes = NULL; 7516fd1166Smrg 7616fd1166Smrg if (monitorModes == NULL || *monitorModes == NULL) { 773bfa90b6Smrg goto out_err; 7816fd1166Smrg } 7916fd1166Smrg 8016fd1166Smrg#ifdef HAVE_XORG_SERVER_1_2_0 813bfa90b6Smrg if (dwidth && dheight) { 823bfa90b6Smrg MonPtr monitor = pScrn->monitor; 833bfa90b6Smrg DisplayModePtr mode = NULL; 843bfa90b6Smrg DisplayModeRec dynamic = 853bfa90b6Smrg { MODEPREFIX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX }; 863bfa90b6Smrg unsigned dispModeCount = 0; 870b7217d9Smrg CONST_ABI_18_0 char **dispModeList; 883bfa90b6Smrg char *dynModeName; 893bfa90b6Smrg char name[80]; 903bfa90b6Smrg VMWAREPtr pVMWARE = VMWAREPTR(pScrn); 913bfa90b6Smrg 923bfa90b6Smrg /* First, add the default mode name to the display mode 933bfa90b6Smrg * requests. 943bfa90b6Smrg */ 953bfa90b6Smrg 963bfa90b6Smrg snprintf(name, sizeof(name), VMW_DEFLT_MODE_NAME, dwidth, dheight); 973bfa90b6Smrg 983bfa90b6Smrg dynModeName = xnfstrdup(name); 993bfa90b6Smrg if (!dynModeName || !pScrn->display) 1003bfa90b6Smrg goto out_err; 1013bfa90b6Smrg 1023bfa90b6Smrg if (pScrn->display->modes) { 1033bfa90b6Smrg dispModeList = pScrn->display->modes; 1043bfa90b6Smrg while(*dispModeList) 1053bfa90b6Smrg dispModeList++; 10622f7e8e5Smrg dispModeCount = (unsigned)(((size_t)dispModeList - 10722f7e8e5Smrg (size_t)pScrn->display->modes) / 10822f7e8e5Smrg sizeof(*dispModeList)); 1093bfa90b6Smrg } 1103bfa90b6Smrg 1113bfa90b6Smrg dispModeList = xnfcalloc(dispModeCount + 2, sizeof(*dispModeList)); 1123bfa90b6Smrg if (!dispModeList) 1133bfa90b6Smrg goto out_err; 1143bfa90b6Smrg 1153bfa90b6Smrg memcpy(dispModeList, pScrn->display->modes, 1163bfa90b6Smrg dispModeCount * sizeof(*dispModeList)); 1173bfa90b6Smrg dispModeList[dispModeCount] = dynModeName; 1183bfa90b6Smrg pScrn->display->modes = dispModeList; 1193bfa90b6Smrg 1203bfa90b6Smrg /* Then, add the default mode itself. 1213bfa90b6Smrg */ 1223bfa90b6Smrg 1233bfa90b6Smrg dynamic.name = name; 1243bfa90b6Smrg dynamic.HDisplay = dwidth; 1253bfa90b6Smrg dynamic.HSyncStart = dynamic.HDisplay + 1; 1263bfa90b6Smrg dynamic.HSyncEnd = dynamic.HSyncStart + 1; 1273bfa90b6Smrg dynamic.HTotal = dynamic.HSyncEnd * 5 / 4; 1283bfa90b6Smrg dynamic.VDisplay = dheight; 1293bfa90b6Smrg dynamic.VSyncStart = dynamic.VDisplay + 1; 1303bfa90b6Smrg dynamic.VSyncEnd = dynamic.VSyncStart + 1; 1313bfa90b6Smrg dynamic.VTotal = dynamic.VSyncEnd + 1; 1323bfa90b6Smrg if (monitor->nVrefresh > 0) 1333bfa90b6Smrg dynamic.VRefresh = monitor->vrefresh[0].lo; 1343bfa90b6Smrg else 1353bfa90b6Smrg dynamic.VRefresh = 60; 1363bfa90b6Smrg dynamic.Clock = dynamic.VRefresh * dynamic.VTotal * 1373bfa90b6Smrg dynamic.HTotal / 1000; 1383bfa90b6Smrg mode = xf86DuplicateMode(&dynamic); 1393bfa90b6Smrg modes = xf86ModesAdd(modes, mode); 1403bfa90b6Smrg 1413bfa90b6Smrg if (dispModeCount == 0) { 1423bfa90b6Smrg 1433bfa90b6Smrg /* 1443bfa90b6Smrg * Set up a large virtual size, so that we allow also 1453bfa90b6Smrg * setting modes larger than the initial mode. 1463bfa90b6Smrg * 1473bfa90b6Smrg * We might also want to consider the case where 1483bfa90b6Smrg * dispModeCount != 0, but the requested display modes 1493bfa90b6Smrg * are not available. This is sufficient for now. 1503bfa90b6Smrg */ 1513bfa90b6Smrg 1523bfa90b6Smrg if (pScrn->display->virtualX == 0) 1533bfa90b6Smrg pScrn->display->virtualX = pVMWARE->maxWidth; 1543bfa90b6Smrg if (pScrn->display->virtualY == 0) 1553bfa90b6Smrg pScrn->display->virtualY = pVMWARE->maxHeight; 1563bfa90b6Smrg } 15716fd1166Smrg } 15816fd1166Smrg 15916fd1166Smrg *monitorModes = xf86ModesAdd(*monitorModes, modes); 1603bfa90b6Smrg#else 1613bfa90b6Smrg (void) modes; 16216fd1166Smrg#endif 1633bfa90b6Smrg return; 1643bfa90b6Smrg out_err: 1653bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to add default mode."); 16616fd1166Smrg} 167