summaryrefslogtreecommitdiff
path: root/src/vmware.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-03-25 19:17:00 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2011-03-29 09:04:18 +0200
commitcdb04224db69a6b3beb66c99879e20917b8b0fb2 (patch)
tree22364a65c785ace7fdc7236ad86250c0117e0d17 /src/vmware.c
parent9a8f0af8782fd5e9de2d71dfa86fad1d48d52b64 (diff)
vmwlegacy: Fix segfault and setup of initial mode.
The fact that modes were added without names caused segfaults on older X servers. At least up to and including Xserver 1.4. Also, for some reason, at least Xserver 1.4 insists on setting the first mode in the modelist, even if we set another mode as the current one. Work around this by inserting a new mode with the current screen dimensions, and add that modename last to the array of display requested mode names. This means that if none of the previous mode names are found, we will at least find the newly inserted mode. Also, if there are no requested mode names at all, the driver previously chose the largest mode that fit the timings. Now we will, in that case, always select the newly inserted mode and thus not change resolution unless specified. Also add an option to not add this default mode. The option "AddDefaultMode" is true by default. Finally when we restore registers at exit and VT switch, make sure we reprogram the initial width, height and bpp for the next time we start a server. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Diffstat (limited to 'src/vmware.c')
-rw-r--r--src/vmware.c77
1 files changed, 28 insertions, 49 deletions
diff --git a/src/vmware.c b/src/vmware.c
index 795ad08..e04835f 100644
--- a/src/vmware.c
+++ b/src/vmware.c
@@ -217,13 +217,15 @@ static XF86ModuleVersionInfo vmwlegacyVersRec = {
typedef enum {
OPTION_HW_CURSOR,
OPTION_XINERAMA,
- OPTION_STATIC_XINERAMA
+ OPTION_STATIC_XINERAMA,
+ OPTION_DEFAULT_MODE,
} VMWAREOpts;
static const OptionInfoRec VMWAREOptions[] = {
{ OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_XINERAMA, "Xinerama", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
+ { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -608,6 +610,7 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
ClockRange* clockRanges;
IOADDRESS domainIOBase = 0;
uint32 width = 0, height = 0;
+ Bool defaultMode;
#ifndef BUILD_FOR_420
domainIOBase = pScrn->domainIOBase;
@@ -923,6 +926,17 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam = pVMWARE->videoRam / 1024;
pScrn->memPhysBase = pVMWARE->memPhysBase;
+ from = X_DEFAULT;
+ defaultMode = TRUE;
+ if (xf86GetOptValBool(options, OPTION_DEFAULT_MODE, &defaultMode)) {
+ from = X_CONFIG;
+ }
+ width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+ height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Will %sset up a driver mode with dimensions %dx%d.\n",
+ defaultMode ? "" : "not ", width, height);
+
free(options);
{
@@ -950,24 +964,10 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
clockRanges->doubleScanAllowed = FALSE;
clockRanges->ClockMulFactor = 1;
clockRanges->ClockDivFactor = 1;
-
- /* Read the configured registers for an initial mode.
- * This gives the benefit that at initial bootup, we're most likely
- * to have an 800x600 mode and thus we have a reasonable default at
- * power on. Subsequent logouts will use the pre-configured mode from
- * last session which is a more natural thing.
- *
- * But, only if we haven't any modes specified in the config file.
- */
- if (pScrn->display && pScrn->display->modes) {
- width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
- height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
- }
- /*
- * Get the default supported modelines
- */
- vmwareGetSupportedModelines(pScrn, width, height);
+ if (defaultMode) {
+ vmwareAddDefaultMode(pScrn, width, height);
+ }
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
clockRanges, NULL, 256, pVMWARE->maxWidth, 32 * 32,
@@ -986,38 +986,12 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
VMWAREFreeRec(pScrn);
return FALSE;
}
- xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
- /* Walk the mode list and choose one that matches our registers */
- {
- DisplayModePtr modes = pScrn->modes;
- while (modes) {
- if (modes->type != M_T_USERDEF) {
- /* The first mode isn't our specified one, so fallback
- * to a sane default so we don't get a large virtual
- * screen that may be scaled to a very small initial
- * login screen.
- * We read the current SVGA registers, so we'll either
- * end up with a default 800x600 at bootup, or the last
- * virtual autofitted resolution from the previous session.
- */
- width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
- height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
- }
+ pScrn->currentMode = pScrn->modes;
+ pScrn->virtualX = pScrn->modes->HDisplay;
+ pScrn->virtualY = pScrn->modes->VDisplay;
- if (modes->HDisplay == width && modes->VDisplay == height)
- break;
-
- modes = modes->next;
-
- if (modes == pScrn->modes)
- break;
- }
-
- pScrn->currentMode = modes;
- pScrn->virtualX = modes->HDisplay;
- pScrn->virtualY = modes->VDisplay;
- }
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
@@ -1153,7 +1127,12 @@ VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg)
vmwareReg->svga_reg_cursor_on);
}
} else {
- vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
+ vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+ vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+ vmwareReg->svga_reg_bits_per_pixel);
+ vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
}
}