summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hourihane <alanh@fairlite.demon.co.uk>2001-06-20 21:53:31 +0000
committerAlan Hourihane <alanh@fairlite.demon.co.uk>2001-06-20 21:53:31 +0000
commitf8a456f094d8f61c021bbfb6e6f0a4723ebdc73f (patch)
tree726a2698dbeada371985a8cd5ffdf9caeb9f2cbc
parent918ff10f2697ee8c17013bd31596072a38c5ac9b (diff)
Add RandR support to the Kdrive pcmcia driver.
-rw-r--r--hw/kdrive/pcmcia/pcmcia.c330
-rw-r--r--hw/kdrive/pcmcia/pcmcia.h6
2 files changed, 326 insertions, 10 deletions
diff --git a/hw/kdrive/pcmcia/pcmcia.c b/hw/kdrive/pcmcia/pcmcia.c
index fe38051d5..784e5762a 100644
--- a/hw/kdrive/pcmcia/pcmcia.c
+++ b/hw/kdrive/pcmcia/pcmcia.c
@@ -27,7 +27,7 @@
*
* Tested running under a Compaq IPAQ Pocket PC running Linux
*/
-/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c,v 1.1 2001/05/23 08:56:08 alanh Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c,v 1.2 2001/06/05 16:57:44 alanh Exp $ */
#include "pcmcia.h"
#define extern
@@ -143,6 +143,8 @@ pcmciaScreenInit (KdScreenInfo *screen)
return FALSE; /* end of list */
}
+ pcmcias->rotation = screen->rotation;
+
memory = 512 * 1024;
pcmcias->screen = pcmciac->fb;
@@ -210,7 +212,7 @@ pcmciaScreenInit (KdScreenInfo *screen)
screen->driver = pcmcias;
- return KdShadowScreenInit(screen);
+ return TRUE;
}
void *
@@ -247,29 +249,341 @@ cirrusWindowWindowed (ScreenPtr pScreen,
return 0;
bank = (row * pScreenPriv->screen->fb[0].byteStride) / 0x1000;
- pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 8);
+ pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 0x0c);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x09, bank);
pcmciaWriteIndex(pcmciac, 0x3ce, 0x0A, bank);
*size = pScreenPriv->screen->fb[0].byteStride;
return (CARD8 *) pcmciac->fb + (row * pScreenPriv->screen->fb[0].byteStride) - (bank * 0x1000) + offset;
}
-Bool
-pcmciaInitScreen (ScreenPtr pScreen)
+LayerPtr
+pcmciaLayerCreate (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
ShadowUpdateProc update;
ShadowWindowProc window;
+ KdMouseMatrix m;
+ PixmapPtr pPixmap;
+ int kind;
+
+ switch (pcmcias->rotation) {
+ case 0:
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ 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 = screen->height;
+ pScreen->height = screen->width;
+ m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = screen->height - 1;
+ m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0;
+ break;
+ case 180:
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = screen->width - 1;
+ m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = screen->height - 1;
+ break;
+ case 270:
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ 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] = screen->width - 1;
+ break;
+ }
+ KdSetMouseMatrix (&m);
if (pcmciac->HP) {
- update = tridentUpdatePacked;
window = tridentWindowLinear;
+ switch (pcmcias->rotation) {
+ case 0:
+ update = tridentUpdatePacked;
+ break;
+ case 90:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_90; break;
+ case 16:
+ update = shadowUpdateRotate16_90; break;
+ }
+ break;
+ case 180:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_180; break;
+ case 16:
+ update = shadowUpdateRotate16_180; break;
+ }
+ break;
+ case 270:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_270; break;
+ case 16:
+ update = shadowUpdateRotate16_270; break;
+ }
+ break;
+ }
} else {
- update = cirrusUpdatePacked;
window = cirrusWindowWindowed;
+ switch (pcmcias->rotation) {
+ case 0:
+ update = cirrusUpdatePacked;
+ break;
+ case 90:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_90; break;
+ case 16:
+ update = shadowUpdateRotate16_90; break;
+ }
+ break;
+ case 180:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_180; break;
+ case 16:
+ update = shadowUpdateRotate16_180; break;
+ }
+ break;
+ case 270:
+ switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
+ case 8:
+ update = shadowUpdateRotate8_270; break;
+ case 16:
+ update = shadowUpdateRotate16_270; break;
+ }
+ break;
+ }
+ }
+
+ if (!update)
+ abort ();
+
+ kind = LAYER_SHADOW;
+ pPixmap = 0;
+
+ return LayerCreate (pScreen, kind, screen->fb[0].depth,
+ pPixmap, update, window, 0);
+}
+
+#ifdef RANDR
+Bool
+pcmciaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ pcmciaCardInfo *pcmciac = pScreenPriv->card->driver;
+ KdScreenInfo *screen = pScreenPriv->screen;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ RRVisualGroupPtr pVisualGroup;
+ RRGroupOfVisualGroupPtr pGroupOfVisualGroup;
+ RRScreenSizePtr pSize;
+ Rotation rotateKind;
+ int rotation;
+ int n;
+
+ *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270;
+
+ 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;
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm,
+ pGroupOfVisualGroup);
+
+ rotation = pcmcias->rotation - screen->rotation;
+ if (rotation < 0)
+ rotation += 360;
+
+ switch (rotation)
+ {
+ case 0:
+ rotateKind = RR_Rotate_0;
+ break;
+ case 90:
+ rotateKind = RR_Rotate_90;
+ break;
+ case 180:
+ rotateKind = RR_Rotate_180;
+ break;
+ case 270:
+ rotateKind = RR_Rotate_270;
+ break;
+ }
+
+ RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup);
+
+ return TRUE;
+ }
+
+int
+pcmciaLayerAdd (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
+pcmciaLayerRemove (WindowPtr pWin, pointer value)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ LayerPtr pLayer = (LayerPtr) value;
+
+ LayerWindowRemove (pScreen, pLayer, pWin);
+
+ return WT_WALKCHILDREN;
+}
+
+pcmciaRandRSetConfig (ScreenPtr pScreen,
+ Rotation rotateKind,
+ RRScreenSizePtr pSize,
+ RRVisualGroupPtr pVisualGroup)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+ int rotation;
+ Bool wasEnabled = pScreenPriv->enabled;
+
+ /*
+ * The only thing that can change is rotation
+ */
+ switch (rotateKind)
+ {
+ case RR_Rotate_0:
+ rotation = screen->rotation;
+ break;
+ case RR_Rotate_90:
+ rotation = screen->rotation + 90;
+ break;
+ case RR_Rotate_180:
+ rotation = screen->rotation + 180;
+ break;
+ case RR_Rotate_270:
+ rotation = screen->rotation + 270;
+ break;
+ }
+ if (rotation >= 360)
+ rotation -= 360;
+
+ if (pcmcias->rotation != rotation)
+ {
+ LayerPtr pNewLayer;
+ int kind;
+ int oldrotation = pcmcias->rotation;
+ int oldwidth = pScreen->width;
+ int oldheight = pScreen->height;
+ PixmapPtr pPixmap;
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ pcmcias->rotation = rotation;
+ pNewLayer = pcmciaLayerCreate (pScreen);
+ if (!pNewLayer)
+ {
+ pcmcias->rotation = oldrotation;
+ }
+ if (WalkTree (pScreen, pcmciaLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING)
+ {
+ WalkTree (pScreen, pcmciaLayerRemove, (pointer) pNewLayer);
+ LayerDestroy (pScreen, pNewLayer);
+ pcmcias->rotation = oldrotation;
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+ }
+ WalkTree (pScreen, pcmciaLayerRemove, (pointer) pcmcias->pLayer);
+ LayerDestroy (pScreen, pcmcias->pLayer);
+ pcmcias->pLayer = pNewLayer;
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
}
- return KdShadowInitScreen (pScreen, update, window);
+ return TRUE;
+}
+
+Bool
+pcmciaRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = pcmciaRandRGetInfo;
+ pScrPriv->rrSetConfig = pcmciaRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+pcmciaInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver;
+
+ if (!LayerStartInit (pScreen))
+ return FALSE;
+ if (!LayerFinishInit (pScreen))
+ return FALSE;
+ pcmcias->pLayer = pcmciaLayerCreate (pScreen);
+ if (!pcmcias->pLayer)
+ return FALSE;
+#ifdef RANDR
+ if (!pcmciaRandRInit (pScreen))
+ return FALSE;
+#endif
+ return TRUE;
}
CARD8
diff --git a/hw/kdrive/pcmcia/pcmcia.h b/hw/kdrive/pcmcia/pcmcia.h
index 9e26dc282..3d8842d26 100644
--- a/hw/kdrive/pcmcia/pcmcia.h
+++ b/hw/kdrive/pcmcia/pcmcia.h
@@ -21,7 +21,7 @@
*
* Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
*/
-/* $XFree86$ */
+/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h,v 1.1 2001/05/23 08:56:09 alanh Exp $ */
#ifndef _PCMCIA_H_
#define _PCMCIA_H_
@@ -194,7 +194,9 @@ typedef struct _pcmciaScreenInfo {
CARD8 *screen;
CARD8 *off_screen;
int off_screen_size;
- pcmciaCursor cursor;
+ int rotation;
+ LayerPtr pLayer;
+ pcmciaCursor cursor;
} pcmciaScreenInfo;
#define getpcmciaScreenInfo(kd) ((pcmciaScreenInfo *) ((kd)->screen->driver))