From 79486b3b5c792a990cb73b4efa453218262e605f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 20 Jul 2001 19:35:30 +0000 Subject: [PATCH] Too many changes, but all in kdrive: Add support for global screen origins (-origin option), handles both Xinerama and mouse crossings. Fix XV enable/disable sequences -- can't use card wrappers as cards have more than one screen. Change vesa/fbdev to use new depth-independent rotation shadow update Fix vesa to allow starting rotation value (again) Make vesa driver write all colormap changes in one INT10 call --- hw/kdrive/fbdev/fbdev.c | 41 +---- hw/kdrive/i810/i810.c | 9 +- hw/kdrive/mach64/mach64.c | 8 +- hw/kdrive/pcmcia/pcmcia.c | 4 +- hw/kdrive/src/kdrive.c | 60 ++++++-- hw/kdrive/src/kdrive.h | 3 +- hw/kdrive/src/kinput.c | 110 +++++++++----- hw/kdrive/src/kxv.c | 62 ++++---- hw/kdrive/src/kxv.h | 8 +- hw/kdrive/vesa/vesa.c | 305 ++++++++++++++++++++++++-------------- hw/kdrive/vesa/vesa.h | 3 +- 11 files changed, 367 insertions(+), 246 deletions(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 104d76582..4bd800e6b 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.25 2001/07/16 19:48:00 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.26 2001/07/19 08:46:30 keithp Exp $ */ #include "fbdev.h" @@ -400,41 +400,10 @@ fbdevLayerCreate (ScreenPtr pScreen) else #endif /* FAKE24_ON_16 */ { - switch (scrpriv->rotation) { - case 0: + if (scrpriv->rotation) + update = shadowUpdateRotatePacked; + else update = shadowUpdatePacked; - break; - case 90: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_90; break; - case 16: - update = shadowUpdateRotate16_90; break; - case 32: - update = shadowUpdateRotate32_90; break; - } - break; - case 180: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_180; break; - case 16: - update = shadowUpdateRotate16_180; break; - case 32: - update = shadowUpdateRotate32_180; break; - } - break; - case 270: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_270; break; - case 16: - update = shadowUpdateRotate16_270; break; - case 32: - update = shadowUpdateRotate32_270; break; - } - break; - } } if (!update) abort (); @@ -449,7 +418,7 @@ fbdevLayerCreate (ScreenPtr pScreen) window = 0; } return LayerCreate (pScreen, kind, screen->fb[0].depth, - pPixmap, update, window, 0); + pPixmap, update, window, scrpriv->rotation, 0); } diff --git a/hw/kdrive/i810/i810.c b/hw/kdrive/i810/i810.c index bb9cc5ad4..050c2cd64 100644 --- a/hw/kdrive/i810/i810.c +++ b/hw/kdrive/i810/i810.c @@ -32,7 +32,7 @@ of the copyright holder. X Window System is a trademark of The Open Group */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/i810/i810.c,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ /* * i810.c - KDrive driver for the i810 chipset @@ -1954,7 +1954,9 @@ i810Enable (ScreenPtr pScreen) /* Set the DPMS mode */ OUTREG8(DPMS_SYNC_SELECT, DPMSSyncSelect); } - +#ifdef XV + KdXVEnable (pScreen); +#endif return TRUE; } @@ -1972,6 +1974,9 @@ i810Disable(ScreenPtr pScreen) { if (I810_DEBUG) fprintf(stderr,"i810Disable\n"); +#ifdef XV + KdXVDisable (pScreen); +#endif i810Restore(screen->card); if (!i810UnbindGARTMemory(screen)) diff --git a/hw/kdrive/mach64/mach64.c b/hw/kdrive/mach64/mach64.c index 296970ed4..1864907d5 100644 --- a/hw/kdrive/mach64/mach64.c +++ b/hw/kdrive/mach64/mach64.c @@ -19,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.4 2001/06/19 09:31:47 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.5 2001/06/23 03:41:24 keithp Exp $ */ #include "mach64.h" #include @@ -222,12 +222,18 @@ mach64Enable (ScreenPtr pScreen) mach64SetMMIO (mach64c); mach64DPMS (pScreen, KD_DPMS_NORMAL); +#ifdef XV + KdXVEnable (pScreen); +#endif return TRUE; } void mach64Disable (ScreenPtr pScreen) { +#ifdef XV + KdXVDisable (pScreen); +#endif vesaDisable (pScreen); } diff --git a/hw/kdrive/pcmcia/pcmcia.c b/hw/kdrive/pcmcia/pcmcia.c index 6ed2c3f0e..8c03e3759 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.3 2001/06/20 21:53:31 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c,v 1.4 2001/06/21 00:58:51 keithp Exp $ */ #include "pcmcia.h" #define extern @@ -376,7 +376,7 @@ pcmciaLayerCreate (ScreenPtr pScreen) pPixmap = 0; return LayerCreate (pScreen, kind, screen->fb[0].depth, - pPixmap, update, window, 0); + pPixmap, update, window, pcmcias->rotation, 0); } #ifdef RANDR diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index 08c59ad4b..912607005 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.16 2001/06/04 09:45:41 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.17 2001/06/13 19:18:03 keithp Exp $ */ #include "kdrive.h" #ifdef PSEUDO8 @@ -47,6 +47,7 @@ Bool kdEmulateMiddleButton; Bool kdDisableZaphod; Bool kdEnabled; Bool kdSwitchPending; +DDXPointRec kdOrigin; /* * Carry arguments from InitOutput through driver initialization @@ -340,8 +341,7 @@ KdParseScreen (KdScreenInfo *screen, screen->dumb = kdDumbDriver; screen->softCursor = kdSoftCursor; - kdDumbDriver = FALSE; - kdSoftCursor = FALSE; + screen->origin = kdOrigin; screen->rotation = 0; screen->width = 0; screen->height = 0; @@ -386,22 +386,28 @@ KdParseScreen (KdScreenInfo *screen, return; } + kdOrigin.x += screen->width; + kdOrigin.y = 0; + kdDumbDriver = FALSE; + kdSoftCursor = FALSE; + if (delim == '@') { arg = KdParseFindNext (arg, "x", save, &delim); - if (!save[0]) - return; - screen->rotation = atoi (save); - if (screen->rotation < 45) - screen->rotation = 0; - else if (screen->rotation < 135) - screen->rotation = 90; - else if (screen->rotation < 225) - screen->rotation = 180; - else if (screen->rotation < 315) - screen->rotation = 270; - else - screen->rotation = 0; + if (save[0]) + { + screen->rotation = atoi (save); + if (screen->rotation < 45) + screen->rotation = 0; + else if (screen->rotation < 135) + screen->rotation = 90; + else if (screen->rotation < 225) + screen->rotation = 180; + else if (screen->rotation < 315) + screen->rotation = 270; + else + screen->rotation = 0; + } } fb = 0; @@ -496,6 +502,25 @@ KdProcessArgument (int argc, char **argv, int i) } if (!strcmp (argv[i], "-standalone")) return 1; + if (!strcmp (argv[i], "-origin")) + { + if ((i+1) < argc) + { + char *x = argv[i+1]; + char *y = strchr (x, ','); + if (x) + kdOrigin.x = atoi (x); + else + kdOrigin.x = 0; + if (y) + kdOrigin.y = atoi(y+1); + else + kdOrigin.y = 0; + } + else + UseMsg (); + return 2; + } #ifdef PSEUDO8 return p8ProcessArgument (argc, argv, i); #else @@ -671,6 +696,9 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) for (fb = 0; fb < KD_MAX_FB && screen->fb[fb].depth; fb++) pScreenPriv->bytesPerPixel[fb] = screen->fb[fb].bitsPerPixel >> 3; pScreenPriv->dpmsState = KD_DPMS_NORMAL; +#ifdef PANORAMIX + dixScreenOrigins[pScreen->myNum] = screen->origin; +#endif if (!monitorResolution) monitorResolution = 75; diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index 116582496..321ad2596 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.16 2001/06/29 14:00:40 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.17 2001/07/11 02:58:19 keithp Exp $ */ #include #include "X.h" @@ -111,6 +111,7 @@ typedef struct _KdScreenInfo { Bool dumb; Bool softCursor; int mynum; + DDXPointRec origin; KdFrameBuffer fb[KD_MAX_FB]; } KdScreenInfo; diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index cae9d8e92..66503f971 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -21,7 +21,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.17 2001/06/29 14:00:40 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.18 2001/07/11 02:58:19 keithp Exp $ */ #include "kdrive.h" #include "inputstr.h" @@ -1394,54 +1394,92 @@ KdWakeupHandler (int screen, KdProcessSwitch (); } +#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) + static Bool KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) { ScreenPtr pScreen = *ppScreen; + ScreenPtr pNewScreen; int n; + int dx, dy; + int best_x, best_y; + int n_best_x, n_best_y; CARD32 ms; if (kdDisableZaphod || screenInfo.numScreens <= 1) return FALSE; - if (*x < 0 || *y < 0) - { - ms = GetTimeInMillis (); - if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) - return FALSE; - kdOffScreen = TRUE; - kdOffScreenTime = ms; + + if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) + return FALSE; - n = pScreen->myNum - 1; - if (n < 0) - n = screenInfo.numScreens - 1; - pScreen = screenInfo.screens[n]; + ms = GetTimeInMillis (); + if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) + return FALSE; + kdOffScreen = TRUE; + kdOffScreenTime = ms; + n_best_x = -1; + best_x = 32767; + n_best_y = -1; + best_y = 32767; + for (n = 0; n < screenInfo.numScreens; n++) + { + pNewScreen = screenInfo.screens[n]; + if (pNewScreen == pScreen) + continue; + dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; + dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; if (*x < 0) - *x += pScreen->width; + { + if (dx <= 0 && -dx < best_x) + { + best_x = -dx; + n_best_x = n; + } + } + else if (*x >= pScreen->width) + { + if (dx >= 0 && dx < best_x) + { + best_x = dx; + n_best_x = n; + } + } if (*y < 0) - *y += pScreen->height; - *ppScreen = pScreen; - return TRUE; + { + if (dy <= 0 && -dy < best_y) + { + best_y = -dy; + n_best_y = n; + } + } + else if (*y >= pScreen->height) + { + if (dy >= 0 && dy < best_y) + { + best_y = dy; + n_best_y = n; + } + } } - else if (*x >= pScreen->width || *y >= pScreen->height) - { - ms = GetTimeInMillis (); - if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) - return FALSE; - kdOffScreen = TRUE; - kdOffScreenTime = ms; - - n = pScreen->myNum + 1; - if (n >= screenInfo.numScreens) - n = 0; - if (*x >= pScreen->width) - *x -= pScreen->width; - if (*y >= pScreen->height) - *y -= pScreen->height; - pScreen = screenInfo.screens[n]; - *ppScreen = pScreen; - return TRUE; - } - return FALSE; + if (best_y < best_x) + n_best_x = n_best_y; + if (n_best_x == -1) + return FALSE; + pNewScreen = screenInfo.screens[n_best_x]; + + if (*x < 0) + *x += pNewScreen->width; + if (*y < 0) + *y += pNewScreen->height; + + if (*x >= pScreen->width) + *x -= pScreen->width; + if (*y >= pScreen->height) + *y -= pScreen->height; + + *ppScreen = pNewScreen; + return TRUE; } static void diff --git a/hw/kdrive/src/kxv.c b/hw/kdrive/src/kxv.c index 2b985fbb5..4f137d1ae 100644 --- a/hw/kdrive/src/kxv.c +++ b/hw/kdrive/src/kxv.c @@ -35,7 +35,7 @@ of the copyright holder. */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.c,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ #include "kdrive.h" @@ -98,12 +98,7 @@ static Bool KdXVDestroyWindow(WindowPtr pWin); static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2); static void KdXVClipNotify(WindowPtr pWin, int dx, int dy); -/* KdCardInfo functions */ -static Bool KdXVEnable(ScreenPtr); -static void KdXVDisable(ScreenPtr); - /* misc */ - static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr*, int); @@ -191,7 +186,6 @@ KdXVScreenInit( int num ){ KdScreenPriv(pScreen); - KdCardInfo *card = pScreenPriv->card; KdXVScreenPtr ScreenPriv; XvScreenPtr pxvs; @@ -239,19 +233,13 @@ KdXVScreenInit( ScreenPriv->WindowExposures = pScreen->WindowExposures; ScreenPriv->ClipNotify = pScreen->ClipNotify; -/* fprintf(stderr,"XV: Wrapping screen & card funcs\n"); */ - - ScreenPriv->enable = card->cfuncs->enable; - ScreenPriv->disable = card->cfuncs->disable; +/* fprintf(stderr,"XV: Wrapping screen funcs\n"); */ pScreen->CreateWindow = KdXVCreateWindow; pScreen->DestroyWindow = KdXVDestroyWindow; pScreen->WindowExposures = KdXVWindowExposures; pScreen->ClipNotify = KdXVClipNotify; - card->cfuncs->disable = KdXVDisable; - card->cfuncs->enable = KdXVEnable; - if(!KdXVInitAdaptors(pScreen, adaptors, num)) return FALSE; @@ -1154,7 +1142,6 @@ static Bool KdXVCloseScreen(int i, ScreenPtr pScreen) { KdScreenPriv(pScreen); - KdCardInfo *card = pScreenPriv->card; KdScreenInfo *screen=pScreenPriv->screen; XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); @@ -1168,10 +1155,7 @@ KdXVCloseScreen(int i, ScreenPtr pScreen) pScreen->WindowExposures = ScreenPriv->WindowExposures; pScreen->ClipNotify = ScreenPriv->ClipNotify; -/* fprintf(stderr,"XV: Unwrapping screen & card funcs\n"); */ - - card->cfuncs->enable = ScreenPriv->enable; - card->cfuncs->disable = ScreenPriv->disable; +/* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */ for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) { KdXVFreeAdaptor(pa); @@ -1202,29 +1186,41 @@ KdXVQueryAdaptors( } static Bool -KdXVEnable(ScreenPtr pScreen) +KdXVRunning (ScreenPtr pScreen) { - static int count=0; - KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); - Bool ret; - - ret = (*ScreenPriv->enable)(pScreen); - - if(ret) WalkTree(pScreen, KdXVReputAllVideo, 0); - - return ret; + return (KdXVGeneration == serverGeneration && + GET_XV_SCREEN(pScreen) != 0); } -static void +Bool +KdXVEnable(ScreenPtr pScreen) +{ + KdXVScreenPtr ScreenPriv; + + if (!KdXVRunning (pScreen)) + return TRUE; + + WalkTree(pScreen, KdXVReputAllVideo, 0); + + return TRUE; +} + +void KdXVDisable(ScreenPtr pScreen) { - XvScreenPtr pxvs = GET_XV_SCREEN(pScreen); - KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen); + XvScreenPtr pxvs; + KdXVScreenPtr ScreenPriv; XvAdaptorPtr pAdaptor; XvPortPtr pPort; XvPortRecPrivatePtr pPriv; int i, j; + if (!KdXVRunning (pScreen)) + return; + + pxvs = GET_XV_SCREEN(pScreen); + ScreenPriv = GET_KDXV_SCREEN(pScreen); + for(i = 0; i < pxvs->nAdaptors; i++) { pAdaptor = &pxvs->pAdaptors[i]; for(j = 0; j < pAdaptor->nPorts; j++) { @@ -1247,8 +1243,6 @@ KdXVDisable(ScreenPtr pScreen) } } } - - (*ScreenPriv->disable)(pScreen); } /**** XvAdaptorRec fields ****/ diff --git a/hw/kdrive/src/kxv.h b/hw/kdrive/src/kxv.h index 5578e3960..0dc8ca2d2 100644 --- a/hw/kdrive/src/kxv.h +++ b/hw/kdrive/src/kxv.h @@ -35,7 +35,7 @@ of the copyright holder. */ -/* $XFree86$ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.h,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ #ifndef _XVDIX_H_ #define _XVDIX_H_ @@ -249,6 +249,10 @@ KdVideoAdaptorPtr KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen); void KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr); +/* Must be called from KdCardInfo functions, can be called without Xv enabled */ +Bool KdXVEnable(ScreenPtr); +void KdXVDisable(ScreenPtr); + /*** These are DDX layer privates ***/ @@ -257,8 +261,6 @@ typedef struct { DestroyWindowProcPtr DestroyWindow; ClipNotifyProcPtr ClipNotify; WindowExposuresProcPtr WindowExposures; - void (*disable) (ScreenPtr); /* turn off rendering */ - Bool (*enable) (ScreenPtr); /* set up for rendering */ } KdXVScreenRec, *KdXVScreenPtr; typedef struct { diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c index 23101a15c..1144c7400 100644 --- a/hw/kdrive/vesa/vesa.c +++ b/hw/kdrive/vesa/vesa.c @@ -19,7 +19,7 @@ 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.13 2001/06/04 09:45:42 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.14 2001/06/11 01:38:54 keithp Exp $ */ #include "vesa.h" #ifdef RANDR @@ -36,9 +36,8 @@ Bool vesa_verbose = FALSE; #define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver) -#define ScreenRotated(scr) (VesaPriv(scr)->rotate == 90 || VesaPriv(scr)->rotate == 270) -#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) @@ -735,6 +734,65 @@ 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; + + 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) { @@ -750,13 +808,15 @@ vesaLayerCreate (ScreenPtr pScreen) 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: @@ -766,7 +826,6 @@ vesaLayerCreate (ScreenPtr pScreen) else update = shadowUpdatePlanar4; window = vesaWindowPlanar; - pscr->rotate = 0; break; case VESA_MONO: update = vesaUpdateMono; @@ -774,39 +833,6 @@ vesaLayerCreate (ScreenPtr pScreen) window = vesaWindowCga; else window = vesaWindowLinear; - pscr->rotate = 0; - break; - } - switch (pscr->rotate) { - case 90: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_90; break; - case 16: - update = shadowUpdateRotate16_90; break; - case 32: - update = shadowUpdateRotate32_90; break; - } - break; - case 180: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_180; break; - case 16: - update = shadowUpdateRotate16_180; break; - case 32: - update = shadowUpdateRotate32_180; break; - } - break; - case 270: - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8_270; break; - case 16: - update = shadowUpdateRotate16_270; break; - case 32: - update = shadowUpdateRotate32_270; break; - } break; } @@ -823,10 +849,10 @@ vesaLayerCreate (ScreenPtr pScreen) if (vesa_verbose) ErrorF ("Mode selected %dx%dx%d\n", - screen->width, screen->height, screen->fb[0].depth); + pScreen->width, pScreen->height, screen->fb[0].depth); return LayerCreate (pScreen, kind, screen->fb[0].depth, - pPixmap, update, window, 0); + pPixmap, update, window, pscr->rotate, 0); } Bool @@ -915,8 +941,8 @@ vesaMapFramebuffer (KdScreenInfo *screen) pscr->rotate = 0; } - screen->width = vesaWidth(screen, &pscr->mode); - screen->height = vesaHeight(screen, &pscr->mode); + 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; @@ -925,18 +951,10 @@ vesaMapFramebuffer (KdScreenInfo *screen) if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR)) pscr->mapping = VESA_WINDOWED; - pscr->shadow = vesa_shadow; - - if (pscr->rotate) - pscr->shadow = TRUE; - - if (pscr->rotate) - screen->softCursor = TRUE; + screen->softCursor = TRUE; switch (pscr->mapping) { case VESA_MONO: - pscr->shadow = TRUE; - /* fall through */ case VESA_LINEAR: if (pscr->mode.vbe) pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, @@ -951,11 +969,9 @@ vesaMapFramebuffer (KdScreenInfo *screen) break; case VESA_WINDOWED: pscr->fb = NULL; - pscr->shadow = TRUE; break; case VESA_PLANAR: pscr->fb = NULL; - pscr->shadow = TRUE; break; } screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb); @@ -1063,16 +1079,39 @@ vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) mode->BlueMaskSize == pscr->mode.BlueMaskSize && mode->BlueFieldPosition == pscr->mode.BlueFieldPosition) { - pSize = RRRegisterSize (pScreen, - mode->XResolution, - mode->YResolution, - screen->width_mm, - screen->height_mm, - pGroupOfVisualGroup); - if (mode->XResolution == pScreen->width && - mode->YResolution == pScreen->height) + int width, height, width_mm, height_mm; + if (screen->rotation == 0 || screen->rotation == 180) { - RRSetCurrentConfig (pScreen, RR_Rotate_0, pSize, + 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); } } @@ -1124,7 +1163,18 @@ vesaRandRSetConfig (ScreenPtr pScreen, 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]; @@ -1133,8 +1183,8 @@ vesaRandRSetConfig (ScreenPtr pScreen, /* * XXX all we have to match is the size */ - if (mode->XResolution == pSize->width && - mode->YResolution == pSize->height && + if (mode->XResolution == newwidth && + mode->YResolution == newheight && mode->NumberOfPlanes == pscr->mode.NumberOfPlanes && mode->BitsPerPixel == pscr->mode.BitsPerPixel && mode->RedMaskSize == pscr->mode.RedMaskSize && @@ -1152,11 +1202,13 @@ vesaRandRSetConfig (ScreenPtr pScreen, if (wasEnabled) KdDisableScreen (pScreen); - ret = vesaSetMode (pScreen, mode); + if (mode->mode != pscr->mode.mode) + { + ret = vesaSetMode (pScreen, mode); + if (!ret) + goto bail1; + } - if (!ret) - goto bail1; - oldscr = *pscr; oldwidth = screen->width; @@ -1176,6 +1228,10 @@ vesaRandRSetConfig (ScreenPtr pScreen, case RR_Rotate_270: pscr->rotate = 270; break; } + pscr->rotate += screen->rotation; + if (pscr->rotate >= 360) + pscr->rotate -= 360; + /* * Can't rotate some formats */ @@ -1190,20 +1246,6 @@ vesaRandRSetConfig (ScreenPtr pScreen, break; } - pScreen->width = screen->width = vesaWidth(screen, mode); - pScreen->height = screen->height = vesaHeight(screen, mode); - - if (rotation & (RR_Rotate_90|RR_Rotate_270)) - { - pScreen->mmWidth = pSize->mmHeight; - pScreen->mmHeight = pSize->mmWidth; - } - else - { - pScreen->mmWidth = pSize->mmWidth; - pScreen->mmHeight = pSize->mmHeight; - } - vesaUnmapFramebuffer (screen); if (!vesaMapFramebuffer (screen)) goto bail3; @@ -1217,6 +1259,15 @@ vesaRandRSetConfig (ScreenPtr pScreen, #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), @@ -1227,7 +1278,10 @@ vesaRandRSetConfig (ScreenPtr pScreen, screen->fb[0].byteStride, screen->fb[0].frameBuffer); } - + + /* + * Create the layer + */ pNewLayer = vesaLayerCreate (pScreen); if (!pNewLayer) goto bail4; @@ -1255,14 +1309,28 @@ bail4: (void) vesaMapFramebuffer (screen); bail3: - pScreen->width = screen->width = oldwidth; - pScreen->height = screen->height = oldheight; + 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: @@ -1311,6 +1379,8 @@ vesaFinishInitScreen (ScreenPtr pScreen) if (!LayerFinishInit (pScreen)) return FALSE; + vesaConfigureScreen (pScreen); + pscr->pLayer = vesaLayerCreate (pScreen); if (!pscr->pLayer) return FALSE; @@ -1363,7 +1433,6 @@ vesaEnable(ScreenPtr pScreen) int i; CARD32 size; char *p; - KdMouseMatrix m; if (!vesaSetMode (pScreen, &pscr->mode)) return FALSE; @@ -1397,25 +1466,6 @@ vesaEnable(ScreenPtr pScreen) } break; } - switch (pscr->rotate) { - case 0: - 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: - m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = pScreen->width - 1; - m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0; - break; - case 180: - m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = pScreen->width - 1; - m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = pScreen->height - 1; - break; - case 270: - 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; - break; - } - KdSetMouseMatrix (&m); return TRUE; } @@ -1561,8 +1611,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) { @@ -1577,13 +1628,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) { @@ -1601,19 +1659,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) { @@ -1628,8 +1689,24 @@ vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) blue = 2; } - for(i = 0; i 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; diff --git a/hw/kdrive/vesa/vesa.h b/hw/kdrive/vesa/vesa.h index 6d555fb02..b84d58d2b 100644 --- a/hw/kdrive/vesa/vesa.h +++ b/hw/kdrive/vesa/vesa.h @@ -19,7 +19,7 @@ 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.h,v 1.9 2001/05/29 04:54:13 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.h,v 1.10 2001/06/04 09:45:42 keithp Exp $ */ #ifndef _VESA_H_ #define _VESA_H_ @@ -84,6 +84,7 @@ typedef struct _VesaCardPriv { int old_vga_mode; VbeInfoPtr vbeInfo; char text[VESA_TEXT_SAVE]; + CARD8 cmap[256*4]; } VesaCardPrivRec, *VesaCardPrivPtr; #define VESA_LINEAR 0