From 78b53386b51cde4fe4664963ddafa36b814360f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 29 May 2001 04:54:13 +0000 Subject: [PATCH] Add miext/layer for more complete RandR support in kdrive/Xfbdev --- hw/kdrive/Imakefile | 6 +- hw/kdrive/Kdrive.tmpl | 3 +- hw/kdrive/fbdev/fbdev.c | 378 ++++++++++++--- hw/kdrive/fbdev/fbdev.h | 9 +- hw/kdrive/igs/igsdraw.c | 19 +- hw/kdrive/savage/s3draw.c | 28 +- hw/kdrive/sis530/sisdraw.c | 13 +- hw/kdrive/src/kaa.c | 623 +++++++++++++++++++++++++ hw/kdrive/src/kdrive.c | 27 +- hw/kdrive/src/kdrive.h | 28 ++ hw/kdrive/trident/tridentdraw.c | 799 ++++---------------------------- hw/kdrive/vesa/vbe.c | 19 +- hw/kdrive/vesa/vbe.h | 4 +- hw/kdrive/vesa/vesa.c | 155 +++++-- hw/kdrive/vesa/vesa.h | 4 +- 15 files changed, 1258 insertions(+), 857 deletions(-) create mode 100644 hw/kdrive/src/kaa.c diff --git a/hw/kdrive/Imakefile b/hw/kdrive/Imakefile index 1b91011ba..ad1050092 100644 --- a/hw/kdrive/Imakefile +++ b/hw/kdrive/Imakefile @@ -1,5 +1,5 @@ XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $ -XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.6 2001/03/30 02:15:19 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Imakefile,v 1.7 2001/05/23 08:56:08 alanh Exp $ KDRIVE=. #include "Kdrive.tmpl" @@ -17,10 +17,10 @@ XVOBJS=kxv.o DEFINES = -DXIPAQ #endif -SRCS = kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \ +SRCS = kaa.c kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \ vga.c kasync.c kmode.c kcurscol.c kshadow.c $(RENDERSRCS) $(XVSRCS) -OBJS = kcmap.o kcolor.o kdrive.o kinfo.o kinput.o kmap.o knoop.o ktest.o \ +OBJS = kaa.o kcmap.o kcolor.o kdrive.o kinfo.o kinput.o kmap.o knoop.o ktest.o \ vga.o kasync.o kmode.o kcurscol.o kshadow.o $(RENDEROBJS) $(XVOBJS) INCLUDES = $(KDINCS) diff --git a/hw/kdrive/Kdrive.tmpl b/hw/kdrive/Kdrive.tmpl index 33592e48c..ade5604af 100644 --- a/hw/kdrive/Kdrive.tmpl +++ b/hw/kdrive/Kdrive.tmpl @@ -1,4 +1,4 @@ -XCOMM $XFree86$ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Kdrive.tmpl,v 1.2 2001/05/26 01:25:41 keithp Exp $ #include @@ -13,5 +13,6 @@ RANDRINCS=-I$(KDRIVE)/../../randr -I$(EXTINCSRC) KDINCS = -I$(KDRIVE) -I$(XBUILDINCDIR) -I$(FONTINCSRC) \ -I$(KDRIVE)/../../fb -I$(KDRIVE)/../../mi \ -I$(KDRIVE)/../../miext/shadow \ + -I$(KDRIVE)/../../miext/layer \ -I$(KDRIVE)/../../include -I$(KDRIVE)/../../os \ -I$(EXTINCSRC) -I$(XINCLUDESRC) $(RENDERINCS) $(RANDRINCS) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 54d3c9c14..85fbe6314 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.12 2001/05/23 08:56:08 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.13 2001/05/25 07:44:29 alanh Exp $ */ #include "fbdev.h" @@ -92,7 +92,6 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) FbdevPriv *priv = screen->card->driver; Pixel allbits; int depth; - Bool rotate; Bool shadow; #ifdef FAKE24_ON_16 Bool fake24; @@ -134,15 +133,15 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) break; } screen->rate = 72; - scrpriv->rotate = ((priv->var.xres < priv->var.yres) != - (screen->width < screen->height)); + scrpriv->rotation = screen->rotation; + #ifdef FAKE24_ON_16 if (screen->fb[0].depth == 24 && screen->fb[0].bitsPerPixel == 24 && priv->var.bits_per_pixel == 16) { fake24 = TRUE; scrpriv->shadow = TRUE; - scrpriv->rotate = FALSE; + scrpriv->rotation = 0; screen->fb[0].redMask = 0xff0000; screen->fb[0].greenMask = 0x00ff00; screen->fb[0].blueMask = 0x0000ff; @@ -155,27 +154,13 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) { screen->fb[0].depth = depth; screen->fb[0].bitsPerPixel = priv->var.bits_per_pixel; - if (!scrpriv->rotate) - { - screen->width = priv->var.xres; - screen->height = priv->var.yres; - screen->fb[0].byteStride = priv->fix.line_length; - screen->fb[0].pixelStride = (priv->fix.line_length * 8 / - priv->var.bits_per_pixel); - screen->fb[0].frameBuffer = (CARD8 *) (priv->fb); - return TRUE; - } - else - { - screen->width = priv->var.yres; - screen->height = priv->var.xres; - screen->softCursor = TRUE; - } + screen->width = priv->var.xres; + screen->height = priv->var.yres; + screen->fb[0].byteStride = priv->fix.line_length; + screen->fb[0].pixelStride = (priv->fix.line_length * 8 / + priv->var.bits_per_pixel); + screen->fb[0].frameBuffer = (CARD8 *) (priv->fb); } - if (scrpriv->rotate) - scrpriv->shadow = TRUE; - if (scrpriv->shadow) - return KdShadowScreenInit (screen); return TRUE; } @@ -202,7 +187,8 @@ fbdevWindowLinear (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); FbdevPriv *priv = pScreenPriv->card->driver; @@ -295,6 +281,279 @@ fbdevUpdateFake24 (ScreenPtr pScreen, } #endif /* FAKE24_ON_16 */ +LayerPtr +fbdevLayerCreate (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + FbdevPriv *priv = pScreenPriv->card->driver; + FbdevScrPriv *scrpriv = screen->driver; + LayerPtr pLayer; + ShadowUpdateProc update; + ShadowWindowProc window; + PixmapPtr pPixmap; + int kind; + + if (scrpriv->shadow) + { + window = fbdevWindowLinear; +#ifdef FAKE24_ON_16 + if (pScreenPriv->screen->fb[0].bitsPerPixel == 24 && priv->var.bits_per_pixel == 16) + { + update = fbdevUpdateFake24; + } + else +#endif /* FAKE24_ON_16 */ + { + switch (scrpriv->rotation) { + case 0: + 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; + } + } + kind = LAYER_SHADOW; + pPixmap = 0; + } + else + { + kind = LAYER_FB; + pPixmap = LAYER_SCREEN_PIXMAP; + update = 0; + window = 0; + } + return LayerCreate (pScreen, kind, screen->fb[0].depth, + pPixmap, update, window, 0); +} + + +#ifdef RANDR +Bool +fbdevRandRGetInfo (ScreenPtr pScreen, int *rotations, int *swaps) +{ + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + KdScreenInfo *screen = pScreenPriv->screen; + FbdevScrPriv *scrpriv = screen->driver; + RRVisualSetPtr pVisualSet; + RRSetOfVisualSetPtr pSetOfVisualSet; + RRSizeInfoPtr pSize; + int rotateKind; + int n; + + *swaps = 0; + *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; + + pVisualSet = RRCreateVisualSet (pScreen); + if (!pVisualSet) + return FALSE; + if (!RRAddDepthToVisualSet (pScreen, + pVisualSet, + &pScreen->allowedDepths[n])) + { + RRDestroyVisualSet (pScreen, pVisualSet); + return FALSE; + } + + pVisualSet = RRRegisterVisualSet (pScreen, pVisualSet); + if (!pVisualSet) + return FALSE; + + pSetOfVisualSet = RRCreateSetOfVisualSet (pScreen); + + if (!RRAddVisualSetToSetOfVisualSet (pScreen, + pSetOfVisualSet, + pVisualSet)) + { + RRDestroySetOfVisualSet (pScreen, pSetOfVisualSet); + /* pVisualSet left until screen closed */ + return FALSE; + } + + pSetOfVisualSet = RRRegisterSetOfVisualSet (pScreen, pSetOfVisualSet); + if (!pSetOfVisualSet) + return FALSE; + + pSize = RRRegisterSize (pScreen, + screen->width, + screen->height, + screen->width_mm, + screen->height_mm, + pSetOfVisualSet); + + switch (scrpriv->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, 0, pSize, pVisualSet); + + return TRUE; +} + +int +fbdevLayerAdd (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 +fbdevLayerRemove (WindowPtr pWin, pointer value) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + LayerPtr pLayer = (LayerPtr) value; + + LayerWindowRemove (pScreen, pLayer, pWin); + + return WT_WALKCHILDREN; +} + +fbdevRandRSetConfig (ScreenPtr pScreen, + int rotateKind, + int swap, + RRSizeInfoPtr pSize, + RRVisualSetPtr pVisualSet) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + FbdevPriv *priv = pScreenPriv->card->driver; + FbdevScrPriv *scrpriv = screen->driver; + int rotation; + Bool wasEnabled = pScreenPriv->enabled; + + /* + * The only thing that can change is rotation + */ + switch (rotateKind) + { + case RR_ROTATE_0: + rotation = 0; + break; + case RR_ROTATE_90: + rotation = 90; + break; + case RR_ROTATE_180: + rotation = 180; + break; + case RR_ROTATE_270: + rotation = 270; + break; + } + if (scrpriv->rotation != rotation) + { + LayerPtr pNewLayer; + int kind; + int oldrotation = scrpriv->rotation; + int oldshadow = scrpriv->shadow; + PixmapPtr pPixmap; + + if (wasEnabled) + KdDisableScreen (pScreen); + + scrpriv->rotation = rotation; + if (rotation) + scrpriv->shadow = TRUE; + else + scrpriv->shadow = FALSE; + + pNewLayer = fbdevLayerCreate (pScreen); + if (!pNewLayer) + { + scrpriv->shadow = oldshadow; + scrpriv->rotation = oldrotation; + } + if (rotation == 90 || rotation == 270) + { + pScreen->width = screen->height; + pScreen->height = screen->width; + } + else + { + pScreen->width = screen->width; + pScreen->height = screen->height; + } + + if (WalkTree (pScreen, fbdevLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING) + { + WalkTree (pScreen, fbdevLayerRemove, (pointer) pNewLayer); + LayerDestroy (pScreen, pNewLayer); + scrpriv->rotation = oldrotation; + scrpriv->shadow = oldshadow; + return FALSE; + } + WalkTree (pScreen, fbdevLayerRemove, (pointer) scrpriv->pLayer); + LayerDestroy (pScreen, scrpriv->pLayer); + scrpriv->pLayer = pNewLayer; + if (wasEnabled) + KdEnableScreen (pScreen); + } + return TRUE; +} + +void +fbdevRandRInit (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + + if (!pScrPriv) + return; + pScrPriv->rrGetInfo = fbdevRandRGetInfo; + pScrPriv->rrSetConfig = fbdevRandRSetConfig; +} +#endif + #ifdef TOUCHSCREEN int TsFbdev = -1; #endif @@ -312,33 +571,16 @@ fbdevInitScreen (ScreenPtr pScreen) TsFbdev = pScreen->myNum; #endif - if (scrpriv->shadow) - { - window = fbdevWindowLinear; -#ifdef FAKE24_ON_16 - if (pScreenPriv->screen->fb[0].bitsPerPixel == 24 && priv->var.bits_per_pixel == 16) - { - update = fbdevUpdateFake24; - } - else -#endif /* FAKE24_ON_16 */ - { - update = shadowUpdatePacked; - if (scrpriv->rotate) - { - window = fbdevWindowLinear; - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8; break; - case 16: - update = shadowUpdateRotate16; break; - case 32: - update = shadowUpdateRotate32; break; - } - } - } - return KdShadowInitScreen (pScreen, update, window); - } + if (!LayerStartInit (pScreen)) + return FALSE; + if (!LayerFinishInit (pScreen)) + return FALSE; + scrpriv->pLayer = fbdevLayerCreate (pScreen); + if (!scrpriv->pLayer) + return FALSE; +#ifdef RANDR + fbdevRandRInit (pScreen); +#endif return TRUE; } @@ -351,7 +593,7 @@ Bool fbdevEnable (ScreenPtr pScreen) { KdScreenPriv(pScreen); - FbdevPriv *priv = pScreenPriv->card->driver; + FbdevPriv *priv = pScreenPriv->card->driver; FbdevScrPriv *scrpriv = pScreenPriv->screen->driver; int k; KdMouseMatrix m; @@ -365,16 +607,26 @@ fbdevEnable (ScreenPtr pScreen) perror ("FBIOPUT_VSCREENINFO"); return FALSE; } - if (scrpriv->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 - { + switch (scrpriv->rotation) { + 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); + if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR) { struct fb_cmap cmap; @@ -397,7 +649,6 @@ fbdevEnable (ScreenPtr pScreen) cmap.transp = 0; ioctl (priv->fd, FBIOPUTCMAP, &cmap); } - KdSetMouseMatrix (&m); return TRUE; } @@ -432,9 +683,6 @@ void fbdevScreenFini (KdScreenInfo *screen) { FbdevScrPriv *scrpriv = screen->driver; - - if (scrpriv->shadow) - KdShadowScreenFini (screen); } void diff --git a/hw/kdrive/fbdev/fbdev.h b/hw/kdrive/fbdev/fbdev.h index f28997bff..0a1792f25 100644 --- a/hw/kdrive/fbdev/fbdev.h +++ b/hw/kdrive/fbdev/fbdev.h @@ -25,11 +25,15 @@ #ifndef _FBDEV_H_ #define _FBDEV_H_ -#include "kdrive.h" #include #include #include #include +#include "kdrive.h" +#include "layer.h" +#ifdef RANDR +#include "randrstr.h" +#endif typedef struct _fbdevPriv { struct fb_var_screeninfo var; @@ -43,8 +47,9 @@ typedef struct _fbdevPriv { } FbdevPriv; typedef struct _fbdevScrPriv { - Bool rotate; + int rotation; Bool shadow; + LayerPtr pLayer; } FbdevScrPriv; Bool diff --git a/hw/kdrive/igs/igsdraw.c b/hw/kdrive/igs/igsdraw.c index be46dc438..7ac19393b 100644 --- a/hw/kdrive/igs/igsdraw.c +++ b/hw/kdrive/igs/igsdraw.c @@ -112,19 +112,20 @@ igsSetPattern (ScreenPtr pScreen, FbStip *pix; FbStride pixStride; int pixBpp; + int pixXoff, pixYoff; CARD8 tmp[8]; CARD32 *pat; int stipX, stipY; int y; FbStip bits; - modulus (-yrot, pPixmap->drawable.height, stipY); - modulus (-xrot, FB_UNIT, stipX); + fbGetStipDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, pixXoff, pixYoff); + + modulus (-yrot - pixYoff, pPixmap->drawable.height, stipY); + modulus (-xrot - pixXoff, FB_UNIT, stipX); pat = (CARD32 *) p->base; - fbGetStipDrawable (&pPixmap->drawable, pix, pixStride, pixBpp); - for (y = 0; y < 8; y++) { bits = pix[stipY * pixStride]; @@ -152,8 +153,9 @@ igsSetPattern (ScreenPtr pScreen, FbBits *pat; FbStride patStride; int patBpp; + int patXoff, patYoff; - fbGetDrawable (&pPixmap->drawable, pix, pixStride, pixBpp); + fbGetDrawable (&pPixmap->drawable, pix, pixStride, pixBpp, patXoff, patYoff); pat = (FbBits *) p->base; patBpp = pixBpp; @@ -166,7 +168,7 @@ igsSetPattern (ScreenPtr pScreen, pPixmap->drawable.width * pixBpp, pPixmap->drawable.height, GXcopy, FB_ALLONES, pixBpp, - xrot * pixBpp, yrot); + (xrot - patXoff) * pixBpp, yrot - patYoff); } return p; } @@ -404,6 +406,7 @@ igsCopy1toN (DrawablePtr pSrcDrawable, FbStip *psrcBase; FbStride widthSrc; int srcBpp; + int srcXoff, srcYoff; CARD32 cmd; if (args->opaque && sourceInvarient (pGC->alu)) @@ -413,7 +416,7 @@ igsCopy1toN (DrawablePtr pSrcDrawable, return; } - fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp); + fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff); if (args->opaque) { @@ -433,7 +436,7 @@ igsCopy1toN (DrawablePtr pSrcDrawable, igsStipple (pDstDrawable->pScreen, cmd, psrcBase, widthSrc, - dstx + dx, dsty + dy, + dstx + dx - srcXoff, dsty + dy - srcYoff, dstx, dsty, pbox->x2 - dstx, pbox->y2 - dsty); pbox++; diff --git a/hw/kdrive/savage/s3draw.c b/hw/kdrive/savage/s3draw.c index 831db3be0..ab5f76bec 100644 --- a/hw/kdrive/savage/s3draw.c +++ b/hw/kdrive/savage/s3draw.c @@ -22,7 +22,7 @@ * * Author: Keith Packard, SuSE, Inc. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.4 2000/05/06 22:17:46 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.5 2000/08/09 17:52:41 keithp Exp $ */ #include "s3.h" #include "s3draw.h" @@ -258,6 +258,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable, FbStip *psrcBase; FbStride widthSrc; int srcBpp; + int srcXoff, srcYoff; if (args->opaque && sourceInvarient (pGC->alu)) { @@ -267,7 +268,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable, } s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC)); - fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp); + fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff); if (args->opaque) { @@ -287,7 +288,7 @@ s3Copy1toN (DrawablePtr pSrcDrawable, _s3Stipple (s3c, psrcBase, widthSrc, - dstx + dx, dsty + dy, + dstx + dx - srcXoff, dsty + dy - srcYoff, dstx, dsty, pbox->x2 - dstx, pbox->y2 - dsty); pbox++; @@ -412,12 +413,13 @@ s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC, FbStip *stip; FbStride stipStride; int stipBpp; + int stipXoff, stipYoff; int stipWidth, stipHeight; int dstX, dstY, width, height; stipWidth = pStipple->width; stipHeight = pStipple->height; - fbGetStipDrawable (pStipple, stip, stipStride, stipBpp); + fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff); s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable)); if (pGC->fillStyle == FillOpaqueStippled) @@ -443,8 +445,8 @@ s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC, width = pBox->x2 - pBox->x1; height = pBox->y2 - pBox->y1; pBox++; - modulus (dstY - yRot, stipHeight, stipY); - modulus (dstX - xRot, stipWidth, stipX); + modulus (dstY - yRot - stipYoff, stipHeight, stipY); + modulus (dstX - xRot - stipXoff, stipWidth, stipX); y = dstY; while (height) { @@ -649,13 +651,14 @@ _s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC, FbStip *stip; FbStride stipStride; int stipBpp; + int stipXoff, stipYoff; int stipWidth, stipHeight; int dstX, dstY, width, height; s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC)); stipWidth = pStipple->width; stipHeight = pStipple->height; - fbGetStipDrawable (pStipple, stip, stipStride, stipBpp); + fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff); if (pGC->fillStyle == FillOpaqueStippled) { _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask, @@ -676,8 +679,8 @@ _s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC, dstY = ppt->y; ppt++; width = *pwidth++; - modulus (dstY - yRot, stipHeight, stipY); - modulus (dstX - xRot, stipWidth, stipX); + modulus (dstY - yRot - stipYoff, stipHeight, stipY); + modulus (dstX - xRot - stipXoff, stipWidth, stipX); y = dstY; x = dstX; sx = stipX; @@ -2827,6 +2830,7 @@ s3_24ImageGlyphBlt (DrawablePtr pDrawable, FbBits *dst; FbStride dstStride; int dstBpp; + int dstXoff, dstYoff; FbBits depthMask; int xBack, widthBack; int yBack, heightBack; @@ -2839,7 +2843,7 @@ s3_24ImageGlyphBlt (DrawablePtr pDrawable, KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); return; } - fbGetDrawable (pDrawable, dst, dstStride, dstBpp); + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); x += pDrawable->x; y += pDrawable->y; @@ -2882,12 +2886,12 @@ s3_24ImageGlyphBlt (DrawablePtr pDrawable, if (gWidth <= sizeof (FbStip) * 8 && fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { - fbGlyph24 (dst + gy * dstStride, + fbGlyph24 (dst + (gy - dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->fg, - gx, + gx - dstXoff, gHeight); } else diff --git a/hw/kdrive/sis530/sisdraw.c b/hw/kdrive/sis530/sisdraw.c index 0cc14ba6d..09dbf8c13 100644 --- a/hw/kdrive/sis530/sisdraw.c +++ b/hw/kdrive/sis530/sisdraw.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/sis530/sisdraw.c,v 1.4 2000/05/06 22:17:50 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c,v 1.5 2000/08/09 17:52:44 keithp Exp $ */ #include "sis.h" #include "sisdraw.h" @@ -803,6 +803,7 @@ sisStipplePrepare (DrawablePtr pDrawable, GCPtr pGC) FbStip *stip, *stipEnd, bits; FbStride stipStride; int stipBpp; + int stipXoff, stipYoff; /* XXX assumed to be zero */ int y; CARD32 cmd; @@ -812,7 +813,7 @@ sisStipplePrepare (DrawablePtr pDrawable, GCPtr pGC) modulus (- xRot, FB_UNIT, stipX); rot = stipX; - fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp); + fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); for (y = 0; y < 8; y++) { bits = stip[stipY<<1]; @@ -852,8 +853,9 @@ sisTilePrepare (PixmapPtr pTile, int xRot, int yRot, CARD8 alu) FbBits *tile; FbStride tileStride; int tileBpp; + int tileXoff, tileYoff; /* XXX assumed to be zero */ - fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp); + fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); /* * Tile the pattern register @@ -1157,6 +1159,7 @@ sisCopy1toN (DrawablePtr pSrcDrawable, FbStip *psrcBase; FbStride widthSrc; int srcBpp; + int srcXoff, srcYoff; if (sourceInvarient (pGC->alu)) { @@ -1165,7 +1168,7 @@ sisCopy1toN (DrawablePtr pSrcDrawable, return; } - fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp); + fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff); sis->u.general.src_fg = args->copyPlaneFG; sis->u.general.src_bg = args->copyPlaneBG; @@ -1178,7 +1181,7 @@ sisCopy1toN (DrawablePtr pSrcDrawable, _sisStipple (pDstDrawable->pScreen, psrcBase, widthSrc, pGC->alu, - dstx + dx, dsty + dy, + dstx + dx - srcXoff, dsty + dy - srcYoff, dstx, dsty, pbox->x2 - dstx, pbox->y2 - dsty); pbox++; diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c new file mode 100644 index 000000000..0dd51986e --- /dev/null +++ b/hw/kdrive/src/kaa.c @@ -0,0 +1,623 @@ +/* + * $XFree86$ + * + * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "kdrive.h" +#include "fontstruct.h" +#include "dixfontstr.h" + +int kaaGeneration; +int kaaScreenPrivateIndex; + +#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = (KaaScreenPrivPtr) (s)->devPrivates[kaaScreenPrivateIndex].ptr + +void +kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, + DDXPointPtr ppt, int *pwidth, int fSorted) +{ + KaaScreenPriv (pDrawable->pScreen); + RegionPtr pClip = fbGetCompositeClip(pGC); + BoxPtr pextent, pbox; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + int partX1, partX2; + + if (pGC->fillStyle != FillSolid || + !(*pKaaScr->PrepareSolid) (pDrawable, + pGC->alu, + pGC->planemask, + pGC->fgPixel)) + { + KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); + return; + } + + pextent = REGION_EXTENTS(pGC->pScreen, pClip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + while (n--) + { + fullX1 = ppt->x; + fullY1 = ppt->y; + fullX2 = fullX1 + (int) *pwidth; + ppt++; + pwidth++; + + if (fullY1 < extentY1 || extentY2 <= fullY1) + continue; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullX1 >= fullX2) + continue; + + nbox = REGION_NUM_RECTS (pClip); + if (nbox == 1) + { + (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY1 + 1); + } + else + { + pbox = REGION_RECTS(pClip); + while(nbox--) + { + if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) + { + partX1 = pbox->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partX2 = pbox->x2; + if (partX2 > fullX2) + partX2 = fullX2; + if (partX2 > partX1) + (*pKaaScr->Solid) (partX1, fullY1, partX2, fullY1 + 1); + } + pbox++; + } + } + } + (*pKaaScr->DoneSolid) (); + KdMarkSync(pDrawable->pScreen); +} + +void +kaaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + KaaScreenPriv (pDstDrawable->pScreen); + int srcX, srcY, dstX, dstY; + int w, h; + CARD32 flags; + CARD32 cmd; + CARD8 alu; + + if ((*pKaaScr->PrepareCopy) (pSrcDrawable, + pDstDrawable, + upsidedown, + reverse, + pGC ? pGC->alu : GXcopy, + pGC ? pGC->planemask : FB_ALLONES)) + { + while (nbox--) + { + (*pKaaScr->Copy) (pbox->x1 + dx, pbox->y1 + dy, + pbox->x1, pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1); + pbox++; + } + (*pKaaScr->DoneCopy) (); + KdMarkSync(pDstDrawable->pScreen); + } + else + { + KdCheckSync (pDstDrawable->pScreen); + fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, + pbox, nbox, dx, dy, reverse, upsidedown, + bitplane, closure); + } +} + +RegionPtr +kaaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + int srcx, int srcy, int width, int height, int dstx, int dsty) +{ + return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, + dstx, dsty, kaaCopyNtoN, 0, 0); +} + +void +kaaPolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, + int nrect, + xRectangle *prect) +{ + KaaScreenPriv (pDrawable->pScreen); + RegionPtr pClip = fbGetCompositeClip(pGC); + register BoxPtr pbox; + BoxPtr pextent; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1, fullY2; + int partX1, partX2, partY1, partY2; + int xorg, yorg; + int n; + + if (pGC->fillStyle != FillSolid || + !(*pKaaScr->PrepareSolid) (pDrawable, + pGC->alu, + pGC->planemask, + pGC->fgPixel)) + { + KdCheckPolyFillRect (pDrawable, pGC, nrect, prect); + return; + } + + xorg = pDrawable->x; + yorg = pDrawable->y; + + pextent = REGION_EXTENTS(pGC->pScreen, pClip); + extentX1 = pextent->x1; + extentY1 = pextent->y1; + extentX2 = pextent->x2; + extentY2 = pextent->y2; + while (nrect--) + { + fullX1 = prect->x + xorg; + fullY1 = prect->y + yorg; + fullX2 = fullX1 + (int) prect->width; + fullY2 = fullY1 + (int) prect->height; + prect++; + + if (fullX1 < extentX1) + fullX1 = extentX1; + + if (fullY1 < extentY1) + fullY1 = extentY1; + + if (fullX2 > extentX2) + fullX2 = extentX2; + + if (fullY2 > extentY2) + fullY2 = extentY2; + + if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) + continue; + n = REGION_NUM_RECTS (pClip); + if (n == 1) + { + (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY2); + } + else + { + pbox = REGION_RECTS(pClip); + /* + * clip the rectangle to each box in the clip region + * this is logically equivalent to calling Intersect() + */ + while(n--) + { + partX1 = pbox->x1; + if (partX1 < fullX1) + partX1 = fullX1; + partY1 = pbox->y1; + if (partY1 < fullY1) + partY1 = fullY1; + partX2 = pbox->x2; + if (partX2 > fullX2) + partX2 = fullX2; + partY2 = pbox->y2; + if (partY2 > fullY2) + partY2 = fullY2; + + pbox++; + + if (partX1 < partX2 && partY1 < partY2) + (*pKaaScr->Solid) (partX1, partY1, + partX2, partY2); + } + } + } + (*pKaaScr->DoneSolid) (); + KdMarkSync(pDrawable->pScreen); +} + +void +kaaSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + FbBits pm, + FbBits fg, + int x1, + int y1, + int x2, + int y2) +{ + KaaScreenPriv (pDrawable->pScreen); + BoxPtr pbox; + int nbox; + int partX1, partX2, partY1, partY2; + CARD32 cmd; + + if ((*pKaaScr->PrepareSolid) (pDrawable, GXcopy, pm, fg)) + { + for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); + nbox--; + pbox++) + { + partX1 = pbox->x1; + if (partX1 < x1) + partX1 = x1; + + partX2 = pbox->x2; + if (partX2 > x2) + partX2 = x2; + + if (partX2 <= partX1) + continue; + + partY1 = pbox->y1; + if (partY1 < y1) + partY1 = y1; + + partY2 = pbox->y2; + if (partY2 > y2) + partY2 = y2; + + if (partY2 <= partY1) + continue; + + (*pKaaScr->Solid) (partX1, partY1, partX2, partY2); + } + (*pKaaScr->DoneSolid) (); + KdMarkSync(pDrawable->pScreen); + } + else + { + fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel); + fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2, + fbAnd (GXcopy, fg, pm), + fbXor (GXcopy, fg, pm)); + } +} + +void +kaaImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppciInit, + pointer pglyphBase) +{ + KaaScreenPriv (pDrawable->pScreen); + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + CharInfoPtr *ppci; + CharInfoPtr pci; + unsigned char *pglyph; /* pointer bits in glyph */ + int gWidth, gHeight; /* width and height of glyph */ + FbStride gStride; /* stride of glyph */ + Bool opaque; + int n; + int gx, gy; + void (*glyph) (FbBits *, + FbStride, + int, + FbStip *, + FbBits, + int, + int); + FbBits *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + FbBits depthMask; + + depthMask = FbFullMask(pDrawable->depth); + if ((pGC->planemask & depthMask) != depthMask) + { + KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); + return; + } + glyph = 0; + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; + case 24: glyph = fbGlyph24; break; + case 32: glyph = fbGlyph32; break; + } + + x += pDrawable->x; + y += pDrawable->y; + + if (TERMINALFONT (pGC->font) && !glyph) + { + opaque = TRUE; + } + else + { + int xBack, widthBack; + int yBack, heightBack; + + ppci = ppciInit; + n = nglyph; + widthBack = 0; + while (n--) + widthBack += (*ppci++)->metrics.characterWidth; + + xBack = x; + if (widthBack < 0) + { + xBack += widthBack; + widthBack = -widthBack; + } + yBack = y - FONTASCENT(pGC->font); + heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + kaaSolidBoxClipped (pDrawable, + fbGetCompositeClip(pGC), + pGC->planemask, + pGC->bgPixel, + xBack, + yBack, + xBack + widthBack, + yBack + heightBack); + opaque = FALSE; + } + + KdCheckSync (pDrawable->pScreen); + + ppci = ppciInit; + while (nglyph--) + { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + gx = x + pci->metrics.leftSideBearing; + gy = y - pci->metrics.ascent; + if (glyph && gWidth <= sizeof (FbStip) * 8 && + fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) + { + (*glyph) (dst + (gy - dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->fg, + gx - dstXoff, + gHeight); + } + else + { + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); + fbPutXYImage (pDrawable, + fbGetCompositeClip(pGC), + pPriv->fg, + pPriv->bg, + pPriv->pm, + GXcopy, + opaque, + + gx, + gy, + gWidth, gHeight, + + (FbStip *) pglyph, + gStride, + 0); + } + } + x += pci->metrics.characterWidth; + } +} + +static const GCOps kaaOps = { + kaaFillSpans, + KdCheckSetSpans, + KdCheckPutImage, + kaaCopyArea, + KdCheckCopyPlane, + KdCheckPolyPoint, + KdCheckPolylines, + KdCheckPolySegment, + miPolyRectangle, + KdCheckPolyArc, + miFillPolygon, + kaaPolyFillRect, + miPolyFillArc, + miPolyText8, + miPolyText16, + miImageText8, + miImageText16, + kaaImageGlyphBlt, + KdCheckPolyGlyphBlt, + KdCheckPushPixels, +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + +void +kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) +{ + FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC); + + fbValidateGC (pGC, changes, pDrawable); + + if (pDrawable->type == DRAWABLE_WINDOW) + pGC->ops = (GCOps *) &kaaOps; + else + pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; +} + +GCFuncs kaaGCFuncs = { + kaaValidateGC, + miChangeGC, + miCopyGC, + miDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip +}; + +int +kaaCreateGC (GCPtr pGC) +{ + if (!fbCreateGC (pGC)) + return FALSE; + + if (pGC->depth != 1) + pGC->funcs = &kaaGCFuncs; + + return TRUE; +} + +void +kaaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + KaaScreenPriv (pScreen); + RegionRec rgnDst; + int dx, dy; + WindowPtr pwinRoot; + + pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; + + dx = ptOldOrg.x - pWin->drawable.x; + dy = ptOldOrg.y - pWin->drawable.y; + REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); + + REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); + + REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); + + fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, + 0, + &rgnDst, dx, dy, kaaCopyNtoN, 0, 0); + + REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); +} + +void +kaaFillRegionSolid (DrawablePtr pDrawable, + RegionPtr pRegion, + Pixel pixel) +{ + KaaScreenPriv(pDrawable->pScreen); + + if ((*pKaaScr->PrepareSolid) (pDrawable, GXcopy, FB_ALLONES, pixel)) + { + int nbox = REGION_NUM_RECTS (pRegion); + BoxPtr pBox = REGION_RECTS (pRegion); + + while (nbox--) + { + (*pKaaScr->Solid) (pBox->x1, pBox->y1, pBox->x2, pBox->y2); + pBox++; + } + (*pKaaScr->DoneSolid) (); + KdMarkSync(pDrawable->pScreen); + } + else + fbFillRegionSolid (pDrawable, pRegion, 0, + fbReplicatePixel (pixel, pDrawable->bitsPerPixel)); +} + +void +kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) +{ + PixmapPtr pTile; + + if (!REGION_NUM_RECTS(pRegion)) + return; + switch (what) { + case PW_BACKGROUND: + switch (pWin->backgroundState) { + case None: + return; + case ParentRelative: + do { + pWin = pWin->parent; + } while (pWin->backgroundState == ParentRelative); + (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, + what); + return; + case BackgroundPixel: + kaaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel); + return; + } + break; + case PW_BORDER: + if (pWin->borderIsPixel) + { + kaaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel); + return; + } + break; + } + KdCheckPaintWindow (pWin, pRegion, what); +} + +Bool +kaaDrawInit (ScreenPtr pScreen, + KaaScreenPrivPtr pScreenPriv) +{ + if (kaaGeneration != serverGeneration) + { + kaaScreenPrivateIndex = AllocateScreenPrivateIndex(); + kaaGeneration = serverGeneration; + } + pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pScreenPriv; + + /* + * Hook up asynchronous drawing + */ + KdScreenInitAsync (pScreen); + /* + * Replace various fb screen functions + */ + pScreen->CreateGC = kaaCreateGC; + pScreen->CopyWindow = kaaCopyWindow; + pScreen->PaintWindowBackground = kaaPaintWindow; + pScreen->PaintWindowBorder = kaaPaintWindow; + + return TRUE; +} + diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index d90922079..35c2fc7a2 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.13 2001/05/23 03:29:44 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.14 2001/05/26 01:25:41 keithp Exp $ */ #include "kdrive.h" #ifdef PSEUDO8 @@ -342,6 +342,7 @@ KdParseScreen (KdScreenInfo *screen, screen->softCursor = kdSoftCursor; kdDumbDriver = FALSE; kdSoftCursor = FALSE; + screen->rotation = 0; screen->width = 0; screen->height = 0; screen->width_mm = 0; @@ -356,7 +357,7 @@ KdParseScreen (KdScreenInfo *screen, for (i = 0; i < 2; i++) { - arg = KdParseFindNext (arg, "x/", save, &delim); + arg = KdParseFindNext (arg, "x/@", save, &delim); if (!save[0]) return; @@ -365,7 +366,7 @@ KdParseScreen (KdScreenInfo *screen, if (delim == '/') { - arg = KdParseFindNext (arg, "x", save, &delim); + arg = KdParseFindNext (arg, "x@", save, &delim); if (!save[0]) return; mm = atoi(save); @@ -381,9 +382,27 @@ KdParseScreen (KdScreenInfo *screen, screen->height = pixels; screen->height_mm = mm; } - if (delim != 'x') + if (delim != 'x' && delim != '@') return; } + + 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; + } fb = 0; while (fb < KD_MAX_FB) diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index ca4a8db75..13385d248 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -102,6 +102,7 @@ typedef struct _KdScreenInfo { KdCardInfo *card; ScreenPtr pScreen; void *driver; + int rotation; int width; int height; int rate; @@ -225,6 +226,33 @@ typedef struct _KdMouseMatrix { int matrix[2][3]; } KdMouseMatrix; +typedef struct _KaaScreenPriv { + Bool (*PrepareSolid) (DrawablePtr pDrawable, + int alu, + Pixel planemask, + Pixel fg); + void (*Solid) (int x1, int y1, int x2, int y2); + void (*DoneSolid) (void); + + Bool (*PrepareCopy) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + Bool upsidedown, + Bool reverse, + int alu, + Pixel planemask); + void (*Copy) (int srcX, + int srcY, + int dstX, + int dstY, + int width, + int height); + void (*DoneCopy) (void); +} KaaScreenPrivRec, *KaaScreenPrivPtr; + +Bool +KaaInit (ScreenPtr pScreen, + KaaScreenPrivPtr pScreenPriv); + /* * This is the only completely portable way to * compute this info. diff --git a/hw/kdrive/trident/tridentdraw.c b/hw/kdrive/trident/tridentdraw.c index 9060018b8..0d28dd14b 100644 --- a/hw/kdrive/trident/tridentdraw.c +++ b/hw/kdrive/trident/tridentdraw.c @@ -70,620 +70,103 @@ CARD8 tridentRop[16] = { pixel = pixel | pixel << 16; \ } \ } -void -tridentFillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox, - unsigned long pixel, int alu) -{ - SetupTrident(pDrawable->pScreen); - CARD32 cmd; - tridentFillPix(pDrawable->bitsPerPixel,pixel); - _tridentInit(cop,tridentc); - _tridentSetSolidRect(cop,pixel,alu,cmd); - while (nBox--) - { - _tridentRect(cop,pBox->x1,pBox->y1,pBox->x2-1,pBox->y2-1,cmd); - pBox++; - } - KdMarkSync(pDrawable->pScreen); -} +static Cop *cop; +static CARD32 cmd; -void -tridentCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure) +Bool +tridentPrepareSolid (DrawablePtr pDrawable, + int alu, + Pixel pm, + Pixel fg) { - SetupTrident(pDstDrawable->pScreen); - int srcX, srcY, dstX, dstY; - int w, h; - CARD32 flags; - CARD32 cmd; - CARD8 alu; + FbBits depthMask; - if (pGC) - { - alu = pGC->alu; - if (sourceInvarient (pGC->alu)) - { - tridentFillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu); - return; - } - } + depthMask = FbFullMask(pDrawable->depth); + if ((pm & depthMask) != depthMask) + return FALSE; else - alu = GXcopy; - - _tridentInit(cop,tridentc); - cop->multi = COP_MULTI_PATTERN; - cop->multi = COP_MULTI_ROP | tridentRop[alu]; - if (reverse) - upsidedown = TRUE; - cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FB; - if (upsidedown) - cmd |= COP_X_REVERSE; - while (nbox--) { - if (upsidedown) - { - cop->src_start_xy = TRI_XY (pbox->x2 + dx - 1, - pbox->y2 + dy - 1); - cop->src_end_xy = TRI_XY (pbox->x1 + dx, - pbox->y1 + dy); - cop->dst_start_xy = TRI_XY (pbox->x2 - 1, - pbox->y2 - 1); - cop->dst_end_xy = TRI_XY (pbox->x1, - pbox->y1); - } - else - { - cop->src_start_xy = TRI_XY (pbox->x1 + dx, - pbox->y1 + dy); - cop->src_end_xy = TRI_XY (pbox->x2 + dx - 1, - pbox->y2 + dy - 1); - cop->dst_start_xy = TRI_XY (pbox->x1, - pbox->y1); - cop->dst_end_xy = TRI_XY (pbox->x2 - 1, - pbox->y2 - 1); - } - _tridentWaitDone(cop); - cop->command = cmd; - pbox++; + KdScreenPriv(pDrawable->pScreen); + tridentCardInfo(pScreenPriv); + cop = tridentc->cop; + + tridentFillPix(pDrawable->bitsPerPixel,fg); + _tridentInit(cop,tridentc); + _tridentSetSolidRect(cop,fg,alu,cmd); + return TRUE; } - KdMarkSync(pDstDrawable->pScreen); } -RegionPtr -tridentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty) +void +tridentSolid (int x1, int y1, int x2, int y2) +{ + _tridentRect (cop, x1, y1, x2 - 1, y2 - 1, cmd); +} + +void +tridentDoneSolid (void) +{ +} + +Bool +tridentPrepareCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + Bool upsidedown, + Bool reverse, + int alu, + Pixel pm) { - KdScreenPriv(pDstDrawable->pScreen); FbBits depthMask; - depthMask = FbFullMask (pDstDrawable->depth); - if ((pGC->planemask & depthMask) == depthMask && + if ((pm & depthMask) == depthMask && pSrcDrawable->type == DRAWABLE_WINDOW && pDstDrawable->type == DRAWABLE_WINDOW) { - return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, - dstx, dsty, tridentCopyNtoN, 0, 0); - } - return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, dstx, dsty); -} - -BOOL -tridentFillOk (GCPtr pGC) -{ - FbBits depthMask; - - depthMask = FbFullMask(pGC->depth); - if ((pGC->planemask & depthMask) != depthMask) - return FALSE; - switch (pGC->fillStyle) { - case FillSolid: + KdScreenPriv(pDstDrawable->pScreen); + tridentCardInfo(pScreenPriv); + cop = tridentc->cop; + _tridentInit(cop,tridentc); + cop->multi = COP_MULTI_PATTERN; + cop->multi = COP_MULTI_ROP | tridentRop[alu]; + cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FB; + if (upsidedown || reverse) + cmd |= COP_X_REVERSE; return TRUE; -#if 0 - case FillTiled: - return (tridentPatternDimOk (pGC->tile.pixmap->drawable.width) && - tridentPatternDimOk (pGC->tile.pixmap->drawable.height)); - case FillStippled: - case FillOpaqueStippled: - return (tridentPatternDimOk (pGC->stipple->drawable.width) && - tridentPatternDimOk (pGC->stipple->drawable.height)); -#endif - } - return FALSE; -} - -void -tridentFillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, - DDXPointPtr ppt, int *pwidth, int fSorted) -{ - SetupTrident(pDrawable->pScreen); - DDXPointPtr pptFree; - FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC); - int *pwidthFree;/* copies of the pointers to free */ - CARD32 cmd; - int nTmp; - INT16 x, y; - int width; - CARD32 pixel; - - if (!tridentFillOk (pGC)) - { - KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); - return; - } - nTmp = n * miFindMaxBand(fbGetCompositeClip(pGC)); - pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int)); - pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec)); - if(!pptFree || !pwidthFree) - { - if (pptFree) DEALLOCATE_LOCAL(pptFree); - if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree); - return; - } - n = miClipSpans(fbGetCompositeClip(pGC), - ppt, pwidth, n, - pptFree, pwidthFree, fSorted); - pwidth = pwidthFree; - ppt = pptFree; - _tridentInit(cop,tridentc); - switch (pGC->fillStyle) { - case FillSolid: - pixel = pGC->fgPixel; - tridentFillPix (pDrawable->bitsPerPixel,pixel); - _tridentSetSolidRect(cop,pixel,pGC->alu,cmd); - break; -#if 0 - case FillTiled: - cmd = tridentTilePrepare (pGC->tile.pixmap, - pGC->patOrg.x + pDrawable->x, - pGC->patOrg.y + pDrawable->y, - pGC->alu); - break; - default: - cmd = tridentStipplePrepare (pDrawable, pGC); - break; -#endif - } - while (n--) - { - x = ppt->x; - y = ppt->y; - ppt++; - width = *pwidth++; - if (width) - { - _tridentRect(cop,x,y,x + width - 1,y,cmd); - } - } - KdMarkSync(pDrawable->pScreen); - DEALLOCATE_LOCAL(pptFree); - DEALLOCATE_LOCAL(pwidthFree); -} - -#define NUM_STACK_RECTS 1024 - -void -tridentPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrectFill, xRectangle *prectInit) -{ - SetupTrident(pDrawable->pScreen); - xRectangle *prect; - RegionPtr prgnClip; - register BoxPtr pbox; - register BoxPtr pboxClipped; - BoxPtr pboxClippedBase; - BoxPtr pextent; - BoxRec stackRects[NUM_STACK_RECTS]; - FbGCPrivPtr fbPriv = fbGetGCPrivate (pGC); - int numRects; - int n; - int xorg, yorg; - int x, y; - - if (!tridentFillOk (pGC)) - { - KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit); - return; - } - prgnClip = fbGetCompositeClip(pGC); - xorg = pDrawable->x; - yorg = pDrawable->y; - - if (xorg || yorg) - { - prect = prectInit; - n = nrectFill; - while(n--) - { - prect->x += xorg; - prect->y += yorg; - prect++; - } - } - - prect = prectInit; - - numRects = REGION_NUM_RECTS(prgnClip) * nrectFill; - if (numRects > NUM_STACK_RECTS) - { - pboxClippedBase = (BoxPtr)xalloc(numRects * sizeof(BoxRec)); - if (!pboxClippedBase) - return; } else - pboxClippedBase = stackRects; - - pboxClipped = pboxClippedBase; - - if (REGION_NUM_RECTS(prgnClip) == 1) - { - int x1, y1, x2, y2, bx2, by2; - - pextent = REGION_RECTS(prgnClip); - x1 = pextent->x1; - y1 = pextent->y1; - x2 = pextent->x2; - y2 = pextent->y2; - while (nrectFill--) - { - if ((pboxClipped->x1 = prect->x) < x1) - pboxClipped->x1 = x1; - - if ((pboxClipped->y1 = prect->y) < y1) - pboxClipped->y1 = y1; - - bx2 = (int) prect->x + (int) prect->width; - if (bx2 > x2) - bx2 = x2; - pboxClipped->x2 = bx2; - - by2 = (int) prect->y + (int) prect->height; - if (by2 > y2) - by2 = y2; - pboxClipped->y2 = by2; - - prect++; - if ((pboxClipped->x1 < pboxClipped->x2) && - (pboxClipped->y1 < pboxClipped->y2)) - { - pboxClipped++; - } - } - } - else - { - int x1, y1, x2, y2, bx2, by2; - - pextent = REGION_EXTENTS(pGC->pScreen, prgnClip); - x1 = pextent->x1; - y1 = pextent->y1; - x2 = pextent->x2; - y2 = pextent->y2; - while (nrectFill--) - { - BoxRec box; - - if ((box.x1 = prect->x) < x1) - box.x1 = x1; - - if ((box.y1 = prect->y) < y1) - box.y1 = y1; - - bx2 = (int) prect->x + (int) prect->width; - if (bx2 > x2) - bx2 = x2; - box.x2 = bx2; - - by2 = (int) prect->y + (int) prect->height; - if (by2 > y2) - by2 = y2; - box.y2 = by2; - - prect++; - - if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) - continue; - - n = REGION_NUM_RECTS (prgnClip); - pbox = REGION_RECTS(prgnClip); - - /* clip the rectangle to each box in the clip region - this is logically equivalent to calling Intersect() - */ - while(n--) - { - pboxClipped->x1 = max(box.x1, pbox->x1); - pboxClipped->y1 = max(box.y1, pbox->y1); - pboxClipped->x2 = min(box.x2, pbox->x2); - pboxClipped->y2 = min(box.y2, pbox->y2); - pbox++; - - /* see if clipping left anything */ - if(pboxClipped->x1 < pboxClipped->x2 && - pboxClipped->y1 < pboxClipped->y2) - { - pboxClipped++; - } - } - } - } - if (pboxClipped != pboxClippedBase) - { - switch (pGC->fillStyle) { - case FillSolid: - tridentFillBoxSolid(pDrawable, - pboxClipped-pboxClippedBase, pboxClippedBase, - pGC->fgPixel, pGC->alu); - break; -#if 0 - case FillTiled: - tridentFillBoxTiled(pDrawable, - pboxClipped-pboxClippedBase, pboxClippedBase, - pGC->tile.pixmap, - pGC->patOrg.x + pDrawable->x, - pGC->patOrg.y + pDrawable->y, - pGC->alu); - break; - case FillStippled: - case FillOpaqueStippled: - tridentFillBoxStipple (pDrawable, pGC, - pboxClipped-pboxClippedBase, pboxClippedBase); - break; -#endif - } - } - if (pboxClippedBase != stackRects) - xfree(pboxClippedBase); -} - -void -tridentSolidBoxClipped (DrawablePtr pDrawable, - RegionPtr pClip, - int x1, - int y1, - int x2, - int y2, - FbBits fg) -{ - SetupTrident (pDrawable->pScreen); - BoxPtr pbox; - int nbox; - int partX1, partX2, partY1, partY2; - CARD32 cmd; - - _tridentInit (cop, tridentc); - _tridentSetSolidRect (cop, fg, GXcopy, cmd); - - for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); - nbox--; - pbox++) - { - partX1 = pbox->x1; - if (partX1 < x1) - partX1 = x1; - - partX2 = pbox->x2; - if (partX2 > x2) - partX2 = x2; - - if (partX2 <= partX1) - continue; - - partY1 = pbox->y1; - if (partY1 < y1) - partY1 = y1; - - partY2 = pbox->y2; - if (partY2 > y2) - partY2 = y2; - - if (partY2 <= partY1) - continue; - - _tridentRect(cop,partX1, partY1, partX2-1, partY2-1,cmd); - } - KdMarkSync(pDrawable->pScreen); -} - -void -tridentImageGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppciInit, - pointer pglyphBase) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); - CharInfoPtr *ppci; - CharInfoPtr pci; - unsigned char *pglyph; /* pointer bits in glyph */ - int gWidth, gHeight; /* width and height of glyph */ - FbStride gStride; /* stride of glyph */ - Bool opaque; - int n; - int gx, gy; - void (*glyph) (FbBits *, - FbStride, - int, - FbStip *, - FbBits, - int, - int); - FbBits *dst; - FbStride dstStride; - int dstBpp; - FbBits depthMask; - - depthMask = FbFullMask(pDrawable->depth); - if ((pGC->planemask & depthMask) != depthMask) - { - KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); - return; - } - glyph = 0; - fbGetDrawable (pDrawable, dst, dstStride, dstBpp); - switch (dstBpp) { - case 8: glyph = fbGlyph8; break; - case 16: glyph = fbGlyph16; break; - case 24: glyph = fbGlyph24; break; - case 32: glyph = fbGlyph32; break; - } - - x += pDrawable->x; - y += pDrawable->y; - - if (TERMINALFONT (pGC->font) && !glyph) - { - opaque = TRUE; - } - else - { - int xBack, widthBack; - int yBack, heightBack; - - ppci = ppciInit; - n = nglyph; - widthBack = 0; - while (n--) - widthBack += (*ppci++)->metrics.characterWidth; - - xBack = x; - if (widthBack < 0) - { - xBack += widthBack; - widthBack = -widthBack; - } - yBack = y - FONTASCENT(pGC->font); - heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); - tridentSolidBoxClipped (pDrawable, - fbGetCompositeClip(pGC), - xBack, - yBack, - xBack + widthBack, - yBack + heightBack, - pPriv->bg); - opaque = FALSE; - } - - KdCheckSync (pDrawable->pScreen); - - ppci = ppciInit; - while (nglyph--) - { - pci = *ppci++; - pglyph = FONTGLYPHBITS(pglyphBase, pci); - gWidth = GLYPHWIDTHPIXELS(pci); - gHeight = GLYPHHEIGHTPIXELS(pci); - if (gWidth && gHeight) - { - gx = x + pci->metrics.leftSideBearing; - gy = y - pci->metrics.ascent; - if (glyph && gWidth <= sizeof (FbStip) * 8 && - fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) - { - (*glyph) (dst + gy * dstStride, - dstStride, - dstBpp, - (FbStip *) pglyph, - pPriv->fg, - gx, - gHeight); - } - else - { - gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); - fbPutXYImage (pDrawable, - fbGetCompositeClip(pGC), - pPriv->fg, - pPriv->bg, - pPriv->pm, - GXcopy, - opaque, - - gx, - gy, - gWidth, gHeight, - - (FbStip *) pglyph, - gStride, - 0); - } - } - x += pci->metrics.characterWidth; - } -} - -static const GCOps tridentOps = { - tridentFillSpans, - KdCheckSetSpans, - KdCheckPutImage, - tridentCopyArea, - KdCheckCopyPlane, - KdCheckPolyPoint, - KdCheckPolylines, - KdCheckPolySegment, - miPolyRectangle, - KdCheckPolyArc, - miFillPolygon, - tridentPolyFillRect, - miPolyFillArc, - miPolyText8, - miPolyText16, - miImageText8, - miImageText16, - tridentImageGlyphBlt, - KdCheckPolyGlyphBlt, - KdCheckPushPixels, -#ifdef NEED_LINEHELPER - ,NULL -#endif -}; - -void -tridentValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) -{ - FbGCPrivPtr fbPriv = fbGetGCPrivate(pGC); - - fbValidateGC (pGC, changes, pDrawable); - - if (pDrawable->type == DRAWABLE_WINDOW) - pGC->ops = (GCOps *) &tridentOps; - else - pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; -} - -GCFuncs tridentGCFuncs = { - tridentValidateGC, - miChangeGC, - miCopyGC, - miDestroyGC, - miChangeClip, - miDestroyClip, - miCopyClip -}; - -int -tridentCreateGC (GCPtr pGC) -{ - if (!fbCreateGC (pGC)) return FALSE; +} - if (pGC->depth != 1) - pGC->funcs = &tridentGCFuncs; - - return TRUE; +void +tridentCopy (int srcX, + int srcY, + int dstX, + int dstY, + int w, + int h) +{ + if (cmd & COP_X_REVERSE) + { + cop->src_start_xy = TRI_XY (srcX + w - 1, srcY + h - 1); + cop->src_end_xy = TRI_XY (srcX, srcY); + cop->dst_start_xy = TRI_XY (dstX + w - 1, dstY + h - 1); + cop->dst_end_xy = TRI_XY (dstX, dstY); + } + else + { + cop->src_start_xy = TRI_XY (srcX, srcY); + cop->src_end_xy = TRI_XY (srcX + w - 1, srcY + h - 1); + cop->dst_start_xy = TRI_XY (dstX, dstY); + cop->dst_end_xy = TRI_XY (dstX + w - 1, dstY + h - 1); + } + _tridentWaitDone (cop); + cop->command = cmd; +} + +void +tridentDoneCopy (void) +{ } void @@ -710,10 +193,12 @@ tridentComposite (CARD8 op, FbBits *mskBits; FbStride mskStride; int mskBpp; + int mskXoff, mskYoff; CARD32 *src, *srcLine; CARD32 *off, *offLine; FbBits *srcBits; FbStride srcStride; + int srcXoff, srcYoff; FbStride offStride; int srcBpp; int x_msk, y_msk, x_src, y_src, x_dst, y_dst; @@ -767,13 +252,13 @@ tridentComposite (CARD8 op, xSrc += pSrc->pDrawable->x; ySrc += pSrc->pDrawable->y; - fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp); + fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); if (pMask) { xMask += pMask->pDrawable->x; yMask += pMask->pDrawable->y; - fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp); + fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp, mskXoff, mskYoff); mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8); } @@ -840,9 +325,9 @@ tridentComposite (CARD8 op, x_msk = x_dst - xDst + xMask; if (mode == MODE_IMAGE) - srcLine = (CARD32 *) srcBits + y_src * srcStride + x_src; + srcLine = (CARD32 *) srcBits + (y_src - srcYoff) * srcStride + (x_src - srcXoff); else - mskLine = (CARD8 *) mskBits + y_msk * mskStride + x_msk; + mskLine = (CARD8 *) mskBits + (y_msk - mskYoff) * mskStride + (x_msk - mskXoff); while (h) { @@ -914,104 +399,15 @@ tridentComposite (CARD8 op, } } -void -tridentCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - KdScreenPriv(pScreen); - RegionRec rgnDst; - int dx, dy; - WindowPtr pwinRoot; +KaaScreenPrivRec tridentKaa = { + tridentPrepareSolid, + tridentSolid, + tridentDoneSolid, - pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; - - dx = ptOldOrg.x - pWin->drawable.x; - dy = ptOldOrg.y - pWin->drawable.y; - REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); - - REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); - - REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); - - fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, - 0, - &rgnDst, dx, dy, tridentCopyNtoN, 0, 0); - - REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); -} - -void -tridentPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) -{ - KdScreenPriv(pWin->drawable.pScreen); - PixmapPtr pTile; - - if (!REGION_NUM_RECTS(pRegion)) - return; - switch (what) { - case PW_BACKGROUND: - switch (pWin->backgroundState) { - case None: - return; - case ParentRelative: - do { - pWin = pWin->parent; - } while (pWin->backgroundState == ParentRelative); - (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion, - what); - return; -#if 0 - case BackgroundPixmap: - pTile = pWin->background.pixmap; - if (tridentPatternDimOk (pTile->drawable.width) && - tridentPatternDimOk (pTile->drawable.height)) - { - tridentFillBoxTiled ((DrawablePtr)pWin, - (int)REGION_NUM_RECTS(pRegion), - REGION_RECTS(pRegion), - pTile, - pWin->drawable.x, pWin->drawable.y, GXcopy); - return; - } - break; -#endif - case BackgroundPixel: - tridentFillBoxSolid((DrawablePtr)pWin, - (int)REGION_NUM_RECTS(pRegion), - REGION_RECTS(pRegion), - pWin->background.pixel, GXcopy); - return; - } - break; - case PW_BORDER: - if (pWin->borderIsPixel) - { - tridentFillBoxSolid((DrawablePtr)pWin, - (int)REGION_NUM_RECTS(pRegion), - REGION_RECTS(pRegion), - pWin->border.pixel, GXcopy); - return; - } -#if 0 - else - { - pTile = pWin->border.pixmap; - if (tridentPatternDimOk (pTile->drawable.width) && - tridentPatternDimOk (pTile->drawable.height)) - { - tridentFillBoxTiled ((DrawablePtr)pWin, - (int)REGION_NUM_RECTS(pRegion), - REGION_RECTS(pRegion), - pTile, - pWin->drawable.x, pWin->drawable.y, GXcopy); - return; - } - } -#endif - break; - } - KdCheckPaintWindow (pWin, pRegion, what); -} + tridentPrepareCopy, + tridentCopy, + tridentDoneCopy, +}; Bool tridentDrawInit (ScreenPtr pScreen) @@ -1020,17 +416,8 @@ tridentDrawInit (ScreenPtr pScreen) tridentScreenInfo(pScreenPriv); PictureScreenPtr ps = GetPictureScreen(pScreen); - /* - * Hook up asynchronous drawing - */ - KdScreenInitAsync (pScreen); - /* - * Replace various fb screen functions - */ - pScreen->CreateGC = tridentCreateGC; - pScreen->CopyWindow = tridentCopyWindow; - pScreen->PaintWindowBackground = tridentPaintWindow; - pScreen->PaintWindowBorder = tridentPaintWindow; + if (!kaaDrawInit (pScreen, &tridentKaa)) + return FALSE; if (ps && tridents->off_screen) ps->Composite = tridentComposite; diff --git a/hw/kdrive/vesa/vbe.c b/hw/kdrive/vesa/vbe.c index fded83ec3..cb6d0d3a3 100644 --- a/hw/kdrive/vesa/vbe.c +++ b/hw/kdrive/vesa/vbe.c @@ -196,7 +196,7 @@ VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe) } int -VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear) +VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct) { int code; VbeInfoBlock vib; @@ -223,13 +223,16 @@ VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear) vbe->windowA_offset = vbe->windowB_offset = -1; vbe->last_window = 1; - if(vib.Capabilities[0] & 1) - palette_hi = 1; - if(vib.Capabilities[0] & 4) - palette_wait = 1; - - if(palette_hi || palette_wait) - VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait); + if (!direct) + { + if(vib.Capabilities[0] & 1) + palette_hi = 1; + if(vib.Capabilities[0] & 4) + palette_wait = 1; + + if(palette_hi || palette_wait) + VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait); + } return 0; } diff --git a/hw/kdrive/vesa/vbe.h b/hw/kdrive/vesa/vbe.h index 2bc3aab2a..bf347fc6b 100644 --- a/hw/kdrive/vesa/vbe.h +++ b/hw/kdrive/vesa/vbe.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$ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.h,v 1.5 2000/10/20 00:19:50 keithp Exp $ */ #ifndef _VBE_H #define _VBE_H @@ -128,7 +128,7 @@ VbeInfoPtr VbeInit (Vm86InfoPtr vi); int -VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear); +VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct); int VbeGetMode(Vm86InfoPtr vi, int *mode); diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c index f836fa38a..bbbbaac8f 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.8 2000/10/20 00:19:50 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.10 2001/05/26 01:25:41 keithp Exp $ */ #include "vesa.h" #ifdef RANDR @@ -32,12 +32,11 @@ 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 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) @@ -375,9 +374,6 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) int bpp, fbbpp; screen->driver = pscr; - pscr->rotate = FALSE; - if (screen->width < screen->height) - pscr->rotate = TRUE; if (!screen->width || !screen->height) { @@ -407,8 +403,10 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) 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 @@ -499,7 +497,7 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) ErrorF ("\tStatic color bpp %d depth %d\n", bpp, depth); } - pscr->rotate = FALSE; + pscr->rotate = 0; break; default: ErrorF("Unsupported VESA MemoryModel 0x%02X\n", @@ -507,6 +505,15 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) return FALSE; } + switch (fbbpp) { + case 8: + case 16: + case 32: + break; + default: + pscr->rotate = 0; + } + screen->width = vesaWidth(screen, mode); screen->height = vesaHeight(screen, mode); screen->fb[0].depth = depth; @@ -663,7 +670,8 @@ vesaWindowPlanar (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -677,7 +685,8 @@ vesaWindowLinear (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -691,7 +700,8 @@ vesaWindowWindowed (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -711,7 +721,8 @@ vesaWindowCga (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); VesaCardPrivPtr priv = pScreenPriv->card->driver; @@ -726,10 +737,11 @@ vesaWindowCga (ScreenPtr pScreen, } 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); @@ -738,6 +750,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; @@ -745,7 +758,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; @@ -771,11 +784,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; @@ -825,6 +839,7 @@ vesaCreateColormap16 (ColormapPtr pmap) { int i, j; + if (pmap->pVisual->ColormapEntries == 16) for (i = 0; i < pmap->pVisual->ColormapEntries; i++) { j = i & 0xf; @@ -967,7 +982,6 @@ vesaRandRSetConfig (ScreenPtr pScreen, mode->YResolution == pSize->height && 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 && @@ -987,12 +1001,44 @@ vesaRandRSetConfig (ScreenPtr pScreen, if (ret) { pscr->mode = *mode; + switch (screen->fb[0].bitsPerPixel) { + case 8: + case 16: + case 32: + 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; + } + break; + default: + pscr->rotate = 0; + break; + } screen->width = vesaWidth(screen, mode); screen->height = vesaHeight(screen, mode); pScreen->width = screen->width; pScreen->height = screen->height; - pScreen->mmWidth = pSize->mmWidth; - pScreen->mmHeight = pSize->mmHeight; + if (rotation == 90 || rotation == 270) + { + pScreen->mmWidth = pSize->mmHeight; + pScreen->mmHeight = pSize->mmWidth; + } + else + { + pScreen->mmWidth = pSize->mmWidth; + pScreen->mmHeight = pSize->mmHeight; + } #if 0 /* * XXX can't switch depths yet @@ -1038,6 +1084,7 @@ vesaInitScreen(ScreenPtr pScreen) ShadowUpdateProc update; ShadowWindowProc window; + if (pscr->shadow) { switch (pscr->mapping) { @@ -1056,7 +1103,7 @@ vesaInitScreen(ScreenPtr pScreen) else update = shadowUpdatePlanar4; window = vesaWindowPlanar; - pscr->rotate = FALSE; + pscr->rotate = 0; break; case VESA_MONO: update = vesaUpdateMono; @@ -1064,19 +1111,40 @@ vesaInitScreen(ScreenPtr pScreen) window = vesaWindowCga; else window = vesaWindowLinear; - pscr->rotate = FALSE; + pscr->rotate = 0; break; } - if (pscr->rotate) - { + switch (pscr->rotate) { + case 90: switch (pScreenPriv->screen->fb[0].bitsPerPixel) { case 8: - update = shadowUpdateRotate8; break; + update = shadowUpdateRotate8_90; break; case 16: - update = shadowUpdateRotate16; break; + update = shadowUpdateRotate16_90; break; case 32: - update = shadowUpdateRotate32; break; + 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; } return KdShadowInitScreen (pScreen, update, window); @@ -1102,7 +1170,8 @@ vesaSetMode (ScreenPtr pScreen, if (vesa_verbose) ErrorF ("Enable VBE mode 0x%x\n", mode->mode); code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode, - pscr->mapping == VESA_LINEAR); + pscr->mapping == VESA_LINEAR, + mode->MemoryModel == MEMORY_DIRECT); } else { @@ -1161,15 +1230,23 @@ 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 - { + 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; @@ -1249,7 +1326,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 { diff --git a/hw/kdrive/vesa/vesa.h b/hw/kdrive/vesa/vesa.h index b8922751d..d20c103eb 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.7 2000/10/20 00:19:50 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.h,v 1.8 2001/05/26 01:25:42 keithp Exp $ */ #ifndef _VESA_H_ #define _VESA_H_ @@ -90,7 +90,7 @@ typedef struct _VesaCardPriv { typedef struct _VesaScreenPriv { VesaModeRec mode; Bool shadow; - Bool rotate; + int rotate; int mapping; int origDepth; void *fb;