summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/kdrive/vesa/vesa.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/kdrive/vesa/vesa.c')
-rw-r--r--xc/programs/Xserver/hw/kdrive/vesa/vesa.c988
1 files changed, 775 insertions, 213 deletions
diff --git a/xc/programs/Xserver/hw/kdrive/vesa/vesa.c b/xc/programs/Xserver/hw/kdrive/vesa/vesa.c
index 90f4215a1..59c4ceeab 100644
--- a/xc/programs/Xserver/hw/kdrive/vesa/vesa.c
+++ b/xc/programs/Xserver/hw/kdrive/vesa/vesa.c
@@ -19,9 +19,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.9 2000/11/29 08:42:25 keithp Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.16 2001/07/24 19:06:04 keithp Exp $ */
#include "vesa.h"
+#ifdef RANDR
+#include <randrstr.h>
+#endif
int vesa_video_mode = 0;
Bool vesa_force_mode = FALSE;
@@ -29,14 +32,12 @@ Bool vesa_swap_rgb = FALSE;
Bool vesa_shadow = FALSE;
Bool vesa_linear_fb = TRUE;
Bool vesa_restore = FALSE;
-Bool vesa_rotate = FALSE;
Bool vesa_verbose = FALSE;
#define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver)
-#define ScreenRotated(scr) (VesaPriv(scr)->rotate)
-#define vesaWidth(scr,vmib) (ScreenRotated(scr) ? vmib->YResolution : vmib->XResolution)
-#define vesaHeight(scr,vmib) (ScreenRotated(scr) ? vmib->XResolution : vmib->YResolution)
+#define vesaWidth(scr,vmib) ((vmib)->XResolution)
+#define vesaHeight(scr,vmib) ((vmib)->YResolution)
static Bool
vesaModeSupportable (VesaModePtr mode, Bool complain)
@@ -368,13 +369,8 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
VesaCardPrivPtr priv = screen->card->driver;
VesaModePtr mode;
Pixel allbits;
- int depth;
- int bpp, fbbpp;
screen->driver = pscr;
- pscr->rotate = FALSE;
- if (screen->width < screen->height)
- pscr->rotate = TRUE;
if (!screen->width || !screen->height)
{
@@ -388,70 +384,40 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
ErrorF ("Mode requested %dx%dx%d\n",
screen->width, screen->height, screen->fb[0].depth);
- pscr->mode = vesaSelectMode (screen);
+ mode = vesaSelectMode (screen);
- if (!pscr->mode)
+ if (!mode)
{
if (vesa_verbose)
ErrorF ("No selectable mode\n");
return FALSE;
}
+ pscr->mode = *mode;
if (vesa_verbose)
{
ErrorF ("\t");
- vesaReportMode (pscr->mode);
+ vesaReportMode (&pscr->mode);
}
+ pscr->rotate = screen->rotation;
pscr->shadow = vesa_shadow;
pscr->origDepth = screen->fb[0].depth;
- if (vesa_linear_fb)
- pscr->mapping = VESA_LINEAR;
- else
- pscr->mapping = VESA_WINDOWED;
-
- mode = pscr->mode;
+ pscr->layerKind = LAYER_FB;
- depth = vesaDepth (mode);
- bpp = mode->BitsPerPixel;
-
- if (bpp > 24)
- bpp = 32;
- else if (bpp > 16)
- bpp = 24;
- else if (bpp > 8)
- bpp = 16;
- else if (bpp > 4)
- bpp = 8;
- else if (bpp > 1)
- bpp = 4;
- else
- bpp = 1;
- fbbpp = bpp;
-
- switch (mode->MemoryModel) {
+ /*
+ * Compute visual support for the selected depth
+ */
+ switch (pscr->mode.MemoryModel) {
case MEMORY_DIRECT:
/* TrueColor or DirectColor */
screen->fb[0].visuals = (1 << TrueColor);
screen->fb[0].redMask =
- FbStipMask(mode->RedFieldPosition, mode->RedMaskSize);
+ FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize);
screen->fb[0].greenMask =
- FbStipMask(mode->GreenFieldPosition, mode->GreenMaskSize);
+ FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize);
screen->fb[0].blueMask =
- FbStipMask(mode->BlueFieldPosition, mode->BlueMaskSize);
- allbits =
- screen->fb[0].redMask |
- screen->fb[0].greenMask |
- screen->fb[0].blueMask;
- depth = 32;
- while (depth && !(allbits & (1 << (depth - 1))))
- depth--;
- if (vesa_verbose)
- ErrorF ("\tTrue Color bpp %d depth %d red 0x%x green 0x%x blue 0x%x\n",
- bpp, depth,
- screen->fb[0].redMask,
- screen->fb[0].greenMask,
- screen->fb[0].blueMask);
+ FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize);
break;
case MEMORY_PSEUDO:
/* PseudoColor */
@@ -464,98 +430,25 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
- if (vesa_verbose)
- ErrorF ("\tPseudo Color bpp %d depth %d\n",
- bpp, depth);
break;
case MEMORY_PLANAR:
/* 4 plane planar */
- if (mode->ModeAttributes & MODE_COLOUR)
+ if (pscr->mode.ModeAttributes & MODE_COLOUR)
screen->fb[0].visuals = (1 << StaticColor);
else
screen->fb[0].visuals = (1 << StaticGray);
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
- if (bpp == 4)
- {
- bpp = screen->fb[0].bitsPerPixel;
- if (bpp != 8)
- bpp = 4;
- depth = bpp;
- }
- if (bpp == 1)
- {
- pscr->mapping = VESA_MONO;
- if (vesa_verbose)
- ErrorF ("\tMonochrome\n");
- }
- else
- {
- pscr->mapping = VESA_PLANAR;
- if (vesa_verbose)
- ErrorF ("\tStatic color bpp %d depth %d\n",
- bpp, depth);
- }
- pscr->rotate = FALSE;
break;
default:
ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
- mode->MemoryModel);
+ pscr->mode.MemoryModel);
return FALSE;
}
-
- screen->width = vesaWidth(screen, mode);
- screen->height = vesaHeight(screen, mode);
- screen->fb[0].depth = depth;
- screen->fb[0].bitsPerPixel = bpp;
- screen->fb[0].byteStride = mode->BytesPerScanLine;
- screen->fb[0].pixelStride = ((mode->BytesPerScanLine * 8) / fbbpp);
-
- if (pscr->mapping == VESA_LINEAR && !(mode->ModeAttributes & MODE_LINEAR))
- pscr->mapping = VESA_WINDOWED;
-
- if (pscr->rotate)
- pscr->shadow = TRUE;
-
- switch (pscr->mapping) {
- case VESA_MONO:
- pscr->shadow = TRUE;
- /* fall through */
- case VESA_LINEAR:
- if (mode->vbe)
- pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
- pscr->mode->mode,
- &pscr->fb_size);
- else
- pscr->fb = VgaMapFramebuffer (priv->vi,
- pscr->mode->mode,
- &pscr->fb_size);
- break;
- case VESA_WINDOWED:
- pscr->fb = NULL;
- pscr->shadow = TRUE;
- break;
- case VESA_PLANAR:
- pscr->fb = NULL;
- pscr->shadow = TRUE;
- break;
- }
-
screen->rate = 72;
- screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
- if (pscr->rotate)
- screen->softCursor = TRUE;
-
- if (pscr->shadow)
- return KdShadowScreenInit (screen);
-
- if (vesa_verbose)
- ErrorF ("Mode selected %dx%dx%d\n",
- screen->width, screen->height, screen->fb[0].depth);
-
- return TRUE;
+ return vesaMapFramebuffer (screen);
}
Bool
@@ -588,19 +481,19 @@ vesaSetWindowPlanar(ScreenPtr pScreen,
plane = offset & 3;
VgaSetWritePlaneMask (priv->vi, (1 << plane));
offset = offset >> 2;
- if (pscr->mode->vbe)
+ if (pscr->mode.vbe)
{
base = VbeSetWindow (priv->vi,
priv->vbeInfo,
- pscr->mode->BytesPerScanLine * row + offset,
+ pscr->mode.BytesPerScanLine * row + offset,
mode,
&winSize);
}
else
{
base = VgaSetWindow (priv->vi,
- pscr->mode->mode,
- pscr->mode->BytesPerScanLine * row + offset,
+ pscr->mode.mode,
+ pscr->mode.BytesPerScanLine * row + offset,
mode,
&winSize);
}
@@ -619,8 +512,8 @@ vesaSetWindowLinear (ScreenPtr pScreen,
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
- *size = pscr->mode->BytesPerScanLine;
- return (CARD8 *) pscr->fb + row * pscr->mode->BytesPerScanLine + offset;
+ *size = pscr->mode.BytesPerScanLine;
+ return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset;
}
void *
@@ -636,19 +529,19 @@ vesaSetWindowWindowed (ScreenPtr pScreen,
int winSize;
void *base;
- if (pscr->mode->vbe)
+ if (pscr->mode.vbe)
{
base = VbeSetWindow (priv->vi,
priv->vbeInfo,
- pscr->mode->BytesPerScanLine * row + offset,
+ pscr->mode.BytesPerScanLine * row + offset,
mode,
&winSize);
}
else
{
base = VgaSetWindow (priv->vi,
- pscr->mode->mode,
- pscr->mode->BytesPerScanLine * row + offset,
+ pscr->mode.mode,
+ pscr->mode.BytesPerScanLine * row + offset,
mode,
&winSize);
}
@@ -661,7 +554,8 @@ vesaWindowPlanar (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
- CARD32 *size)
+ CARD32 *size,
+ void *closure)
{
KdScreenPriv(pScreen);
@@ -675,7 +569,8 @@ vesaWindowLinear (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
- CARD32 *size)
+ CARD32 *size,
+ void *closure)
{
KdScreenPriv(pScreen);
@@ -689,7 +584,8 @@ vesaWindowWindowed (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
- CARD32 *size)
+ CARD32 *size,
+ void *closure)
{
KdScreenPriv(pScreen);
@@ -709,7 +605,8 @@ vesaWindowCga (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
- CARD32 *size)
+ CARD32 *size,
+ void *closure)
{
KdScreenPriv(pScreen);
VesaCardPrivPtr priv = pScreenPriv->card->driver;
@@ -718,16 +615,17 @@ vesaWindowCga (ScreenPtr pScreen,
if (!pScreenPriv->enabled)
return 0;
- *size = pscr->mode->BytesPerScanLine;
- line = ((row & 1) << 13) + (row >> 1) * pscr->mode->BytesPerScanLine;
+ *size = pscr->mode.BytesPerScanLine;
+ line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine;
return (CARD8 *) pscr->fb + line + offset;
}
void
-vesaUpdateMono (ScreenPtr pScreen,
- PixmapPtr pShadow,
- RegionPtr damage)
+vesaUpdateMono (ScreenPtr pScreen,
+ shadowBufPtr pBuf)
{
+ RegionPtr damage = &pBuf->damage;
+ PixmapPtr pShadow = pBuf->pPixmap;
shadowScrPriv(pScreen);
int nbox = REGION_NUM_RECTS (damage);
BoxPtr pbox = REGION_RECTS (damage);
@@ -736,6 +634,7 @@ vesaUpdateMono (ScreenPtr pScreen,
FbStride shaStride;
int scrBase, scrLine, scr;
int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
int x, y, w, h, width;
int i;
FbBits *winBase, *winLine, *win;
@@ -743,7 +642,7 @@ vesaUpdateMono (ScreenPtr pScreen,
FbBits bits;
int plane;
- fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp);
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
while (nbox--)
{
x = pbox->x1 * shaBpp;
@@ -769,11 +668,12 @@ vesaUpdateMono (ScreenPtr pScreen,
i = scrBase + winSize - scr;
if (i <= 0 || scr < scrBase)
{
- winBase = (FbBits *) (*pScrPriv->window) (pScreen,
- y,
- scr * sizeof (FbBits),
- SHADOW_WINDOW_WRITE,
- &winSize);
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
if(!winBase)
return;
scrBase = scr;
@@ -823,6 +723,7 @@ vesaCreateColormap16 (ColormapPtr pmap)
{
int i, j;
+ if (pmap->pVisual->ColormapEntries == 16)
for (i = 0; i < pmap->pVisual->ColormapEntries; i++)
{
j = i & 0xf;
@@ -833,24 +734,89 @@ vesaCreateColormap16 (ColormapPtr pmap)
return TRUE;
}
+void
+vesaConfigureScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
-Bool
-vesaInitScreen(ScreenPtr pScreen)
+ KdMouseMatrix m;
+
+ if (pscr->mapping == VESA_PLANAR || pscr->mapping == VESA_MONO)
+ {
+ pscr->shadow = TRUE;
+ pscr->rotate = 0;
+ }
+ else switch (pscr->rotate) {
+ case 0:
+ pScreen->width = pscr->mode.XResolution;
+ pScreen->height = pscr->mode.YResolution;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ if (pscr->mapping == VESA_WINDOWED)
+ pscr->shadow = TRUE;
+ else
+ pscr->shadow = vesa_shadow;
+ m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0;
+ m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0;
+ break;
+ case 90:
+ pScreen->width = pscr->mode.YResolution;
+ pScreen->height = pscr->mode.XResolution;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ pscr->shadow = TRUE;
+ m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = pscr->mode.YResolution - 1;
+ m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0;
+ break;
+ case 180:
+ pScreen->width = pscr->mode.XResolution;
+ pScreen->height = pscr->mode.YResolution;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ pscr->shadow = TRUE;
+ m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = pscr->mode.XResolution - 1;
+ m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = pscr->mode.YResolution - 1;
+ break;
+ case 270:
+ pScreen->width = pscr->mode.YResolution;
+ pScreen->height = pscr->mode.XResolution;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ pscr->shadow = TRUE;
+ m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0;
+ m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = pscr->mode.XResolution - 1;
+ break;
+ }
+ KdSetMouseMatrix (&m);
+}
+
+LayerPtr
+vesaLayerCreate (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ LayerPtr pLayer;
ShadowUpdateProc update;
ShadowWindowProc window;
-
+ PixmapPtr pPixmap;
+ int kind;
+
if (pscr->shadow)
{
+ if (pscr->rotate)
+ update = shadowUpdateRotatePacked;
+ else
+ update = shadowUpdatePacked;
switch (pscr->mapping) {
case VESA_LINEAR:
- update = shadowUpdatePacked;
window = vesaWindowLinear;
break;
case VESA_WINDOWED:
- update = shadowUpdatePacked;
window = vesaWindowWindowed;
break;
case VESA_PLANAR:
@@ -860,68 +826,653 @@ vesaInitScreen(ScreenPtr pScreen)
else
update = shadowUpdatePlanar4;
window = vesaWindowPlanar;
- pscr->rotate = FALSE;
break;
case VESA_MONO:
update = vesaUpdateMono;
- if (pscr->mode->mode < 8)
+ if (pscr->mode.mode < 8)
window = vesaWindowCga;
else
window = vesaWindowLinear;
- pscr->rotate = FALSE;
break;
}
- if (pscr->rotate)
+
+ kind = LAYER_SHADOW;
+ pPixmap = 0;
+ }
+ else
+ {
+ kind = pscr->layerKind;
+ pPixmap = LAYER_SCREEN_PIXMAP;
+ update = 0;
+ window = 0;
+ }
+
+ if (vesa_verbose)
+ ErrorF ("Mode selected %dx%dx%d\n",
+ pScreen->width, pScreen->height, screen->fb[0].depth);
+
+ return LayerCreate (pScreen, kind, screen->fb[0].depth,
+ pPixmap, update, window, pscr->rotate, 0);
+}
+
+Bool
+vesaMapFramebuffer (KdScreenInfo *screen)
+{
+ VesaCardPrivPtr priv = screen->card->driver;
+ VesaScreenPrivPtr pscr = screen->driver;
+ int depth, bpp, fbbpp;
+ Pixel allbits;
+
+ if (vesa_linear_fb)
+ pscr->mapping = VESA_LINEAR;
+ else
+ pscr->mapping = VESA_WINDOWED;
+
+ depth = vesaDepth (&pscr->mode);
+ bpp = pscr->mode.BitsPerPixel;
+
+ if (bpp > 24)
+ bpp = 32;
+ else if (bpp > 16)
+ bpp = 24;
+ else if (bpp > 8)
+ bpp = 16;
+ else if (bpp > 4)
+ bpp = 8;
+ else if (bpp > 1)
+ bpp = 4;
+ else
+ bpp = 1;
+ fbbpp = bpp;
+
+ switch (pscr->mode.MemoryModel) {
+ case MEMORY_DIRECT:
+ allbits = (screen->fb[0].redMask |
+ screen->fb[0].greenMask |
+ screen->fb[0].blueMask);
+ depth = 32;
+ while (depth && !(allbits & (1 << (depth - 1))))
+ depth--;
+ if (vesa_verbose)
+ ErrorF ("\tTrue Color red 0x%x green 0x%x blue 0x%x\n",
+ bpp, depth,
+ screen->fb[0].redMask,
+ screen->fb[0].greenMask,
+ screen->fb[0].blueMask);
+ break;
+ case MEMORY_PSEUDO:
+ if (vesa_verbose)
+ ErrorF ("\tPseudo Color bpp %d depth %d\n",
+ bpp, depth);
+ break;
+ case MEMORY_PLANAR:
+ if (bpp == 4)
+ {
+ bpp = screen->fb[0].bitsPerPixel;
+ if (bpp != 8)
+ bpp = 4;
+ depth = bpp;
+ }
+ if (bpp == 1)
+ {
+ pscr->mapping = VESA_MONO;
+ if (vesa_verbose)
+ ErrorF ("\tMonochrome\n");
+ }
+ else
+ {
+ pscr->mapping = VESA_PLANAR;
+ if (vesa_verbose)
+ ErrorF ("\tStatic color bpp %d depth %d\n",
+ bpp, depth);
+ }
+ pscr->rotate = 0;
+ break;
+ default:
+ return 0;
+ }
+
+ switch (fbbpp) {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ pscr->rotate = 0;
+ }
+
+ screen->width = pscr->mode.XResolution;
+ screen->height = pscr->mode.YResolution;
+ screen->fb[0].depth = depth;
+ screen->fb[0].bitsPerPixel = bpp;
+ screen->fb[0].byteStride = pscr->mode.BytesPerScanLine;
+ screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) / fbbpp);
+
+ if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR))
+ pscr->mapping = VESA_WINDOWED;
+
+ screen->softCursor = TRUE;
+
+ switch (pscr->mapping) {
+ case VESA_MONO:
+ case VESA_LINEAR:
+ if (pscr->mode.vbe)
+ pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
+ pscr->mode.mode,
+ &pscr->fb_size);
+ else
+ pscr->fb = VgaMapFramebuffer (priv->vi,
+ pscr->mode.mode,
+ &pscr->fb_size);
+ if (!pscr->fb)
+ return FALSE;
+ break;
+ case VESA_WINDOWED:
+ pscr->fb = NULL;
+ break;
+ case VESA_PLANAR:
+ pscr->fb = NULL;
+ break;
+ }
+ screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
+ return TRUE;
+}
+
+void
+vesaUnmapFramebuffer (KdScreenInfo *screen)
+{
+ VesaCardPrivPtr priv = screen->card->driver;
+ VesaScreenPrivPtr pscr = screen->driver;
+
+ if (pscr->fb)
+ {
+ if (pscr->mode.vbe)
+ VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb);
+ else
+ VgaUnmapFramebuffer (priv->vi);
+ pscr->fb = 0;
+ }
+}
+
+#ifdef RANDR
+Bool
+vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ VesaModePtr modes, mode;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ int nmode;
+ int n;
+ RRVisualGroupPtr pVisualGroup;
+ RRGroupOfVisualGroupPtr pGroupOfVisualGroup;
+ RRScreenSizePtr pSize;
+
+ *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270;
+ /*
+ * Get mode information from BIOS -- every time in case
+ * something changes, like an external monitor is plugged in
+ */
+ modes = vesaGetModes (priv->vi, &nmode);
+ if (!modes)
+ return FALSE;
+ if (priv->modes)
+ xfree (priv->modes);
+ priv->modes = modes;
+ priv->nmode = nmode;
+ /*
+ * XXX Create a single set of visual sets that has all of the visuals
+ * for the root depth
+ */
+ for (n = 0; n < pScreen->numDepths; n++)
+ if (pScreen->allowedDepths[n].numVids)
+ break;
+ if (n == pScreen->numDepths)
+ return FALSE;
+
+ pVisualGroup = RRCreateVisualGroup (pScreen);
+ if (!pVisualGroup)
+ return FALSE;
+
+ if (!RRAddDepthToVisualGroup (pScreen,
+ pVisualGroup,
+ &pScreen->allowedDepths[n]))
+ {
+ RRDestroyVisualGroup (pScreen, pVisualGroup);
+ return FALSE;
+ }
+ pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup);
+ if (!pVisualGroup)
+ return FALSE;
+
+ pGroupOfVisualGroup = RRCreateGroupOfVisualGroup (pScreen);
+
+ if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen,
+ pGroupOfVisualGroup,
+ pVisualGroup))
+ {
+ RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
+ /* pVisualGroup left until screen closed */
+ return FALSE;
+ }
+
+ pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen, pGroupOfVisualGroup);
+ if (!pGroupOfVisualGroup)
+ return FALSE;
+
+ for (n = 0; n < nmode; n++)
+ {
+ mode = &priv->modes[n];
+ if (vesaModeSupported (priv, mode, FALSE))
{
- switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
- case 8:
- update = shadowUpdateRotate8; break;
- case 16:
- update = shadowUpdateRotate16; break;
- case 32:
- update = shadowUpdateRotate32; break;
+ /*
+ * XXX limit reported modes to those matching the current
+ * format
+ */
+ if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
+ mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
+ mode->MemoryModel == pscr->mode.MemoryModel &&
+ mode->RedMaskSize == pscr->mode.RedMaskSize &&
+ mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
+ mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
+ mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
+ mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
+ mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
+ {
+ int width, height, width_mm, height_mm;
+ if (screen->rotation == 0 || screen->rotation == 180)
+ {
+ width = mode->XResolution;
+ height = mode->YResolution;
+ width_mm = screen->width_mm;
+ height_mm = screen->height_mm;
+ }
+ else
+ {
+ width = mode->YResolution;
+ height = mode->XResolution;
+ width_mm = screen->height_mm;
+ height_mm = screen->width_mm;
+ }
+ pSize = RRRegisterSize (pScreen,
+ width, height,
+ width_mm, height_mm,
+ pGroupOfVisualGroup);
+ if (mode->XResolution == screen->width &&
+ mode->YResolution == screen->height)
+ {
+ int rotate = pscr->rotate - screen->rotation;
+ int rot;
+ if (rotate < 0)
+ rotate += 360;
+ switch (rotate) {
+ case 0: rot = RR_Rotate_0; break;
+ case 90: rot = RR_Rotate_90; break;
+ case 180: rot = RR_Rotate_180; break;
+ case 270: rot = RR_Rotate_270; break;
+ }
+ RRSetCurrentConfig (pScreen, rot, pSize,
+ pVisualGroup);
+ }
}
}
+ }
+ return TRUE;
+}
+
+int
+vesaLayerAdd (WindowPtr pWin, pointer value)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ if (!LayerWindowAdd (pScreen, pLayer, pWin))
+ return WT_STOPWALKING;
+
+ return WT_WALKCHILDREN;
+}
+
+int
+vesaLayerRemove (WindowPtr pWin, pointer value)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ LayerWindowRemove (pScreen, pLayer, pWin);
+
+ return WT_WALKCHILDREN;
+}
+
+Bool
+vesaRandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ RRScreenSizePtr pSize,
+ RRVisualGroupPtr pVisualGroup)
+{
+ KdScreenPriv(pScreen);
+ VesaModePtr mode;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ int n;
+ Bool wasEnabled = pScreenPriv->enabled;
+ Bool ret = FALSE;
+ VesaScreenPrivRec oldscr;
+ int oldwidth;
+ int oldheight;
+ int oldmmwidth;
+ int oldmmheight;
+ LayerPtr pNewLayer;
+ int newwidth, newheight;
+
+ if (screen->rotation == 0 || screen->rotation == 180)
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+ for (n = 0; n < priv->nmode; n++)
+ {
+ mode = &priv->modes[n];
+ if (vesaModeSupported (priv, mode, FALSE))
+ {
+ /*
+ * XXX all we have to match is the size
+ */
+ if (mode->XResolution == newwidth &&
+ mode->YResolution == newheight &&
+ mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
+ mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
+ mode->RedMaskSize == pscr->mode.RedMaskSize &&
+ mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
+ mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
+ mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
+ mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
+ mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
+ break;
+ }
+ }
+ if (n == priv->nmode)
+ goto bail0;
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ if (mode->mode != pscr->mode.mode)
+ {
+ ret = vesaSetMode (pScreen, mode);
+ if (!ret)
+ goto bail1;
+ }
+
+ oldscr = *pscr;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+
+ /*
+ * Set new configuration
+ */
+
+ pscr->mode = *mode;
+ switch (rotation) {
+ case RR_Rotate_0: pscr->rotate = 0; break;
+ case RR_Rotate_90: pscr->rotate = 90; break;
+ case RR_Rotate_180: pscr->rotate = 180; break;
+ case RR_Rotate_270: pscr->rotate = 270; break;
+ }
+
+ pscr->rotate += screen->rotation;
+ if (pscr->rotate >= 360)
+ pscr->rotate -= 360;
+
+ /*
+ * Can't rotate some formats
+ */
+ switch (screen->fb[0].bitsPerPixel) {
+ case 8:
+ case 16:
+ case 32:
+ break;
+ default:
+ if (pscr->rotate)
+ goto bail2;
+ break;
+ }
+
+ vesaUnmapFramebuffer (screen);
+ if (!vesaMapFramebuffer (screen))
+ goto bail3;
+
+#if 0
+ /*
+ * XXX can't switch depths yet
+ */
+ screen->fb[0].depth = depth;
+ screen->fb[0].bitsPerPixel = bpp;
+#endif
+ screen->fb[0].byteStride = mode->BytesPerScanLine;
+ screen->fb[0].pixelStride = ((mode->BytesPerScanLine * 8) / screen->fb[0].bitsPerPixel);
+
+ /*
+ * Compute screen geometry
+ */
+ vesaConfigureScreen (pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ if (!pscr->shadow)
+ {
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb[0].depth,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[0].byteStride,
+ screen->fb[0].frameBuffer);
+ }
- return KdShadowInitScreen (pScreen, update, window);
+ /*
+ * Create the layer
+ */
+ pNewLayer = vesaLayerCreate (pScreen);
+ if (!pNewLayer)
+ goto bail4;
+
+ if (WalkTree (pScreen, vesaLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING)
+ goto bail5;
+
+ WalkTree (pScreen, vesaLayerRemove, (pointer) pscr->pLayer);
+ LayerDestroy (pScreen, pscr->pLayer);
+
+ pscr->pLayer = pNewLayer;
+
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+bail5:
+ WalkTree (pScreen, vesaLayerRemove, (pointer) pNewLayer);
+ LayerDestroy (pScreen, pNewLayer);
+bail4:
+ vesaUnmapFramebuffer (screen);
+ *pscr = oldscr;
+ (void) vesaMapFramebuffer (screen);
+
+bail3:
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+bail2:
+ *pscr = oldscr;
+
+ /*
+ * Set frame buffer mapping
+ */
+ if (!pscr->shadow)
+ {
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb[0].depth,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[0].byteStride,
+ screen->fb[0].frameBuffer);
}
+
+ (void) vesaSetMode (pScreen, &pscr->mode);
+
+bail1:
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+bail0:
+
+ return FALSE;
+}
+
+Bool
+vesaRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = vesaRandRGetInfo;
+ pScrPriv->rrSetConfig = vesaRandRSetConfig;
return TRUE;
}
+#endif
Bool
-vesaEnable(ScreenPtr pScreen)
+vesaInitScreen(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+
+ if (!LayerStartInit (pScreen))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+vesaFinishInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+
+ pscr->layerKind = LayerNewKind (pScreen);
+
+ if (!LayerFinishInit (pScreen))
+ return FALSE;
+
+ vesaConfigureScreen (pScreen);
+
+ pscr->pLayer = vesaLayerCreate (pScreen);
+ if (!pscr->pLayer)
+ return FALSE;
+
+#ifdef RANDR
+ if (!vesaRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+vesaSetMode (ScreenPtr pScreen,
+ VesaModePtr mode)
{
KdScreenPriv(pScreen);
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
int code;
- int i;
- CARD32 size;
- char *p;
- KdMouseMatrix m;
-
- if (pscr->mode->vbe)
+
+ if (mode->vbe)
{
if (vesa_verbose)
- ErrorF ("Enable VBE mode 0x%x\n", pscr->mode->mode);
- code = VbeSetMode(priv->vi, priv->vbeInfo, pscr->mode->mode,
- pscr->mapping == VESA_LINEAR);
+ ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
+ code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode,
+ pscr->mapping == VESA_LINEAR,
+ mode->MemoryModel == MEMORY_DIRECT);
}
else
{
if (vesa_verbose)
- ErrorF ("Enable BIOS mode 0x%x\n", pscr->mode->mode);
- code = VgaSetMode (priv->vi, pscr->mode->mode);
+ ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
+ code = VgaSetMode (priv->vi, mode->mode);
}
if(code < 0)
return FALSE;
+ return TRUE;
+}
+
+Bool
+vesaEnable(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ VesaCardPrivPtr priv = pScreenPriv->card->driver;
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int code;
+ int i;
+ CARD32 size;
+ char *p;
+
+ if (!vesaSetMode (pScreen, &pscr->mode))
+ return FALSE;
+
switch (pscr->mapping) {
case VESA_MONO:
VgaSetWritePlaneMask (priv->vi, 0x1);
case VESA_LINEAR:
+ /*
+ * Remap the frame buffer if necessary
+ */
+ if (!pscr->fb)
+ {
+ if (pscr->mode.vbe)
+ pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
+ pscr->mode.mode,
+ &pscr->fb_size);
+ else
+ pscr->fb = VgaMapFramebuffer (priv->vi,
+ pscr->mode.mode,
+ &pscr->fb_size);
+ if (!pscr->fb)
+ return FALSE;
+ screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
+ /*
+ * Set frame buffer mapping
+ */
+ if (!pscr->shadow)
+ {
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb[0].depth,
+ screen->fb[0].bitsPerPixel,
+ screen->fb[0].byteStride,
+ screen->fb[0].frameBuffer);
+ }
+ }
memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
break;
case VESA_WINDOWED:
@@ -947,17 +1498,6 @@ vesaEnable(ScreenPtr pScreen)
}
break;
}
- if (pscr->rotate)
- {
- m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0;
- m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = pScreen->height - 1;
- }
- else
- {
- m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0;
- m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0;
- }
- KdSetMouseMatrix (&m);
return TRUE;
}
@@ -965,8 +1505,9 @@ void
vesaDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
- VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
+ VesaScreenPrivPtr pscr = screen->driver;
int i=0;
CARD32 size;
char *p;
@@ -999,6 +1540,7 @@ vesaDisable(ScreenPtr pScreen)
}
break;
}
+ vesaUnmapFramebuffer (screen);
}
void
@@ -1035,7 +1577,7 @@ vesaRestore(KdCardInfo *card)
{
if (vesa_verbose)
ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode);
- VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0);
+ VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0);
}
else
{
@@ -1052,6 +1594,8 @@ vesaCardFini(KdCardInfo *card)
if (priv->vbeInfo)
VbeCleanup (priv->vi, priv->vbeInfo);
+ if (priv->modes)
+ xfree (priv->modes);
Vm86Cleanup(priv->vi);
}
@@ -1061,16 +1605,7 @@ vesaScreenFini(KdScreenInfo *screen)
VesaScreenPrivPtr pscr = screen->driver;
VesaCardPrivPtr priv = screen->card->driver;
- if (pscr->fb)
- {
- if (pscr->mode->vbe)
- VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode->mode, pscr->fb);
- else
- VgaUnmapFramebuffer (priv->vi);
- }
-
- if (pscr->shadow)
- KdShadowScreenFini (screen);
+ vesaUnmapFramebuffer (screen);
screen->fb[0].depth = pscr->origDepth;
}
@@ -1110,8 +1645,9 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
int p;
- CARD8 scratch[4];
+ CARD8 *scratch;
int red, green, blue;
+ int min, max;
if (vesa_swap_rgb)
{
@@ -1126,13 +1662,20 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
blue = 2;
}
+ min = 256;
+ max = 0;
while (n--)
{
+ p = pdefs->pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+ scratch = priv->cmap + (p * 4);
scratch[red] = pdefs->red >> 8;
scratch[green] = pdefs->green >> 8;
scratch[blue] = pdefs->blue >> 8;
scratch[3] = 0;
- p = pdefs->pixel;
pdefs++;
if (pscr->mapping == VESA_PLANAR)
{
@@ -1150,19 +1693,22 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
vesaSetPalette (priv, 0x14, 1, scratch);
}
}
- else
- vesaSetPalette(priv, p, 1, scratch);
}
+ if (pscr->mapping != VESA_PLANAR)
+ vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4);
}
void
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
+ VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
int first, i, j, k;
- CARD8 scratch[4];
int red, green, blue;
+ int min, max;
+ int p;
+ CARD8 *scratch;
if (vesa_swap_rgb)
{
@@ -1177,8 +1723,24 @@ vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
blue = 2;
}
- for(i = 0; i<n; i++) {
- vesaGetPalette(priv, pdefs[i].pixel, 1, scratch);
+ min = 256;
+ max = 0;
+ for(i = 0; i < n; i++)
+ {
+ p = pdefs[i].pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+ if (pscr->mapping == VESA_PLANAR)
+ vesaGetPalette (priv, p, 1, priv->cmap + p * 4);
+ }
+ if (pscr->mapping != VESA_PLANAR)
+ vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4);
+ for (i = 0; i < n; i++)
+ {
+ p = pdefs[i].pixel;
+ scratch = priv->cmap + p * 4;
pdefs[i].red = scratch[red]<<8;
pdefs[i].green = scratch[green]<<8;
pdefs[i].blue = scratch[blue]<<8;