summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/vmware.c52
-rw-r--r--src/vmware.h4
-rw-r--r--src/vmwaremodes.c33
3 files changed, 84 insertions, 5 deletions
diff --git a/src/vmware.c b/src/vmware.c
index 3177138..795ad08 100644
--- a/src/vmware.c
+++ b/src/vmware.c
@@ -607,6 +607,7 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
int i;
ClockRange* clockRanges;
IOADDRESS domainIOBase = 0;
+ uint32 width = 0, height = 0;
#ifndef BUILD_FOR_420
domainIOBase = pScrn->domainIOBase;
@@ -950,17 +951,31 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
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->monitor->Modes);
+ vmwareGetSupportedModelines(pScrn, width, height);
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
clockRanges, NULL, 256, pVMWARE->maxWidth, 32 * 32,
128, pVMWARE->maxHeight,
pScrn->display->virtualX, pScrn->display->virtualY,
pVMWARE->videoRam,
- LOOKUP_BEST_REFRESH);
+ LOOKUP_BEST_REFRESH | LOOKUP_OPTIONAL_TOLERANCES);
+
if (i == -1) {
VMWAREFreeRec(pScrn);
return FALSE;
@@ -972,7 +987,38 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
- pScrn->currentMode = pScrn->modes;
+
+ /* 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);
+ }
+
+ 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;
+ }
+
xf86PrintModes(pScrn);
xf86SetDpi(pScrn, 0, 0);
if (!xf86LoadSubModule(pScrn, "fb") ||
diff --git a/src/vmware.h b/src/vmware.h
index 9216dcd..3253a64 100644
--- a/src/vmware.h
+++ b/src/vmware.h
@@ -314,6 +314,8 @@ void vmwareCheckVideoSanity(
/* vmwaremode.c */
void vmwareGetSupportedModelines(
- DisplayModePtr *monitorModes
+ ScrnInfoPtr pScrn,
+ uint32 dwidth,
+ uint32 dheight
);
#endif
diff --git a/src/vmwaremodes.c b/src/vmwaremodes.c
index 2f1e5b4..ceeedf6 100644
--- a/src/vmwaremodes.c
+++ b/src/vmwaremodes.c
@@ -42,6 +42,7 @@
#ifdef HAVE_XORG_SERVER_1_2_0
#include <xf86Modes.h>
#endif
+#include "vm_basic_types.h"
#ifndef M_T_DRIVER
# define M_T_DRIVER 0x40 /* Supplied by the driver (EDID, etc) */
@@ -109,9 +110,13 @@ static DisplayModeRec VMwareModes[] = {
*/
void
-vmwareGetSupportedModelines(DisplayModePtr *monitorModes)
+vmwareGetSupportedModelines(ScrnInfoPtr pScrn, uint32 dwidth, uint32 dheight)
{
+ MonPtr monitor = pScrn->monitor;
+ DisplayModePtr *monitorModes = &pScrn->monitor->Modes;
DisplayModePtr modes = NULL, mode = NULL;
+ DisplayModeRec dynamic =
+ { MODEPREFIX, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX };
int i = 0;
if (monitorModes == NULL || *monitorModes == NULL) {
@@ -124,6 +129,32 @@ vmwareGetSupportedModelines(DisplayModePtr *monitorModes)
modes = xf86ModesAdd(modes, mode);
}
+ /*
+ * Let's add a mode of current SVGA register values and so we can
+ * match against this for subsequent login.
+ */
+ if (dwidth && dheight) {
+ dynamic.HDisplay = dwidth;
+ dynamic.HSyncStart = dynamic.HDisplay + 1;
+ dynamic.HSyncEnd = dynamic.HSyncStart + 1;
+ dynamic.HTotal = dynamic.HSyncEnd * 5 / 4;
+ if (monitor->nHsync > 0)
+ dynamic.Clock = dynamic.HTotal * monitor->hsync[0].lo;
+ else
+ dynamic.Clock = 75000;
+ dynamic.VDisplay = dheight;
+ dynamic.VSyncStart = dynamic.VDisplay + 1;
+ dynamic.VSyncEnd = dynamic.VSyncStart + 1;
+ dynamic.VTotal = dynamic.VSyncEnd + 1;
+ if (monitor->nVrefresh > 0)
+ dynamic.VRefresh = monitor->vrefresh[0].lo;
+ else
+ dynamic.VRefresh = 60000;
+
+ mode = xf86DuplicateMode(&dynamic);
+ modes = xf86ModesAdd(modes, mode);
+ }
+
*monitorModes = xf86ModesAdd(*monitorModes, modes);
#endif
}