vmwaremodes.c revision 0b7217d9
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