diff options
author | dawes <dawes> | 2001-08-22 18:00:12 +0000 |
---|---|---|
committer | dawes <dawes> | 2001-08-22 18:00:12 +0000 |
commit | 43b79bb01fb3ccf0785d8c1beed4d8710db48a8d (patch) | |
tree | c76efae431766da82895f2030fac3ca20d486e2b /xc/programs/Xserver/hw/kdrive | |
parent | 9d8ac1f4820f6a1984bcc9e4a4151ba9f0acdc1f (diff) |
Import of XFree86 4.1.99.1X_4_1_99_1
Diffstat (limited to 'xc/programs/Xserver/hw/kdrive')
49 files changed, 8336 insertions, 1321 deletions
diff --git a/xc/programs/Xserver/hw/kdrive/Imakefile b/xc/programs/Xserver/hw/kdrive/Imakefile index fd7488492..24eb377b9 100644 --- a/xc/programs/Xserver/hw/kdrive/Imakefile +++ b/xc/programs/Xserver/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.8 2001/05/29 04:54:10 keithp Exp $ KDRIVE=. #include "Kdrive.tmpl" @@ -13,10 +13,14 @@ XVSRCS=kxv.c XVOBJS=kxv.o #endif -SRCS = kcmap.c kcolor.c kdrive.c kinfo.c kinput.c kmap.c knoop.c ktest.c \ +#if XipaqServer +DEFINES = -DXIPAQ +#endif + +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/xc/programs/Xserver/hw/kdrive/Kdrive.tmpl b/xc/programs/Xserver/hw/kdrive/Kdrive.tmpl index 5b3a65a56..7c7763085 100644 --- a/xc/programs/Xserver/hw/kdrive/Kdrive.tmpl +++ b/xc/programs/Xserver/hw/kdrive/Kdrive.tmpl @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Kdrive.tmpl,v 1.1 2000/09/03 05:11:46 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Kdrive.tmpl,v 1.3 2001/05/29 04:54:10 keithp Exp $ #include <Server.tmpl> @@ -6,8 +6,13 @@ XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/Kdrive.tmpl,v 1.1 2000/09/03 05:11 RENDERINCS=-I$(KDRIVE)/../../render -I$(EXTINCSRC) #endif +#if BuildRandR +RANDRINCS=-I$(KDRIVE)/../../randr -I$(EXTINCSRC) +#endif + 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) + -I$(EXTINCSRC) -I$(XINCLUDESRC) $(RENDERINCS) $(RANDRINCS) diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile b/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile index 4f371869d..575838a9f 100644 --- a/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile +++ b/xc/programs/Xserver/hw/kdrive/fbdev/Imakefile @@ -1,8 +1,12 @@ XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $ -XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.3 2000/12/01 00:01:31 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/Imakefile,v 1.5 2001/05/24 19:31:46 alanh Exp $ KDRIVE=.. #include "../Kdrive.tmpl" +#if XipaqServer +DEFINES = -DXIPAQ +#endif + SRCS = fbdev.c fbinit.c OBJS = fbdev.o fbinit.o diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c index f5225ca22..be4ad327c 100644 --- a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c +++ b/xc/programs/Xserver/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.11 2001/03/30 02:15:20 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.28 2001/07/24 19:06:03 keithp Exp $ */ #include "fbdev.h" @@ -86,28 +86,67 @@ fbdevCardInit (KdCardInfo *card) return TRUE; } +#define FBDEV_KLUDGE_FORMAT +#ifdef FBDEV_KLUDGE_FORMAT +static Pixel +fbdevMakeContig (Pixel orig, Pixel others) +{ + Pixel low; + + low = lowbit (orig) >> 1; + while (low && (others & low) == 0) + { + orig |= low; + low >>= 1; + } + return orig; +} +#endif + Bool fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) { FbdevPriv *priv = screen->card->driver; Pixel allbits; int depth; - Bool rotate; Bool shadow; + Bool gray; #ifdef FAKE24_ON_16 Bool fake24; #endif depth = priv->var.bits_per_pixel; + gray = priv->var.grayscale; switch (priv->fix.visual) { case FB_VISUAL_PSEUDOCOLOR: - screen->fb[0].visuals = ((1 << StaticGray) | - (1 << GrayScale) | - (1 << StaticColor) | - (1 << PseudoColor) | - (1 << TrueColor) | - (1 << DirectColor)); + if (gray) + { + screen->fb[0].visuals = (1 << StaticGray); + /* could also support GrayScale, but what's the point? */ + } + else + { + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + } + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + case FB_VISUAL_STATIC_PSEUDOCOLOR: + if (gray) + { + screen->fb[0].visuals = (1 << StaticGray); + } + else + { + screen->fb[0].visuals = (1 << StaticColor); + } screen->fb[0].blueMask = 0x00; screen->fb[0].greenMask = 0x00; screen->fb[0].redMask = 0x00; @@ -119,11 +158,24 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) screen->fb[0].redMask = Mask (priv->var.red.offset, priv->var.red.length); screen->fb[0].greenMask = Mask (priv->var.green.offset, priv->var.green.length); screen->fb[0].blueMask = Mask (priv->var.blue.offset, priv->var.blue.length); -#ifdef ITSY - screen->fb[0].redMask = 0xf800; - screen->fb[0].greenMask = 0x07e0; - screen->fb[0].blueMask = 0x001f; -#endif +#ifdef FBDEV_KLUDGE_FORMAT + /* + * This is a kludge so that Render will work -- fill in the gaps + * in the pixel + */ + screen->fb[0].redMask = fbdevMakeContig (screen->fb[0].redMask, + screen->fb[0].greenMask| + screen->fb[0].blueMask); + + screen->fb[0].greenMask = fbdevMakeContig (screen->fb[0].greenMask, + screen->fb[0].redMask| + screen->fb[0].blueMask); + + screen->fb[0].blueMask = fbdevMakeContig (screen->fb[0].blueMask, + screen->fb[0].redMask| + screen->fb[0].greenMask); + +#endif allbits = screen->fb[0].redMask | screen->fb[0].greenMask | screen->fb[0].blueMask; depth = 32; while (depth && !(allbits & (1 << (depth - 1)))) @@ -134,15 +186,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 +207,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 +240,8 @@ fbdevWindowLinear (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); FbdevPriv *priv = pScreenPriv->card->driver; @@ -295,18 +334,64 @@ fbdevUpdateFake24 (ScreenPtr pScreen, } #endif /* FAKE24_ON_16 */ -Bool -fbdevInitScreen (ScreenPtr pScreen) +LayerPtr +fbdevLayerCreate (ScreenPtr pScreen) { KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; FbdevPriv *priv = pScreenPriv->card->driver; - FbdevScrPriv *scrpriv = pScreenPriv->screen->driver; + FbdevScrPriv *scrpriv = screen->driver; + LayerPtr pLayer; ShadowUpdateProc update; ShadowWindowProc window; + PixmapPtr pPixmap; + int kind; + KdMouseMatrix m; + switch (scrpriv->rotation) { + case 0: + pScreen->width = screen->width; + pScreen->height = screen->height; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + scrpriv->shadow = FALSE; + m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0; + m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0; + break; + case 90: + pScreen->width = screen->height; + pScreen->height = screen->width; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + scrpriv->shadow = TRUE; + m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = screen->height - 1; + m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0; + break; + case 180: + pScreen->width = screen->width; + pScreen->height = screen->height; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + scrpriv->shadow = TRUE; + m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = screen->width - 1; + m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = screen->height - 1; + break; + case 270: + pScreen->width = screen->height; + pScreen->height = screen->width; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + scrpriv->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] = screen->width - 1; + break; + } + KdSetMouseMatrix (&m); + if (scrpriv->shadow) { window = fbdevWindowLinear; + update = 0; #ifdef FAKE24_ON_16 if (pScreenPriv->screen->fb[0].bitsPerPixel == 24 && priv->var.bits_per_pixel == 16) { @@ -315,25 +400,292 @@ fbdevInitScreen (ScreenPtr pScreen) 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; - } - } + if (scrpriv->rotation) + update = shadowUpdateRotatePacked; + else + update = shadowUpdatePacked; + } + if (!update) + abort (); + 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, scrpriv->rotation, 0); +} + + +#ifdef RANDR +Bool +fbdevRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + KdScreenInfo *screen = pScreenPriv->screen; + FbdevScrPriv *scrpriv = screen->driver; + RRVisualGroupPtr pVisualGroup; + RRGroupOfVisualGroupPtr pGroupOfVisualGroup; + RRScreenSizePtr pSize; + Rotation rotateKind; + int rotation; + int n; + + *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270; + + for (n = 0; n < pScreen->numDepths; n++) + if (pScreen->allowedDepths[n].numVids) + break; + if (n == pScreen->numDepths) + return FALSE; + + pVisualGroup = RRCreateVisualGroup (pScreen); + if (!pVisualGroup) + return FALSE; + if (!RRAddDepthToVisualGroup (pScreen, + pVisualGroup, + &pScreen->allowedDepths[n])) + { + RRDestroyVisualGroup (pScreen, pVisualGroup); + return FALSE; + } + + pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup); + if (!pVisualGroup) + return FALSE; + + pGroupOfVisualGroup = RRCreateGroupOfVisualGroup (pScreen); + + if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen, + pGroupOfVisualGroup, + pVisualGroup)) + { + RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + /* pVisualGroup left until screen closed */ + return FALSE; + } + + pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + if (!pGroupOfVisualGroup) + return FALSE; + + pSize = RRRegisterSize (pScreen, + screen->width, + screen->height, + screen->width_mm, + screen->height_mm, + pGroupOfVisualGroup); + + rotation = scrpriv->rotation - screen->rotation; + if (rotation < 0) + rotation += 360; + + switch (rotation) + { + case 0: + rotateKind = RR_Rotate_0; + break; + case 90: + rotateKind = RR_Rotate_90; + break; + case 180: + rotateKind = RR_Rotate_180; + break; + case 270: + rotateKind = RR_Rotate_270; + break; + } + + RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup); + + return TRUE; +} + +int +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, + Rotation rotateKind, + RRScreenSizePtr pSize, + RRVisualGroupPtr pVisualGroup) +{ + 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 = screen->rotation; + break; + case RR_Rotate_90: + rotation = screen->rotation + 90; + break; + case RR_Rotate_180: + rotation = screen->rotation + 180; + break; + case RR_Rotate_270: + rotation = screen->rotation + 270; + break; + } + if (rotation >= 360) + rotation -= 360; + + if (scrpriv->rotation != rotation) + { + LayerPtr pNewLayer; + int kind; + int oldrotation = scrpriv->rotation; + int oldshadow = scrpriv->shadow; + int oldwidth = pScreen->width; + int oldheight = pScreen->height; + PixmapPtr pPixmap; + + if (wasEnabled) + KdDisableScreen (pScreen); + + scrpriv->rotation = rotation; + pNewLayer = fbdevLayerCreate (pScreen); + if (!pNewLayer) + { + scrpriv->shadow = oldshadow; + scrpriv->rotation = oldrotation; + } + if (WalkTree (pScreen, fbdevLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING) + { + WalkTree (pScreen, fbdevLayerRemove, (pointer) pNewLayer); + LayerDestroy (pScreen, pNewLayer); + scrpriv->rotation = oldrotation; + scrpriv->shadow = oldshadow; + pScreen->width = oldwidth; + pScreen->height = oldheight; + if (wasEnabled) + KdEnableScreen (pScreen); + return FALSE; } - return KdShadowInitScreen (pScreen, update, window); + WalkTree (pScreen, fbdevLayerRemove, (pointer) scrpriv->pLayer); + LayerDestroy (pScreen, scrpriv->pLayer); + scrpriv->pLayer = pNewLayer; + if (wasEnabled) + KdEnableScreen (pScreen); } return TRUE; } +Bool +fbdevRandRInit (ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRScreenInit (pScreen)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = fbdevRandRGetInfo; + pScrPriv->rrSetConfig = fbdevRandRSetConfig; + return TRUE; +} +#endif + +Bool +fbdevCreateColormap (ColormapPtr pmap) +{ + ScreenPtr pScreen = pmap->pScreen; + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + VisualPtr pVisual; + int i; + int nent; + xColorItem *pdefs; + + switch (priv->fix.visual) { + case FB_VISUAL_STATIC_PSEUDOCOLOR: + pVisual = pmap->pVisual; + nent = pVisual->ColormapEntries; + pdefs = ALLOCATE_LOCAL (nent * sizeof (xColorItem)); + if (!pdefs) + return FALSE; + for (i = 0; i < nent; i++) + pdefs[i].pixel = i; + fbdevGetColors (pScreen, 0, nent, pdefs); + for (i = 0; i < nent; i++) + { + pmap->red[i].co.local.red = pdefs[i].red; + pmap->red[i].co.local.green = pdefs[i].green; + pmap->red[i].co.local.blue = pdefs[i].blue; + } + DEALLOCATE_LOCAL (pdefs); + return TRUE; + default: + return fbInitializeColormap (pmap); + } +} + +#ifdef TOUCHSCREEN +int TsFbdev = -1; +#endif + +Bool +fbdevInitScreen (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + FbdevScrPriv *scrpriv = pScreenPriv->screen->driver; + ShadowUpdateProc update; + ShadowWindowProc window; + +#ifdef TOUCHSCREEN + TsFbdev = pScreen->myNum; +#endif + + pScreen->CreateColormap = fbdevCreateColormap; + + if (!LayerStartInit (pScreen)) + return FALSE; + if (!LayerFinishInit (pScreen)) + return FALSE; + scrpriv->pLayer = fbdevLayerCreate (pScreen); + if (!scrpriv->pLayer) + return FALSE; +#ifdef RANDR + if (!fbdevRandRInit (pScreen)) + return FALSE; +#endif + return TRUE; +} + void fbdevPreserve (KdCardInfo *card) { @@ -343,10 +695,10 @@ Bool fbdevEnable (ScreenPtr pScreen) { KdScreenPriv(pScreen); - FbdevPriv *priv = pScreenPriv->card->driver; + KdScreenInfo *screen = pScreenPriv->screen; + FbdevPriv *priv = pScreenPriv->card->driver; FbdevScrPriv *scrpriv = pScreenPriv->screen->driver; int k; - KdMouseMatrix m; priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL; @@ -357,16 +709,7 @@ 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 - { - 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; - } + if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR) { struct fb_cmap cmap; @@ -389,7 +732,6 @@ fbdevEnable (ScreenPtr pScreen) cmap.transp = 0; ioctl (priv->fd, FBIOPUTCMAP, &cmap); } - KdSetMouseMatrix (&m); return TRUE; } @@ -398,14 +740,23 @@ fbdevDPMS (ScreenPtr pScreen, int mode) { KdScreenPriv(pScreen); FbdevPriv *priv = pScreenPriv->card->driver; + static int oldmode = -1; + if (mode == oldmode) + return TRUE; #ifdef FBIOPUT_POWERMODE if (ioctl (priv->fd, FBIOPUT_POWERMODE, &mode) >= 0) + { + oldmode = mode; return TRUE; + } #endif #ifdef FBIOBLANK if (ioctl (priv->fd, FBIOBLANK, mode ? mode + 1 : 0) >= 0) + { + oldmode = mode; return TRUE; + } #endif return FALSE; } @@ -424,9 +775,6 @@ void fbdevScreenFini (KdScreenInfo *screen) { FbdevScrPriv *scrpriv = screen->driver; - - if (scrpriv->shadow) - KdShadowScreenFini (screen); } void @@ -512,3 +860,32 @@ fbdevPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) cmap.transp = 0; ioctl (priv->fd, FBIOPUTCMAP, &cmap); } + + +KdCardFuncs fbdevFuncs = { + fbdevCardInit, /* cardinit */ + fbdevScreenInit, /* scrinit */ + fbdevInitScreen, /* initScreen */ + fbdevPreserve, /* preserve */ + fbdevEnable, /* enable */ + fbdevDPMS, /* dpms */ + fbdevDisable, /* disable */ + fbdevRestore, /* restore */ + fbdevScreenFini, /* scrfini */ + fbdevCardFini, /* cardfini */ + + 0, /* initCursor */ + 0, /* enableCursor */ + 0, /* disableCursor */ + 0, /* finiCursor */ + 0, /* recolorCursor */ + + 0, /* initAccel */ + 0, /* enableAccel */ + 0, /* syncAccel */ + 0, /* disableAccel */ + 0, /* finiAccel */ + + fbdevGetColors, /* getColors */ + fbdevPutColors, /* putColors */ +}; diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h index 830ed62b9..2e33564c1 100644 --- a/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h +++ b/xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h @@ -21,15 +21,20 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h,v 1.8 2000/09/27 20:46:36 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h,v 1.11 2001/06/03 21:52:45 keithp Exp $ */ #ifndef _FBDEV_H_ #define _FBDEV_H_ -#include "kdrive.h" #include <stdio.h> #include <linux/fb.h> #include <unistd.h> #include <sys/mman.h> +#include "kdrive.h" +#include "layer.h" + +#ifdef RANDR +#include "randrstr.h" +#endif typedef struct _fbdevPriv { struct fb_var_screeninfo var; @@ -43,10 +48,13 @@ typedef struct _fbdevPriv { } FbdevPriv; typedef struct _fbdevScrPriv { - Bool rotate; + int rotation; Bool shadow; + LayerPtr pLayer; } FbdevScrPriv; +extern KdCardFuncs fbdevFuncs; + Bool fbdevInitialize (KdCardInfo *card, FbdevPriv *priv); diff --git a/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c b/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c index 3ec4a60cc..902174b1b 100644 --- a/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c +++ b/xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c @@ -21,38 +21,10 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.6 2000/09/28 20:58:21 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbinit.c,v 1.8 2001/05/29 17:47:55 keithp Exp $ */ #include <fbdev.h> -KdCardFuncs fbdevFuncs = { - fbdevCardInit, /* cardinit */ - fbdevScreenInit, /* scrinit */ - fbdevInitScreen, /* initScreen */ - fbdevPreserve, /* preserve */ - fbdevEnable, /* enable */ - fbdevDPMS, /* dpms */ - fbdevDisable, /* disable */ - fbdevRestore, /* restore */ - fbdevScreenFini, /* scrfini */ - fbdevCardFini, /* cardfini */ - - 0, /* initCursor */ - 0, /* enableCursor */ - 0, /* disableCursor */ - 0, /* finiCursor */ - 0, /* recolorCursor */ - - 0, /* initAccel */ - 0, /* enableAccel */ - 0, /* syncAccel */ - 0, /* disableAccel */ - 0, /* finiAccel */ - - fbdevGetColors, /* getColors */ - fbdevPutColors, /* putColors */ -}; - void InitCard (char *name) { diff --git a/xc/programs/Xserver/hw/kdrive/i810/i810.c b/xc/programs/Xserver/hw/kdrive/i810/i810.c index 2ad214f8d..7c85a516c 100644 --- a/xc/programs/Xserver/hw/kdrive/i810/i810.c +++ b/xc/programs/Xserver/hw/kdrive/i810/i810.c @@ -32,7 +32,7 @@ of the copyright holder. X Window System is a trademark of The Open Group */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/i810/i810.c,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/i810/i810.c,v 1.2 2001/07/20 19:35:30 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/xc/programs/Xserver/hw/kdrive/igs/igsdraw.c b/xc/programs/Xserver/hw/kdrive/igs/igsdraw.c index a93c0b248..1445686f7 100644 --- a/xc/programs/Xserver/hw/kdrive/igs/igsdraw.c +++ b/xc/programs/Xserver/hw/kdrive/igs/igsdraw.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/igs/igsdraw.c,v 1.2 2000/05/24 23:52:48 keithp Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/igs/igsdraw.c,v 1.3 2001/05/29 04:54:11 keithp Exp $ * * Copyright © 2000 Keith Packard * @@ -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/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile b/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile new file mode 100644 index 000000000..8fb723ca2 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/ipaq/Imakefile @@ -0,0 +1,13 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/Imakefile,v 1.1 2001/05/23 17:28:39 alanh Exp $ +KDRIVE=.. +#include "../Kdrive.tmpl" + +SRCS = ipaq.c + +OBJS = ipaq.o + +INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev -I$(KDRIVE)/pcmcia + +NormalLibraryObjectRule() +NormalLibraryTarget(ipaq,$(OBJS)) +DependTarget() diff --git a/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c b/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c new file mode 100644 index 000000000..b281c213b --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c @@ -0,0 +1,89 @@ +/* + * Copyright © 1999 Keith Packard + * + * 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. + * + * Adapted from ts300.c by Alan Hourihane <alanh@fairlite.demon.co.uk> + * For the Compaq IPAQ handheld, with the HP VGA Out Card (F1252A). + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/ipaq/ipaq.c,v 1.2 2001/05/29 17:47:55 keithp Exp $ */ + +#include "pcmcia.h" + +extern KdCardFuncs pcmciaFuncs; + +void +InitCard (char *name) +{ + KdCardAttr attr; + if (name && !strcmp(name, "pcmcia")) + KdCardInfoAdd (&pcmciaFuncs, &attr, 0); + else + KdCardInfoAdd (&fbdevFuncs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ +#ifdef __powerpc__ + KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs); +#else + KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); +#endif +#ifdef TOUCHSCREEN + KdInitTouchScreen (&TsFuncs); +#endif +} + +extern pcmciaDisplayModeRec pcmciaDefaultModes[]; + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + int ret; + + if (!strcmp (argv[i], "-listmodes")) + { + int j = 0, bpp = 0; + ErrorF("Valid modes are....\n\n"); + + for (bpp = 8; bpp < 24; bpp += 8) { + while (pcmciaDefaultModes[j].Width != 0) { + if ((pcmciaDefaultModes[j].Width * + pcmciaDefaultModes[j].Height * bpp/8) <= 512 * 1024) { + ErrorF("%dx%dx%dx%d\n", + pcmciaDefaultModes[j].Width, + pcmciaDefaultModes[j].Height, + bpp, + pcmciaDefaultModes[j].Refresh); + } + j++; + } + j = 0; + } + exit(1); + } + return KdProcessArgument (argc, argv, i); +} diff --git a/xc/programs/Xserver/hw/kdrive/kaa.c b/xc/programs/Xserver/hw/kdrive/kaa.c new file mode 100644 index 000000000..3e362cfb8 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/kaa.c @@ -0,0 +1,636 @@ +/* + * $XFree86: xc/programs/Xserver/hw/kdrive/kaa.c,v 1.5 2001/06/29 13:55:53 keithp Exp $ + * + * 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) +{ + ScreenPtr pScreen = pDrawable->pScreen; + KdScreenPriv (pScreen); + KaaScreenPriv (pScreen); + RegionPtr pClip = fbGetCompositeClip(pGC); + BoxPtr pextent, pbox; + int nbox; + int extentX1, extentX2, extentY1, extentY2; + int fullX1, fullX2, fullY1; + int partX1, partX2; + + if (!pScreenPriv->enabled || + 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) +{ + KdScreenPriv (pDstDrawable->pScreen); + KaaScreenPriv (pDstDrawable->pScreen); + int srcX, srcY, dstX, dstY; + int w, h; + CARD32 flags; + CARD32 cmd; + CARD8 alu; + + if (pScreenPriv->enabled && + pSrcDrawable->type == DRAWABLE_WINDOW && + (*pKaaScr->PrepareCopy) (pSrcDrawable, + pDstDrawable, + dx, + dy, + 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) +{ + KdScreenPriv (pDrawable->pScreen); + 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 (!pScreenPriv->enabled || + 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) +{ + KdScreenPriv (pDrawable->pScreen); + KaaScreenPriv (pDrawable->pScreen); + BoxPtr pbox; + int nbox; + int partX1, partX2, partY1, partY2; + CARD32 cmd; + + if (!pScreenPriv->enabled || + !(*pKaaScr->PrepareSolid) (pDrawable, GXcopy, pm, fg)) + { + KdCheckSync (pDrawable->pScreen); + fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel); + fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2, + fbAnd (GXcopy, fg, pm), + fbXor (GXcopy, fg, pm)); + return; + } + 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); +} + +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; + + 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) +{ + KdScreenPriv(pDrawable->pScreen); + KaaScreenPriv(pDrawable->pScreen); + + if (pScreenPriv->enabled && + (*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 + { + KdCheckSync (pDrawable->pScreen); + 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/xc/programs/Xserver/hw/kdrive/kasync.c b/xc/programs/Xserver/hw/kdrive/kasync.c index 4f016ed90..1b5b0bce8 100644 --- a/xc/programs/Xserver/hw/kdrive/kasync.c +++ b/xc/programs/Xserver/hw/kdrive/kasync.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/kasync.c,v 1.8 2001/03/30 02:15:19 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kasync.c,v 1.9 2001/06/04 09:45:41 keithp Exp $ */ #include "kdrive.h" @@ -60,7 +60,8 @@ RegionPtr KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty) { - KdCheckSync (pSrc->pScreen); + if (pSrc->type == DRAWABLE_WINDOW || pDst->type == DRAWABLE_WINDOW) + KdCheckSync (pSrc->pScreen); return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); } @@ -69,7 +70,8 @@ KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, int w, int h, int dstx, int dsty, unsigned long bitPlane) { - KdCheckSync (pSrc->pScreen); + if (pSrc->type == DRAWABLE_WINDOW || pDst->type == DRAWABLE_WINDOW) + KdCheckSync (pSrc->pScreen); return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, bitPlane); } diff --git a/xc/programs/Xserver/hw/kdrive/kdrive.c b/xc/programs/Xserver/hw/kdrive/kdrive.c index d88e95d9f..9597a80d3 100644 --- a/xc/programs/Xserver/hw/kdrive/kdrive.c +++ b/xc/programs/Xserver/hw/kdrive/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.12 2001/03/30 02:15:20 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.c,v 1.19 2001/07/24 21:26:17 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 @@ -105,6 +106,10 @@ KdSetRootClip (ScreenPtr pScreen, BOOL enable) box.y1 = 0; box.x2 = pScreen->width; box.y2 = pScreen->height; + pWin->drawable.width = pScreen->width; + pWin->drawable.height = pScreen->height; + REGION_INIT (pScreen, &pWin->winSize, &box, 1); + REGION_INIT (pScreen, &pWin->borderSize, &box, 1); REGION_RESET(pScreen, &pWin->borderClip, &box); REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); } @@ -228,6 +233,45 @@ KdDisableScreens (void) } } +void +KdSuspend (void) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (kdEnabled) + { + for (card = kdCardInfo; card; card = card->next) + { + for (screen = card->screenList; screen; screen = screen->next) + if (screen->mynum == card->selected && screen->pScreen) + KdDisableScreen (screen->pScreen); + if (card->driver) + (*card->cfuncs->restore) (card); + } + KdDisableInput (); + } +} + +void +KdResume (void) +{ + KdCardInfo *card; + KdScreenInfo *screen; + + if (kdEnabled) + { + for (card = kdCardInfo; card; card = card->next) + { + (*card->cfuncs->preserve) (card); + for (screen = card->screenList; screen; screen = screen->next) + if (screen->mynum == card->selected && screen->pScreen) + KdEnableScreen (screen->pScreen); + } + KdEnableInput (); + } +} + Bool KdEnableScreen (ScreenPtr pScreen) { @@ -336,8 +380,8 @@ 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; screen->width_mm = 0; @@ -352,7 +396,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; @@ -361,7 +405,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); @@ -377,9 +421,33 @@ KdParseScreen (KdScreenInfo *screen, screen->height = pixels; screen->height_mm = mm; } - if (delim != 'x') + if (delim != 'x' && delim != '@') return; } + + kdOrigin.x += screen->width; + kdOrigin.y = 0; + kdDumbDriver = FALSE; + kdSoftCursor = FALSE; + + if (delim == '@') + { + arg = KdParseFindNext (arg, "x", save, &delim); + 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; while (fb < KD_MAX_FB) @@ -473,6 +541,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 @@ -648,7 +735,12 @@ 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; /* * This is done in this order so that backing store wraps * our GC functions; fbFinishScreenInit initializes MI @@ -657,7 +749,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) if (!fbSetupScreen (pScreen, screen->fb[0].frameBuffer, screen->width, screen->height, - 75, 75, + monitorResolution, monitorResolution, screen->fb[0].pixelStride, screen->fb[0].bitsPerPixel)) { @@ -690,7 +782,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) screen->fb[0].frameBuffer, screen->fb[1].frameBuffer, screen->width, screen->height, - 75, 75, + monitorResolution, monitorResolution, screen->fb[0].pixelStride, screen->fb[1].pixelStride, screen->fb[0].bitsPerPixel, @@ -707,7 +799,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) if (!fbFinishScreenInit (pScreen, screen->fb[0].frameBuffer, screen->width, screen->height, - 75, 75, + monitorResolution, monitorResolution, screen->fb[0].pixelStride, screen->fb[0].bitsPerPixel)) { @@ -721,8 +813,12 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) */ if (screen->width_mm) pScreen->mmWidth = screen->width_mm; + else + screen->width_mm = pScreen->mmWidth; if (screen->height_mm) pScreen->mmHeight = screen->height_mm; + else + screen->height_mm = pScreen->mmHeight; /* * Plug in our own block/wakeup handlers. @@ -735,7 +831,6 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) if (!fbPictureInit (pScreen, 0, 0)) return FALSE; #endif - if (card->cfuncs->initScreen) if (!(*card->cfuncs->initScreen) (pScreen)) return FALSE; @@ -748,6 +843,10 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) (void) p8Init (pScreen, PSEUDO8_USE_DEFAULT); #endif + if (card->cfuncs->finishInitScreen) + if (!(*card->cfuncs->finishInitScreen) (pScreen)) + return FALSE; + #if 0 fbInitValidateTree (pScreen); #endif diff --git a/xc/programs/Xserver/hw/kdrive/kdrive.h b/xc/programs/Xserver/hw/kdrive/kdrive.h index 1d4690213..72aa689dc 100644 --- a/xc/programs/Xserver/hw/kdrive/kdrive.h +++ b/xc/programs/Xserver/hw/kdrive/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.13 2001/03/30 02:15:20 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kdrive.h,v 1.20 2001/08/09 20:45:15 dawes Exp $ */ #include <stdio.h> #include "X.h" @@ -102,6 +102,7 @@ typedef struct _KdScreenInfo { KdCardInfo *card; ScreenPtr pScreen; void *driver; + int rotation; int width; int height; int rate; @@ -110,6 +111,7 @@ typedef struct _KdScreenInfo { Bool dumb; Bool softCursor; int mynum; + DDXPointRec origin; KdFrameBuffer fb[KD_MAX_FB]; } KdScreenInfo; @@ -139,6 +141,8 @@ typedef struct _KdCardFuncs { void (*getColors) (ScreenPtr, int, int, xColorItem *); void (*putColors) (ScreenPtr, int, int, xColorItem *); + + Bool (*finishInitScreen) (ScreenPtr pScreen); } KdCardFuncs; #define KD_MAX_PSEUDO_DEPTH 8 @@ -165,25 +169,15 @@ typedef struct { typedef struct _KdMouseFuncs { int (*Init) (void); - void (*Read) (int); - void (*Fini) (int); + void (*Fini) (void); } KdMouseFuncs; -#ifdef TOUCHSCREEN -typedef struct _KdTsFuncs { - int (*Init) (void); - void (*Read) (int); - void (*Fini) (int); -} KdTsFuncs; -#endif - typedef struct _KdKeyboardFuncs { void (*Load) (void); int (*Init) (void); - void (*Read) (int); void (*Leds) (int); void (*Bell) (int, int, int); - void (*Fini) (int); + void (*Fini) (void); int LockLed; } KdKeyboardFuncs; @@ -225,6 +219,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. @@ -263,6 +284,17 @@ extern KdOsFuncs *kdOsFuncs; #define KdMarkSync(s) (KdGetScreenPriv(s)->card->needSync = TRUE) +/* kaa.c */ +Bool +kaaDrawInit (ScreenPtr pScreen, + KaaScreenPrivPtr pScreenPriv); + +void +kaaWrapGC (GCPtr pGC); + +void +kaaUnwrapGC (GCPtr pGC); + /* kasync.c */ void KdCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, @@ -434,6 +466,12 @@ void KdEnableScreens (void); void +KdSuspend (void); + +void +KdResume (void); + +void KdProcessSwitch (void); void @@ -501,9 +539,18 @@ KdScreenInfoDispose (KdScreenInfo *si); void KdInitInput(KdMouseFuncs *, KdKeyboardFuncs *); +int +KdAllocInputType (void); + +Bool +KdRegisterFd (int type, int fd, void (*read) (int fd, void *closure), void *closure); + +void +KdUnregisterFds (int type, Bool do_close); + #ifdef TOUCHSCREEN void -KdInitTouchScreen(KdTsFuncs *pTsFuncs); +KdInitTouchScreen(KdMouseFuncs *pTsFuncs); #endif void @@ -553,8 +600,9 @@ ProcessInputEvents (); extern KdMouseFuncs Ps2MouseFuncs; extern KdMouseFuncs BusMouseFuncs; +extern KdMouseFuncs MsMouseFuncs; #ifdef TOUCHSCREEN -extern KdTsFuncs TsFuncs; +extern KdMouseFuncs TsFuncs; #endif extern KdKeyboardFuncs LinuxKeyboardFuncs; extern KdOsFuncs LinuxFuncs; diff --git a/xc/programs/Xserver/hw/kdrive/kinput.c b/xc/programs/Xserver/hw/kdrive/kinput.c index 887efcbc9..7d6109eee 100644 --- a/xc/programs/Xserver/hw/kdrive/kinput.c +++ b/xc/programs/Xserver/hw/kdrive/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.13.2.1 2001/05/25 18:50:08 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kinput.c,v 1.20 2001/08/09 09:06:08 keithp Exp $ */ #include "kdrive.h" #include "inputstr.h" @@ -37,8 +37,6 @@ static DeviceIntPtr pKdKeyboard, pKdPointer; static KdMouseFuncs *kdMouseFuncs; static KdKeyboardFuncs *kdKeyboardFuncs; -static int kdMouseFd = -1; -static int kdKeyboardFd = -1; static unsigned long kdEmulationTimeout; static Bool kdTimeoutPending; static int kdBellPitch; @@ -53,8 +51,7 @@ static KdMouseMatrix kdMouseMatrix = { }; #ifdef TOUCHSCREEN -static KdTsFuncs *kdTsFuncs; -static int kdTsFd = -1; +static KdMouseFuncs *kdTsFuncs; #endif int kdMinScanCode; @@ -78,17 +75,26 @@ CARD8 kdKeyState[KD_KEY_COUNT/8]; #define IsKeyDown(key) ((kdKeyState[(key) >> 3] >> ((key) & 7)) & 1) +#define KD_MAX_INPUT_FDS 8 + +typedef struct _kdInputFd { + int type; + int fd; + void (*read) (int fd, void *closure); + void *closure; +} KdInputFd; + +KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; +int kdNumInputFds; +int kdInputTypeSequence; + void KdSigio (int sig) { -#ifdef TOUCHSCREEN - if (kdTsFd >= 0) - (*kdTsFuncs->Read) (kdTsFd); -#endif - if (kdMouseFd >= 0) - (*kdMouseFuncs->Read) (kdMouseFd); - if (kdKeyboardFd >= 0) - (*kdKeyboardFuncs->Read) (kdKeyboardFd); + int i; + + for (i = 0; i < kdNumInputFds; i++) + (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); } void @@ -111,7 +117,7 @@ KdUnblockSigio (void) sigprocmask (SIG_UNBLOCK, &set, 0); } -#define VERIFY_SIGIO +#undef VERIFY_SIGIO #ifdef VERIFY_SIGIO void @@ -127,7 +133,7 @@ KdAssertSigioBlocked (char *where) #else -#define KdVerifySigioBlocked(s) +#define KdAssertSigioBlocked(s) #endif @@ -183,17 +189,56 @@ KdRemoveFd (int fd) } } +int +KdAllocInputType (void) +{ + return ++kdInputTypeSequence; +} + +Bool +KdRegisterFd (int type, int fd, void (*read) (int fd, void *closure), void *closure) +{ + if (kdNumInputFds == KD_MAX_INPUT_FDS) + return FALSE; + kdInputFds[kdNumInputFds].type = type; + kdInputFds[kdNumInputFds].fd = fd; + kdInputFds[kdNumInputFds].read = read; + kdInputFds[kdNumInputFds].closure = closure; + ++kdNumInputFds; + if (kdInputEnabled) + KdAddFd (fd); + return TRUE; +} + +void +KdUnregisterFds (int type, Bool do_close) +{ + int i; + + for (i = 0; i < kdNumInputFds;) + { + if (kdInputFds[i].type == type) + { + if (kdInputEnabled) + KdRemoveFd (kdInputFds[i].fd); + if (do_close) + close (kdInputFds[i].fd); + --kdNumInputFds; + for (; i < kdNumInputFds; i++) + kdInputFds[i] = kdInputFds[i+1]; + } + else + i++; + } +} + void KdDisableInput (void) { -#ifdef TOUCHSCREEN - if (kdTsFd >= 0) - KdRemoveFd (kdTsFd); -#endif - if (kdMouseFd >= 0) - KdRemoveFd (kdMouseFd); - if (kdKeyboardFd >= 0) - KdRemoveFd (kdKeyboardFd); + int i; + + for (i = 0; i < kdNumInputFds; i++) + KdRemoveFd (kdInputFds[i].fd); kdInputEnabled = FALSE; } @@ -201,16 +246,12 @@ void KdEnableInput (void) { xEvent xE; + int i; kdInputEnabled = TRUE; -#ifdef TOUCHSCREEN - if (kdTsFd >= 0) - KdAddFd (kdTsFd); -#endif - if (kdMouseFd >= 0) - KdAddFd (kdMouseFd); - if (kdKeyboardFd >= 0) - KdAddFd (kdKeyboardFd); + for (i = 0; i < kdNumInputFds; i++) + KdAddFd (kdInputFds[i].fd); + /* reset screen saver */ xE.u.keyButtonPointer.time = GetTimeInMillis (); NoticeEventTime (&xE); @@ -241,18 +282,10 @@ KdMouseProc(DeviceIntPtr pDevice, int onoff) pDev->on = TRUE; pKdPointer = pDevice; if (kdMouseFuncs) - { - kdMouseFd = (*kdMouseFuncs->Init) (); - if (kdMouseFd >= 0 && kdInputEnabled) - KdAddFd (kdMouseFd); - } + (*kdMouseFuncs->Init) (); #ifdef TOUCHSCREEN if (kdTsFuncs) - { - kdTsFd = (*kdTsFuncs->Init) (); - if (kdTsFd >= 0 && kdInputEnabled) - KdAddFd (kdTsFd); - } + (*kdTsFuncs->Init) (); #endif break; case DEVICE_OFF: @@ -261,21 +294,11 @@ KdMouseProc(DeviceIntPtr pDevice, int onoff) { pDev->on = FALSE; pKdPointer = 0; - if (kdMouseFd >= 0) - { - if (kdInputEnabled) - KdRemoveFd (kdMouseFd); - (*kdMouseFuncs->Fini) (kdMouseFd); - kdMouseFd = -1; - } + if (kdMouseFuncs) + (*kdMouseFuncs->Fini) (); #ifdef TOUCHSCREEN - if (kdTsFd >= 0) - { - if (kdInputEnabled) - KdRemoveFd (kdTsFd); - (*kdTsFuncs->Fini) (kdTsFd); - kdTsFd = -1; - } + if (kdTsFuncs >= 0) + (*kdTsFuncs->Fini) (); #endif } break; @@ -354,11 +377,7 @@ KdKeybdProc(DeviceIntPtr pDevice, int onoff) pDev->on = TRUE; pKdKeyboard = pDevice; if (kdKeyboardFuncs) - { - kdKeyboardFd = (*kdKeyboardFuncs->Init) (); - if (kdKeyboardFd >= 0 && kdInputEnabled) - KdAddFd (kdKeyboardFd); - } + (*kdKeyboardFuncs->Init) (); break; case DEVICE_OFF: case DEVICE_CLOSE: @@ -366,13 +385,8 @@ KdKeybdProc(DeviceIntPtr pDevice, int onoff) if (pDev->on) { pDev->on = FALSE; - if (kdKeyboardFd >= 0) - { - if (kdInputEnabled) - KdRemoveFd (kdKeyboardFd); - (*kdKeyboardFuncs->Fini) (kdKeyboardFd); - kdKeyboardFd = -1; - } + if (kdKeyboardFuncs) + (*kdKeyboardFuncs->Fini) (); } break; } @@ -497,7 +511,7 @@ KdInitInput(KdMouseFuncs *pMouseFuncs, #ifdef TOUCHSCREEN void -KdInitTouchScreen(KdTsFuncs *pTsFuncs) +KdInitTouchScreen(KdMouseFuncs *pTsFuncs) { kdTsFuncs = pTsFuncs; } @@ -992,7 +1006,7 @@ extern int nClients; void KdCheckSpecialKeys(xEvent *xE) { - KeySym sym; + KeySym sym = KEYCOL1(xE->u.u.detail); if (!pKdKeyboard) return; @@ -1001,7 +1015,25 @@ KdCheckSpecialKeys(xEvent *xE) */ if (xE->u.u.type == KeyRelease) return; - + +#ifdef XIPAQ + /* + * Check for buttons 1, 2 and 3 on the iPAQ + */ + if (sym == XK_Pointer_Button1) { + KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_1, 0, 0); + return; + } + if (sym == XK_Pointer_Button2) { + KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_2, 0, 0); + return; + } + if (sym == XK_Pointer_Button3) { + KdEnqueueMouseEvent(KD_MOUSE_DELTA | KD_BUTTON_3, 0, 0); + return; + } +#endif + /* * Check for control/alt pressed */ @@ -1009,7 +1041,6 @@ KdCheckSpecialKeys(xEvent *xE) (ControlMask|Mod1Mask)) return; - sym = KEYCOL1(xE->u.u.detail); /* * Let OS function see keysym first @@ -1337,29 +1368,17 @@ KdWakeupHandler (int screen, { int result = (int) lresult; fd_set *pReadmask = (fd_set *) readmask; + int i; if (kdInputEnabled && result > 0) { - if (kdMouseFd >= 0 && FD_ISSET (kdMouseFd, pReadmask)) - { - KdBlockSigio (); - (*kdMouseFuncs->Read) (kdMouseFd); - KdUnblockSigio (); - } -#ifdef TOUCHSCREEN - if (kdTsFd >= 0 && FD_ISSET (kdTsFd, pReadmask)) - { - KdBlockSigio (); - (*kdTsFuncs->Read) (kdTsFd); - KdUnblockSigio (); - } -#endif - if (kdKeyboardFd >= 0 && FD_ISSET (kdKeyboardFd, pReadmask)) - { - KdBlockSigio (); - (*kdKeyboardFuncs->Read) (kdKeyboardFd); - KdUnblockSigio (); - } + for (i = 0; i < kdNumInputFds; i++) + if (FD_ISSET (kdInputFds[i].fd, pReadmask)) + { + KdBlockSigio (); + (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); + KdUnblockSigio (); + } } if (kdTimeoutPending) { @@ -1375,69 +1394,117 @@ 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; - } - 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; + { + 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; + } + } } - 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 KdCrossScreen(ScreenPtr pScreen, Bool entering) { +#ifndef XIPAQ if (entering) KdEnableScreen (pScreen); else KdDisableScreen (pScreen); +#endif } +#ifdef TOUCHSCREEN +/* HACK! */ +extern int TsScreen; +#endif + static void KdWarpCursor (ScreenPtr pScreen, int x, int y) { KdBlockSigio (); +#ifdef TOUCHSCREEN + TsScreen = pScreen->myNum; +#endif miPointerWarpCursor (pScreen, x, y); KdUnblockSigio (); } diff --git a/xc/programs/Xserver/hw/kdrive/kmap.c b/xc/programs/Xserver/hw/kdrive/kmap.c index 0f96cca96..3602023e5 100644 --- a/xc/programs/Xserver/hw/kdrive/kmap.c +++ b/xc/programs/Xserver/hw/kdrive/kmap.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/kmap.c,v 1.7 2001/03/30 02:15:20 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kmap.c,v 1.10 2001/07/24 21:26:17 keithp Exp $ */ #include "kdrive.h" @@ -67,7 +67,11 @@ KdMapDevice (CARD32 addr, CARD32 size) void *a; int fd; +#ifdef __arm__ + fd = open ("/dev/mem", O_RDWR|O_SYNC); +#else fd = open ("/dev/mem", O_RDWR); +#endif if (fd < 0) FatalError ("KdMapDevice: failed to open /dev/mem (%s)\n", strerror (errno)); @@ -117,7 +121,7 @@ KdSetMappedMode (CARD32 addr, CARD32 size, int mode) mtrr = open ("/proc/mtrr", 2); if (mtrr > 0) { - base = addr & ~((1<22)-1); + base = addr & ~((1<<22)-1); bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1); switch (mode) { case KD_MAPPED_MODE_REGISTERS: @@ -131,7 +135,9 @@ KdSetMappedMode (CARD32 addr, CARD32 size, int mode) sentry.size = bound - base; sentry.type = type; - ioctl (mtrr, MTRRIOC_ADD_ENTRY, &sentry); + if (ioctl (mtrr, MTRRIOC_ADD_ENTRY, &sentry) < 0) + ErrorF ("MTRRIOC_ADD_ENTRY failed 0x%x 0x%x %d (errno %d)\n", + base, bound - base, type, errno); } #endif } @@ -150,7 +156,7 @@ KdResetMappedMode (CARD32 addr, CARD32 size, int mode) mtrr = open ("/proc/mtrr", 2); if (mtrr > 0) { - base = addr & ~((1<22)-1); + base = addr & ~((1<<22)-1); bound = ((addr + size) + ((1<<22) - 1)) & ~((1<<22) - 1); switch (mode) { case KD_MAPPED_MODE_REGISTERS: @@ -164,7 +170,9 @@ KdResetMappedMode (CARD32 addr, CARD32 size, int mode) sentry.size = bound - base; sentry.type = type; - ioctl (mtrr, MTRRIOC_DEL_ENTRY, &sentry); + if (ioctl (mtrr, MTRRIOC_DEL_ENTRY, &sentry) < 0) + ErrorF ("MTRRIOC_DEL_ENTRY failed 0x%x 0x%x %d (errno %d)\n", + base, bound - base, type, errno); } #endif } diff --git a/xc/programs/Xserver/hw/kdrive/kxv.c b/xc/programs/Xserver/hw/kdrive/kxv.c index 27eb7ddb5..f97781087 100644 --- a/xc/programs/Xserver/hw/kdrive/kxv.c +++ b/xc/programs/Xserver/hw/kdrive/kxv.c @@ -35,7 +35,7 @@ of the copyright holder. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.c,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.c,v 1.3 2001/08/09 09:08:54 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); + return (KdXVGeneration == serverGeneration && + GET_XV_SCREEN(pScreen) != 0); +} - if(ret) WalkTree(pScreen, KdXVReputAllVideo, 0); +Bool +KdXVEnable(ScreenPtr pScreen) +{ + KdXVScreenPtr ScreenPriv; + + if (!KdXVRunning (pScreen)) + return TRUE; + + WalkTree(pScreen, KdXVReputAllVideo, 0); - return ret; + return TRUE; } -static void +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 ****/ @@ -1660,8 +1654,8 @@ KdXVPutImage( VPBox.x1 = 0; VPBox.y1 = 0; - VPBox.x2 = screen->width; - VPBox.y2 = screen->height; + VPBox.x2 = pScreen->width; + VPBox.y2 = pScreen->height; REGION_INIT(pScreen, &VPReg, &VPBox, 1); REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg); diff --git a/xc/programs/Xserver/hw/kdrive/kxv.h b/xc/programs/Xserver/hw/kdrive/kxv.h index a75bd529c..47b33335d 100644 --- a/xc/programs/Xserver/hw/kdrive/kxv.h +++ b/xc/programs/Xserver/hw/kdrive/kxv.h @@ -35,7 +35,7 @@ of the copyright holder. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.h,v 1.1 2001/03/30 02:18:41 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kxv.h,v 1.2 2001/07/20 19:35:29 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/xc/programs/Xserver/hw/kdrive/linux/Imakefile b/xc/programs/Xserver/hw/kdrive/linux/Imakefile index c4d080a0e..01530486d 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/Imakefile +++ b/xc/programs/Xserver/hw/kdrive/linux/Imakefile @@ -1,5 +1,5 @@ XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $ -XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/linux/Imakefile,v 1.5 2001/03/30 02:15:20 keithp Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/linux/Imakefile,v 1.6 2001/08/09 20:45:15 dawes Exp $ KDRIVE=.. #include "../Kdrive.tmpl" @@ -8,9 +8,9 @@ TSSRCS = ts.c TSOBJS = ts.o #endif -SRCS = keyboard.c linux.c ps2.c bus.c agp.c $(TSSRCS) +SRCS = keyboard.c linux.c ps2.c ms.c bus.c agp.c $(TSSRCS) -OBJS = keyboard.o linux.o ps2.o bus.o agp.o $(TSOBJS) +OBJS = keyboard.o linux.o ps2.o ms.o bus.o agp.o $(TSOBJS) INCLUDES = -I. $(KDINCS) diff --git a/xc/programs/Xserver/hw/kdrive/linux/bus.c b/xc/programs/Xserver/hw/kdrive/linux/bus.c index e47471ef7..dc377066e 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/bus.c +++ b/xc/programs/Xserver/hw/kdrive/linux/bus.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/linux/bus.c,v 1.1 2000/09/22 06:25:09 keithp Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/linux/bus.c,v 1.2 2001/06/29 14:00:41 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -33,7 +33,7 @@ /* /dev/adbmouse is a busmouse */ void -BusRead (int adbPort) +BusRead (int adbPort, void *closure) { unsigned char buf[3]; unsigned char *b; @@ -64,29 +64,36 @@ char *BusNames[] = { #define NUM_BUS_NAMES (sizeof (BusNames) / sizeof (BusNames[0])) +int BusInputType; + int BusInit (void) { int i; int busPort; + int n = 0; + if (!BusInputType) + BusInputType = KdAllocInputType (); + for (i = 0; i < NUM_BUS_NAMES; i++) { busPort = open (BusNames[i], 0); - if (busPort >= 0) - return busPort; + { + KdRegisterFd (BusInputType, busPort, BusRead, 0); + n++; + } } + return n; } void -BusFini (int busPort) +BusFini (void) { - if (busPort >= 0) - close (busPort); + KdUnregisterFds (BusInputType, TRUE); } KdMouseFuncs BusMouseFuncs = { BusInit, - BusRead, BusFini }; diff --git a/xc/programs/Xserver/hw/kdrive/linux/keyboard.c b/xc/programs/Xserver/hw/kdrive/linux/keyboard.c index 687d36240..78b1191c4 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/keyboard.c +++ b/xc/programs/Xserver/hw/kdrive/linux/keyboard.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/linux/keyboard.c,v 1.6 2001/03/30 02:15:20 keithp Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/linux/keyboard.c,v 1.7 2001/06/29 14:00:41 keithp Exp $ * * Copyright © 1999 Keith Packard * @@ -376,14 +376,35 @@ LinuxKeyboardLoad (void) readKernelMapping (); } +void +LinuxKeyboardRead (int fd, void *closure) +{ + unsigned char buf[256], *b; + int n; + + while ((n = read (fd, buf, sizeof (buf))) > 0) + { + b = buf; + while (n--) + { + KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80); + b++; + } + } +} + static int LinuxKbdTrans; static struct termios LinuxTermios; +static int LinuxKbdType; int LinuxKeyboardInit (void) { struct termios nTty; + if (!LinuxKbdType) + LinuxKbdType = KdAllocInputType (); + ioctl (LinuxConsoleFd, KDGKBMODE, &LinuxKbdTrans); tcgetattr (LinuxConsoleFd, &LinuxTermios); @@ -398,31 +419,16 @@ LinuxKeyboardInit (void) cfsetispeed(&nTty, 9600); cfsetospeed(&nTty, 9600); tcsetattr(LinuxConsoleFd, TCSANOW, &nTty); - return LinuxConsoleFd; + KdRegisterFd (LinuxKbdType, LinuxConsoleFd, LinuxKeyboardRead, 0); + return 1; } void -LinuxKeyboardFini (int fd) +LinuxKeyboardFini (void) { ioctl(LinuxConsoleFd, KDSKBMODE, LinuxKbdTrans); tcsetattr(LinuxConsoleFd, TCSANOW, &LinuxTermios); -} - -void -LinuxKeyboardRead (int fd) -{ - unsigned char buf[256], *b; - int n; - - while ((n = read (fd, buf, sizeof (buf))) > 0) - { - b = buf; - while (n--) - { - KdEnqueueKeyboardEvent (b[0] & 0x7f, b[0] & 0x80); - b++; - } - } + KdUnregisterFds (LinuxKbdType, FALSE); } void @@ -447,7 +453,6 @@ LinuxKeyboardBell (int volume, int pitch, int duration) KdKeyboardFuncs LinuxKeyboardFuncs = { LinuxKeyboardLoad, LinuxKeyboardInit, - LinuxKeyboardRead, LinuxKeyboardLeds, LinuxKeyboardBell, LinuxKeyboardFini, diff --git a/xc/programs/Xserver/hw/kdrive/linux/linux.c b/xc/programs/Xserver/hw/kdrive/linux/linux.c index 2c5e0d0be..c7b4f8154 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/linux.c +++ b/xc/programs/Xserver/hw/kdrive/linux/linux.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/linux/linux.c,v 1.5 2001/03/30 02:15:20 keithp Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/linux/linux.c,v 1.6 2001/07/24 21:26:17 keithp Exp $ * * Copyright © 1999 Keith Packard * @@ -30,9 +30,11 @@ #include <sys/stat.h> #include <sys/ioctl.h> #include <keysym.h> +#include <linux/apm_bios.h> static int vtno; int LinuxConsoleFd; +int LinuxApmFd = -1; static int activeVT; static Bool enabled; @@ -256,6 +258,65 @@ LinuxSetSwitchMode (int mode) } void +LinuxApmBlock (pointer blockData, OSTimePtr pTimeout, pointer pReadmask) +{ +} + +static Bool LinuxApmRunning; + +void +LinuxApmWakeup (pointer blockData, int result, pointer pReadmask) +{ + fd_set *readmask = (fd_set *) pReadmask; + + if (result > 0 && LinuxApmFd >= 0 && FD_ISSET (LinuxApmFd, readmask)) + { + apm_event_t event; + Bool running = LinuxApmRunning; + int cmd = APM_IOC_SUSPEND; + + while (read (LinuxApmFd, &event, sizeof (event)) == sizeof (event)) + { + switch (event) { + case APM_SYS_STANDBY: + case APM_USER_STANDBY: + running = FALSE; + cmd = APM_IOC_STANDBY; + break; + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + case APM_CRITICAL_SUSPEND: + running = FALSE; + cmd = APM_IOC_SUSPEND; + break; + case APM_NORMAL_RESUME: + case APM_CRITICAL_RESUME: + case APM_STANDBY_RESUME: + running = TRUE; + break; + } + } + if (running && !LinuxApmRunning) + { + KdResume (); + LinuxApmRunning = TRUE; + } + else if (!running && LinuxApmRunning) + { + KdSuspend (); + LinuxApmRunning = FALSE; + ioctl (LinuxApmFd, cmd, 0); + } + } +} + +#ifdef FNONBLOCK +#define NOBLOCK FNONBLOCK +#else +#define NOBLOCK FNDELAY +#endif + +void LinuxEnable (void) { if (enabled) @@ -266,6 +327,18 @@ LinuxEnable (void) ioctl (LinuxConsoleFd, VT_RELDISP, VT_ACKACQ); } /* + * Open the APM driver + */ + LinuxApmFd = open ("/dev/apm_bios", 0); + if (LinuxApmFd >= 0) + { + LinuxApmRunning = TRUE; + fcntl (LinuxApmFd, F_SETFL, fcntl (LinuxApmFd, F_GETFL) | NOBLOCK); + RegisterBlockAndWakeupHandlers (LinuxApmBlock, LinuxApmWakeup, 0); + AddEnabledDevice (LinuxApmFd); + } + + /* * now get the VT */ LinuxSetSwitchMode (VT_AUTO); @@ -314,6 +387,13 @@ LinuxDisable (void) ioctl (LinuxConsoleFd, VT_RELDISP, 1); } enabled = FALSE; + if (LinuxApmFd >= 0) + { + RemoveBlockAndWakeupHandlers (LinuxApmBlock, LinuxApmWakeup, 0); + RemoveEnabledDevice (LinuxApmFd); + close (LinuxApmFd); + LinuxApmFd = -1; + } } void diff --git a/xc/programs/Xserver/hw/kdrive/linux/ms.c b/xc/programs/Xserver/hw/kdrive/linux/ms.c new file mode 100644 index 000000000..9c30d2c38 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/linux/ms.c @@ -0,0 +1,158 @@ +/* +Copyright (c) 2001 by Juliusz Chroboczek +Copyright (c) 1999 by Keith Packard + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +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/linux/ms.c,v 1.1 2001/08/09 20:45:15 dawes Exp $ */ + +#define NEED_EVENTS +#include "X.h" +#include "Xproto.h" +#include "inputstr.h" +#include "scrnintstr.h" +#include "kdrive.h" +#include "Xpoll.h" +#include <errno.h> +#include <termios.h> + +int +MsReadBytes (int fd, char *buf, int len, int min) +{ + int n, tot; + fd_set set; + struct timeval tv; + + tot = 0; + while (len) + { + n = read (fd, buf, len); + if (n > 0) + { + tot += n; + buf += n; + len -= n; + } + if (tot % min == 0) + break; + FD_ZERO (&set); + FD_SET (fd, &set); + tv.tv_sec = 0; + tv.tv_usec = 100 * 1000; + n = select (fd + 1, &set, 0, 0, &tv); + if (n <= 0) + break; + } + return tot; +} + +void +MsRead (int port) +{ + unsigned char buf[3 * 200]; + unsigned char *b; + int n; + int dx, dy; + unsigned long flags; + + while ((n = MsReadBytes (port, buf, sizeof (buf), 3)) > 0) + { + b = buf; + while (n >= 3) + { + flags = KD_MOUSE_DELTA; + + if (b[0] & 0x20) + flags |= KD_BUTTON_1; + if (b[0] & 0x10) + flags |= KD_BUTTON_3; + + dx = (char)(((b[0] & 0x03) << 6) | (b[1] & 0x3F)); + dy = (char)(((b[0] & 0x0C) << 4) | (b[2] & 0x3F)); + n -= 3; + b += 3; + KdEnqueueMouseEvent (flags, dx, dy); + } + } +} + +int +MsInit (void) +{ + int port; + char *device = "/dev/mouse"; + struct termios t; + int ret; + + port = open (device, O_RDWR | O_NONBLOCK); + if(port < 0) { + ErrorF("Couldn't open %s (%d)\n", device, (int)errno); + return 0; + } else if (port == 0) { + ErrorF("Opening %s returned 0! Please complain to Keith.\n", + device); + close(port); + return 0; + } + + if(!isatty(port)) { + ErrorF("%s is not a tty\n", device); + goto bail; + } + + ret = tcgetattr(port, &t); + if(ret < 0) { + ErrorF("Couldn't tcgetattr(%s): %d\n", device, errno); + goto bail; + } + t.c_iflag &= ~ (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | + IGNCR | ICRNL | IXON | IXOFF); + t.c_oflag &= ~ OPOST; + t.c_lflag &= ~ (ECHO | ECHONL | ICANON | ISIG | IEXTEN); + t.c_cflag &= ~ (CSIZE | PARENB); + t.c_cflag |= CS8 | CLOCAL | CSTOPB; + + cfsetispeed (&t, B1200); + cfsetospeed (&t, B1200); + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + ret = tcsetattr(port, TCSANOW, &t); + if(ret < 0) { + ErrorF("Couldn't tcsetattr(%s): %d\n", device, errno); + goto bail; + } + return port; + + bail: + close(port); + return 0; +} + +void +MsFini (int port) +{ + if (port >= 0) + close(port); +} + +KdMouseFuncs MsMouseFuncs = { + MsInit, + MsRead, + MsFini +}; diff --git a/xc/programs/Xserver/hw/kdrive/linux/ps2.c b/xc/programs/Xserver/hw/kdrive/linux/ps2.c index 386bf23ad..c2ee1744a 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/ps2.c +++ b/xc/programs/Xserver/hw/kdrive/linux/ps2.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ps2.c,v 1.4 2001/04/01 14:00:04 tsi Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ps2.c,v 1.5 2001/06/29 14:00:41 keithp Exp $ * * Copyright © 1999 Keith Packard * @@ -60,15 +60,34 @@ Ps2ReadBytes (int fd, char *buf, int len, int min) return tot; } +char *Ps2Names[] = { + "/dev/psaux", + "/dev/mouse", + "/dev/input/mice", +}; + +#define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0])) + void -Ps2Read (int ps2Port) +Ps2Read (int ps2Port, void *closure) { unsigned char buf[3 * 200]; unsigned char *b; int n; int dx, dy; unsigned long flags; + int id = (int) closure; + unsigned long left_button = KD_BUTTON_1; + unsigned long right_button = KD_BUTTON_3; +#undef SWAP_USB +#ifdef SWAP_USB + if (id == 2) + { + left_button = KD_BUTTON_3; + right_button = KD_BUTTON_1; + } +#endif while ((n = Ps2ReadBytes (ps2Port, buf, sizeof (buf), 3)) > 0) { b = buf; @@ -78,10 +97,10 @@ Ps2Read (int ps2Port) if (b[0] & 4) flags |= KD_BUTTON_2; if (b[0] & 2) - flags |= KD_BUTTON_3; + flags |= right_button; if (b[0] & 1) - flags |= KD_BUTTON_1; - + flags |= left_button; + dx = b[1]; if (b[0] & 0x10) dx -= 256; @@ -96,37 +115,37 @@ Ps2Read (int ps2Port) } } -char *Ps2Names[] = { - "/dev/psaux", - "/dev/mouse", -}; - -#define NUM_PS2_NAMES (sizeof (Ps2Names) / sizeof (Ps2Names[0])) +int Ps2InputType; int Ps2Init (void) { int i; int ps2Port; + int n; + if (!Ps2InputType) + Ps2InputType = KdAllocInputType (); + n = 0; for (i = 0; i < NUM_PS2_NAMES; i++) { ps2Port = open (Ps2Names[i], 0); if (ps2Port >= 0) - return ps2Port; + { + if (KdRegisterFd (Ps2InputType, ps2Port, Ps2Read, (void *) i)) + n++; + } } - return -1; + return n; } void -Ps2Fini (int ps2Port) +Ps2Fini (void) { - if (ps2Port >= 0) - close (ps2Port); + KdUnregisterFds (Ps2InputType, TRUE); } KdMouseFuncs Ps2MouseFuncs = { Ps2Init, - Ps2Read, Ps2Fini }; diff --git a/xc/programs/Xserver/hw/kdrive/linux/ts.c b/xc/programs/Xserver/hw/kdrive/linux/ts.c index 3d7254534..3181923ea 100644 --- a/xc/programs/Xserver/hw/kdrive/linux/ts.c +++ b/xc/programs/Xserver/hw/kdrive/linux/ts.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ts.c,v 1.2 2000/09/26 15:57:04 tsi Exp $ + * $XFree86: xc/programs/Xserver/hw/kdrive/linux/ts.c,v 1.5 2001/07/11 02:58:19 keithp Exp $ * * Derived from ps2.c by Jim Gettys * @@ -35,8 +35,12 @@ #include <sys/ioctl.h> #include <linux/h3600_ts.h> /* touch screen events */ +static long lastx = 0, lasty = 0; +int TsScreen; +extern int TsFbdev; + void -TsRead (int tsPort) +TsRead (int tsPort, void *closure) { TS_EVENT event; long buf[3]; @@ -52,20 +56,39 @@ TsRead (int tsPort) { if (event.pressure) { - flags = KD_BUTTON_1; - x = event.x; - y = event.y; - } - else { + /* + * HACK ATTACK. (static global variables used !) + * Here we test for the touch screen driver actually being on the + * touch screen, if it is we send absolute coordinates. If not, + * then we send delta's so that we can track the entire vga screen. + */ + if (TsScreen == TsFbdev) { + flags = KD_BUTTON_1; + x = event.x; + y = event.y; + } else { + flags = /* KD_BUTTON_1 |*/ KD_MOUSE_DELTA; + if ((lastx == 0) || (lasty == 0)) { + x = 0; + y = 0; + } else { + x = event.x - lastx; + y = event.y - lasty; + } + lastx = event.x; + lasty = event.y; + } + } else { flags = KD_MOUSE_DELTA; x = 0; y = 0; + lastx = 0; + lasty = 0; } KdEnqueueMouseEvent (flags, x, y); } } - char *TsNames[] = { "/dev/ts", "/dev/h3600_ts" /* temporary name; note this code can try @@ -74,31 +97,36 @@ char *TsNames[] = { #define NUM_TS_NAMES (sizeof (TsNames) / sizeof (TsNames[0])) +int TsInputType; + int TsInit (void) { int i; int TsPort; + if (!TsInputType) + TsInputType = KdAllocInputType (); for (i = 0; i < NUM_TS_NAMES; i++) { TsPort = open (TsNames[i], 0); if (TsPort >= 0) - return TsPort; + { + if (KdRegisterFd (TsInputType, TsPort, TsRead, 0)) + return 1; + } } perror("Touch screen not found.\n"); exit (1); } void -TsFini (int tsPort) +TsFini (void) { - if (tsPort >= 0) - close (tsPort); + KdUnregisterFds (TsInputType, TRUE); } -KdTsFuncs TsFuncs = { +KdMouseFuncs TsFuncs = { TsInit, - TsRead, TsFini }; diff --git a/xc/programs/Xserver/hw/kdrive/mach64/Imakefile b/xc/programs/Xserver/hw/kdrive/mach64/Imakefile new file mode 100644 index 000000000..bd024c68b --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/Imakefile @@ -0,0 +1,20 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/mach64/Imakefile,v 1.2 2001/06/16 05:48:48 keithp Exp $ +KDRIVE=.. +#include "../Kdrive.tmpl" + +#if BuildXvExt +XVSRCS=mach64video.c +XVOBJS=mach64video.o +#endif + +SRCS = mach64.c mach64draw.c mach64stub.c $(XVSRCS) + +OBJS = mach64.o mach64draw.o mach64stub.o $(XVOBJS) + +DEFINES = XvExtensionDefines -DVESA /* -DUSE_PCI*/ + +INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/vesa + +NormalLibraryObjectRule() +NormalLibraryTarget(mach64,$(OBJS)) +DependTarget() diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64.c new file mode 100644 index 000000000..7df5c9d61 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64.c @@ -0,0 +1,450 @@ +/* + * Copyright © 2001 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.c,v 1.8 2001/07/24 21:26:17 keithp Exp $ */ + +#include "mach64.h" +#include <sys/io.h> + +Bool +mach64CardInit (KdCardInfo *card) +{ + Mach64CardInfo *mach64c; + + mach64c = (Mach64CardInfo *) xalloc (sizeof (Mach64CardInfo)); + if (!mach64c) + return FALSE; + + (void) mach64MapReg (card, mach64c); + mach64c->lcdEnabled = FALSE; + + if (!vesaInitialize (card, &mach64c->vesa)) + { + xfree (mach64c); + return FALSE; + } + + card->driver = mach64c; + + return TRUE; +} + +Bool +mach64ScreenInit (KdScreenInfo *screen) +{ + Mach64CardInfo *mach64c = screen->card->driver; + Mach64ScreenInfo *mach64s; + int screen_size, memory; + + mach64s = (Mach64ScreenInfo *) xalloc (sizeof (Mach64ScreenInfo)); + if (!mach64s) + return FALSE; + memset (mach64s, '\0', sizeof (Mach64ScreenInfo)); + if (!vesaScreenInitialize (screen, &mach64s->vesa)) + { + xfree (mach64s); + return FALSE; + } + if (!mach64c->reg) + screen->dumb = TRUE; + if (mach64s->vesa.mapping != VESA_LINEAR) + screen->dumb = TRUE; + mach64s->screen = mach64s->vesa.fb; + switch (screen->fb[0].depth) { + case 8: + mach64s->colorKey = 0xff; + break; + case 15: + case 16: + mach64s->colorKey = 0x001e; + break; + case 24: + mach64s->colorKey = 0x0000fe; + break; + default: + mach64s->colorKey = 1; + break; + } + memory = mach64s->vesa.fb_size; + screen_size = screen->fb[0].byteStride * screen->height; + if (mach64s->screen && memory >= screen_size + 2048) + { + memory -= 2048; + mach64s->cursor_base = mach64s->screen + memory - 2048; + } + else + mach64s->cursor_base = 0; + screen->softCursor = TRUE; /* XXX for now */ + memory -= screen_size; + if (memory > screen->fb[0].byteStride) + { + mach64s->off_screen = mach64s->screen + screen_size; + mach64s->off_screen_size = memory; + } + else + { + mach64s->off_screen = 0; + mach64s->off_screen_size = 0; + } + screen->driver = mach64s; + return TRUE; +} + +Bool +mach64InitScreen (ScreenPtr pScreen) +{ +#ifdef XV + KdScreenPriv(pScreen); + Mach64CardInfo *mach64c = pScreenPriv->screen->card->driver; + if (mach64c->media_reg && mach64c->reg) + mach64InitVideo(pScreen); +#endif + return vesaInitScreen (pScreen); +} + +#ifdef RANDR +mach64RandRSetConfig (ScreenPtr pScreen, + Rotation rotation, + RRScreenSizePtr pSize, + RRVisualGroupPtr pVisualGroup) +{ + KdScreenPriv(pScreen); + + KdCheckSync (pScreen); + + if (!vesaRandRSetConfig (pScreen, rotation, pSize, pVisualGroup)) + return FALSE; + + return TRUE; +} + +void +mach64RandRInit (ScreenPtr pScreen) +{ + rrScrPriv(pScreen); + + pScrPriv->rrSetConfig = mach64RandRSetConfig; +} +#endif + +Bool +mach64FinishInitScreen (ScreenPtr pScreen) +{ + Bool ret; + ret = vesaFinishInitScreen (pScreen); +#ifdef RANDR + mach64RandRInit (pScreen); +#endif + return ret; +} + +CARD32 +mach64ReadLCD (Reg *reg, int id) +{ + CARD32 LCD_INDEX; + + LCD_INDEX = reg->LCD_INDEX & ~(0x3f); + reg->LCD_INDEX = (LCD_INDEX | id); + return reg->LCD_DATA; +} + +void +mach64WriteLCD (Reg *reg, int id, CARD32 data) +{ + CARD32 LCD_INDEX; + + LCD_INDEX = reg->LCD_INDEX & ~(0x3f); + reg->LCD_INDEX = (LCD_INDEX | id); + reg->LCD_DATA = data; +} + +void +mach64Preserve (KdCardInfo *card) +{ + Mach64CardInfo *mach64c = card->driver; + Reg *reg = mach64c->reg; + + vesaPreserve(card); + if (reg) + { + mach64c->save.LCD_GEN_CTRL = mach64ReadLCD (reg, 1); + } +} + +Bool +mach64MapReg (KdCardInfo *card, Mach64CardInfo *mach64c) +{ + mach64c->reg_base = (CARD8 *) KdMapDevice (MACH64_REG_BASE(card), + MACH64_REG_SIZE(card)); + + if (!mach64c->reg_base) + { + mach64c->reg = 0; + mach64c->media_reg = 0; + return FALSE; + } + + KdSetMappedMode (MACH64_REG_BASE(card), + MACH64_REG_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + mach64c->reg = (Reg *) (mach64c->reg_base + MACH64_REG_OFF(card)); + mach64c->media_reg = (MediaReg *) (mach64c->reg_base + MACH64_MEDIA_REG_OFF(card)); + return TRUE; +} + +void +mach64UnmapReg (KdCardInfo *card, Mach64CardInfo *mach64c) +{ + if (mach64c->reg_base) + { + KdResetMappedMode (MACH64_REG_BASE(card), + MACH64_REG_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + KdUnmapDevice ((void *) mach64c->reg_base, MACH64_REG_SIZE(card)); + mach64c->reg_base = 0; + mach64c->reg = 0; + mach64c->media_reg = 0; + } +} + +void +mach64SetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c) +{ + if (!mach64c->reg_base) + mach64MapReg (card, mach64c); + if (mach64c->reg) + { + if (mach64c->reg->GUI_STAT == 0xffffffff) + FatalError ("Mach64 REG not visible\n"); + } +} + +void +mach64ResetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c) +{ + mach64UnmapReg (card, mach64c); +} + +Bool +mach64Enable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + Mach64CardInfo *mach64c = pScreenPriv->card->driver; + + if (!vesaEnable (pScreen)) + return FALSE; + + mach64SetMMIO (pScreenPriv->card, mach64c); + mach64DPMS (pScreen, KD_DPMS_NORMAL); +#ifdef XV + KdXVEnable (pScreen); +#endif + return TRUE; +} + +void +mach64Disable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + Mach64CardInfo *mach64c = pScreenPriv->card->driver; + +#ifdef XV + KdXVDisable (pScreen); +#endif + mach64ResetMMIO (pScreenPriv->card, mach64c); + vesaDisable (pScreen); +} + +const CARD8 mach64DPMSModes[4] = { + 0x80, /* KD_DPMS_NORMAL */ + 0x8c, /* KD_DPMS_STANDBY */ + 0x8c, /* KD_DPMS_STANDBY */ + 0x8c, /* KD_DPMS_STANDBY */ +/* 0xb0, /* KD_DPMS_SUSPEND */ +/* 0xbc, /* KD_DPMS_POWERDOWN */ +}; + +#define PWR_MGT_ON (1 << 0) +#define PWR_MGT_MODE (3 << 1) +#define PWR_MGT_MODE_PIN (0 << 1) +#define PWR_MGT_MODE_REG (1 << 1) +#define PWR_MGT_MODE_TIMER (2 << 1) +#define PWR_MGR_MODE_PCI (3 << 1) +#define AUTO_PWRUP_EN (1 << 3) +#define ACTIVITY_PIN_ON (1 << 4) +#define STANDBY_POL (1 << 5) +#define SUSPEND_POL (1 << 6) +#define SELF_REFRESH (1 << 7) +#define ACTIVITY_PIN_EN (1 << 8) +#define KEYBD_SNOOP (1 << 9) +#define DONT_USE_F32KHZ (1 << 10) +#define TRISTATE_MEM_EN (1 << 11) +#define LCDENG_TEST_MODE (0xf << 12) +#define STANDBY_COUNT (0xf << 16) +#define SUSPEND_COUNT (0xf << 20) +#define BIASON (1 << 24) +#define BLON (1 << 25) +#define DIGON (1 << 26) +#define PM_D3_RST_ENB (1 << 27) +#define STANDBY_NOW (1 << 28) +#define SUSPEND_NOW (1 << 29) +#define PWR_MGT_STATUS (3 << 30) +#define PWR_MGT_STATUS_ON (0 << 30) +#define PWR_MGT_STATUS_STANDBY (1 << 30) +#define PWR_MGT_STATUS_SUSPEND (2 << 30) +#define PWR_MGT_STATUS_TRANSITION (3 << 30) + +Bool +mach64DPMS (ScreenPtr pScreen, int mode) +{ + KdScreenPriv(pScreen); + Mach64CardInfo *mach64c = pScreenPriv->card->driver; + int hsync_off, vsync_off, blank; + CARD32 CRTC_GEN_CNTL; + CARD32 LCD_GEN_CTRL; + Reg *reg = mach64c->reg; + + if (!reg) + return FALSE; + + CRTC_GEN_CNTL = reg->CRTC_GEN_CNTL; + LCD_GEN_CTRL = mach64ReadLCD (reg, 1); + + switch (mode) { + case KD_DPMS_NORMAL: + hsync_off = 0; + vsync_off = 0; + blank = 0; + break; + case KD_DPMS_STANDBY: + hsync_off = 1; + vsync_off = 0; + blank = 1; + break; + case KD_DPMS_SUSPEND: + hsync_off = 0; + vsync_off = 1; + blank = 1; + break; + case KD_DPMS_POWERDOWN: + hsync_off = 1; + vsync_off = 1; + blank = 1; + } + + if (hsync_off) + CRTC_GEN_CNTL |= (1 << 2); + else + CRTC_GEN_CNTL &= ~(1 << 2); + if (vsync_off) + CRTC_GEN_CNTL |= (1 << 3); + else + CRTC_GEN_CNTL &= ~(1 << 3); + if (blank) + { + mach64c->lcdEnabled = (LCD_GEN_CTRL & (1 << 1)) != 0; + LCD_GEN_CTRL &= ~(1 << 1); + CRTC_GEN_CNTL |= (1 << 6); + + } + else + { + if (!(LCD_GEN_CTRL & 3) || mach64c->lcdEnabled) + LCD_GEN_CTRL |= (1 << 1); + CRTC_GEN_CNTL &= ~(1 << 6); + } + + KdCheckSync (pScreen); + + mach64WriteLCD (reg, 1, LCD_GEN_CTRL); + + reg->CRTC_GEN_CNTL = CRTC_GEN_CNTL; + return TRUE; +} + +void +mach64Restore (KdCardInfo *card) +{ + Mach64CardInfo *mach64c = card->driver; + Reg *reg = mach64c->reg; + + if (reg) + { + mach64WriteLCD (reg, 1, mach64c->save.LCD_GEN_CTRL); + } + mach64ResetMMIO (card, mach64c); + vesaRestore (card); +} + +void +mach64ScreenFini (KdScreenInfo *screen) +{ + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + + vesaScreenFini (screen); + xfree (mach64s); + screen->driver = 0; +} + +void +mach64CardFini (KdCardInfo *card) +{ + Mach64CardInfo *mach64c = card->driver; + + mach64UnmapReg (card, mach64c); + vesaCardFini (card); +} + +#define mach64CursorInit 0 /* initCursor */ +#define mach64CursorEnable 0 /* enableCursor */ +#define mach64CursorDisable 0 /* disableCursor */ +#define mach64CursorFini 0 /* finiCursor */ +#define mach64RecolorCursor 0 /* recolorCursor */ + +KdCardFuncs mach64Funcs = { + mach64CardInit, /* cardinit */ + mach64ScreenInit, /* scrinit */ + mach64InitScreen, /* initScreen */ + mach64Preserve, /* preserve */ + mach64Enable, /* enable */ + mach64DPMS, /* dpms */ + mach64Disable, /* disable */ + mach64Restore, /* restore */ + mach64ScreenFini, /* scrfini */ + mach64CardFini, /* cardfini */ + + mach64CursorInit, /* initCursor */ + mach64CursorEnable, /* enableCursor */ + mach64CursorDisable, /* disableCursor */ + mach64CursorFini, /* finiCursor */ + mach64RecolorCursor, /* recolorCursor */ + + mach64DrawInit, /* initAccel */ + mach64DrawEnable, /* enableAccel */ + mach64DrawSync, /* syncAccel */ + mach64DrawDisable, /* disableAccel */ + mach64DrawFini, /* finiAccel */ + + vesaGetColors, /* getColors */ + vesaPutColors, /* putColors */ + + mach64FinishInitScreen, /* finishInitScreen */ +}; diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64.h b/xc/programs/Xserver/hw/kdrive/mach64/mach64.h new file mode 100644 index 000000000..c54238604 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64.h @@ -0,0 +1,655 @@ +/* + * Id: mach64.h,v 1.2 1999/11/02 08:17:24 keithp Exp $ + * + * Copyright © 2001 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64.h,v 1.6 2001/07/24 19:06:03 keithp Exp $ */ + +#ifndef _MACH64_H_ +#define _MACH64_H_ +#include <vesa.h> +#include "kxv.h" + +/* + * offset from ioport beginning + */ + +#define MACH64_REG_BASE(c) ((c)->attr.address[1]) +#define MACH64_REG_SIZE(c) (4096) + +#define MACH64_REG_OFF(c) (1024) +#define MACH64_MEDIA_REG_OFF(c) (0) + +typedef volatile CARD8 VOL8; +typedef volatile CARD16 VOL16; +typedef volatile CARD32 VOL32; + +typedef struct _Reg { + VOL32 CRTC_H_TOTAL_DISP; /* 0x00 */ + VOL32 CRTC_H_SYNC_STRT_WID; /* 0x01 */ + VOL32 CRTC_V_TOTAL_DISP; /* 0x02 */ + VOL32 CRTC_V_SYNC_STRT_WID; /* 0x03 */ + VOL32 CRTC_VLINE_CRNT_VLINE; /* 0x04 */ + VOL32 CRTC_OFF_PITCH; /* 0x05 */ + VOL32 CRTC_INT_CNTL; /* 0x06 */ + VOL32 CRTC_GEN_CNTL; /* 0x07 */ + VOL32 DSP_CONFIG; /* 0x08 */ + VOL32 DSP_ON_OFF; /* 0x09 */ + VOL32 TIMER_CONFIG; /* 0x0a */ + VOL32 MEM_BUF_CNTL; /* 0x0b */ + VOL32 unused0; /* 0x0c */ + VOL32 MEM_ADDR_CONFIG; /* 0x0d */ + VOL32 CRT_TRAP; /* 0x0e */ + VOL32 I2C_CNTL_0; /* 0x0f */ + VOL32 OVR_CLR; /* 0x10 */ + VOL32 OVR_WID_LEFT_RIGHT; /* 0x11 */ + VOL32 OVR_WID_TOP_BOTTOM; /* 0x12 */ + VOL32 VGA_DSP_CONFIG; /* 0x13 */ + VOL32 VGA_DSP_ON_OFF; /* 0x14 */ + VOL32 DSP2_CONFIG; /* 0x15 */ + VOL32 DSP2_ON_OFF; /* 0x16 */ + VOL32 CRTC2_OFF_PITCH; /* 0x17 */ + VOL32 CUR_CLR0; /* 0x18 */ + VOL32 CUR_CLR1; /* 0x19 */ + VOL32 CUR_OFFSET; /* 0x1a */ + VOL32 CUR_HORZ_VERT_POSN; /* 0x1b */ + VOL32 CUR_HORZ_VERT_OFF; /* 0x1c */ + VOL32 TV_OUT_INDEX; /* 0x1d */ + VOL32 GP_IO; /* 0x1e */ + VOL32 HW_DEBUG; /* 0x1f */ + VOL32 SCRATCH_REG0; /* 0x20 */ + VOL32 SCRATCH_REG1; + VOL32 SCRATCH_REG2; + VOL32 SCRATCH_REG3; + VOL32 CLOCK_CNTL; + VOL32 CONFIG_STAT1; + VOL32 CONFIG_STAT2; + VOL32 TV_OUT_DATA; + VOL32 BUS_CNTL; /* 0x28 */ + VOL32 LCD_INDEX; /* 0x29 */ + VOL32 LCD_DATA; /* 0x2a */ + VOL32 EXT_MEM_CNTL; + VOL32 MEM_CNTL; + VOL32 MEM_VGA_WP_SEL; + VOL32 MEM_VGA_RP_SEL; + VOL32 I2C_CNTL_1; + VOL32 DAC_REGS; /* 0x30 */ + VOL32 DAC_CNTL; /* 0x31 */ + VOL32 unused_32; + VOL32 unused_33; + VOL32 GEN_TEST_CNTL; /* 0x34 */ + VOL32 CUSTOM_MACRO_CNTL; + VOL32 unused36; + VOL32 CONFIG_CNTL; + VOL32 CONFIG_CHIP_ID; + VOL32 CONFIG_STAT0; + VOL32 CRC_SIG; + VOL32 unused_3b; + VOL32 unused_3c; + VOL32 unused_3d; + VOL32 unused_3e; + VOL32 unused_3f; + VOL32 DST_OFF_PITCH; /* 0x40 */ + VOL32 DST_X; + VOL32 DST_Y; + VOL32 DST_Y_X; + VOL32 DST_WIDTH; + VOL32 DST_HEIGHT; + VOL32 DST_HEIGHT_WIDTH; + VOL32 DST_X_WIDTH; + VOL32 DST_BRES_LNTH; + VOL32 DST_BRES_ERR; + VOL32 DST_BRES_INC; + VOL32 DST_BRES_DEC; + VOL32 DST_CNTL; + VOL32 DST_Y_X_ALIAS; + VOL32 TRAIL_BRES_ERR; + VOL32 TRAIL_BRES_INC; + VOL32 TRAIL_BRES_DEC; + VOL32 LEAD_BRES_LNTH; + VOL32 Z_OFF_PITCH; + VOL32 Z_CNTL; + VOL32 ALPHA_TST_CNTL; + VOL32 unused55; + VOL32 SECONDARY_STW_EXP; + VOL32 SECONDARY_S_X_INC; + VOL32 SECONDARY_S_Y_INC; + VOL32 SECONDARY_S_START; + VOL32 SECONDARY_W_X_INC; + VOL32 SECONDARY_W_Y_INC; + VOL32 SECONDARY_W_START; + VOL32 SECONDARY_T_X_INC; + VOL32 SECONDARY_T_Y_INC; + VOL32 SECONDARY_T_START; + VOL32 SRC_OFF_PITCH; + VOL32 SRC_X; + VOL32 SRC_Y; + VOL32 SRC_Y_X; + VOL32 SRC_WIDTH1; + VOL32 SRC_HEIGHT1; + VOL32 SRC_HEIGHT1_WIDTH1; + VOL32 SRC_X_START; + VOL32 SRC_Y_START; + VOL32 SRC_Y_X_START; + VOL32 SRC_WIDTH2; + VOL32 SRC_HEIGHT2; + VOL32 SRC_HEIGHT2_WIDTH2; + VOL32 SRC_CNTL; + VOL32 unused6e; + VOL32 unused6f; + union { + struct { + VOL32 SCALE_OFF; /* 0x70 */ + VOL32 unused71; + VOL32 unused72; + VOL32 unused73; + VOL32 unused74; + VOL32 unused75; + VOL32 unused76; + VOL32 SCALE_WIDTH; + VOL32 SCALE_HEIGHT; + VOL32 unused79; + VOL32 unused7a; + VOL32 SCALE_PITCH; + VOL32 SCALE_X_INC; + VOL32 SCALE_Y_INC; + VOL32 SCALE_VACC; + VOL32 SCALE_3D_CNTL; /* 0x7f */ + } scaler; + struct { + VOL32 TEX_0_OFF; /* 0x70 */ + VOL32 TEX_1_OFF; + VOL32 TEX_2_OFF; + VOL32 TEX_3_OFF; + VOL32 TEX_4_OFF; + VOL32 TEX_5_OFF; + VOL32 TEX_6_OFF; + VOL32 TEX_7_OFF; + VOL32 TEX_8_OFF; + VOL32 TEX_9_OFF; + VOL32 TEX_10_OFF; + VOL32 S_Y_INC; + VOL32 RED_X_INC; + VOL32 GREEN_X_INC; /* 0x7d */ + VOL32 unused7e; + VOL32 unused7f; + } texture; + } u; + VOL32 HOST_DATA[16]; /* 0x80 */ + VOL32 HOST_CNTL; /* 0x90 */ + VOL32 BM_HOSTDATA; /* 0x91 */ + VOL32 BM_ADDR; /* 0x92 */ + VOL32 BM_GUI_TABLE_CMD; /* 0x93 */ + VOL32 unused94; /* 0x94 */ + VOL32 unused95; /* 0x95 */ + VOL32 unused96; /* 0x96 */ + VOL32 FOG_TABLE_INDEX; /* 0x97 */ + VOL32 FOG_TABLE_DATA[8]; /* 0x98 */ + VOL32 PAT_REG0; /* 0xa0 */ + VOL32 PAT_REG1; + VOL32 PAT_CNTL; + VOL32 unused_0a3; + VOL32 unused_0a4; + VOL32 unused_0a5; + VOL32 unused_0a6; + VOL32 unused_0a7; + VOL32 SC_LEFT; + VOL32 SC_RIGHT; + VOL32 SC_LEFT_RIGHT; + VOL32 SC_TOP; + VOL32 SC_BOTTOM; + VOL32 SC_TOP_BOTTOM; + VOL32 USR1_DST_OFF_PITCH; + VOL32 USR2_DST_OFF_PITCH; + VOL32 DP_BKGD_CLR; /* 0xb0 */ + VOL32 DP_FRGD_CLR; + VOL32 DP_WRITE_MSK; + VOL32 unused_0b3; + VOL32 DP_PIX_WIDTH; + VOL32 DP_MIX; + VOL32 DP_SRC; + VOL32 DP_FRGD_CLR_MIX; + VOL32 DP_FRGD_BKGD_CLR; + VOL32 unused_0b9; + VOL32 DST_X_Y; + VOL32 DST_WIDTH_HEIGHT; + VOL32 USR_DST_PITCH; + VOL32 unused_0bd; + VOL32 DP_SET_GUI_ENGINE2; + VOL32 DP_SET_GUI_ENGINE; + VOL32 CLR_CMP_CLR; /* 0xc0 */ + VOL32 CLR_CMP_MSK; + VOL32 CLR_CMP_CNTL; + VOL32 unused_0c3; + VOL32 FIFO_STAT; + VOL32 unused_0c5; + VOL32 unused_0c6; + VOL32 unused_0c7; + VOL32 unused_0c8; + VOL32 unused_0c9; + VOL32 unused_0ca; + VOL32 unused_0cb; + VOL32 GUI_TRAJ_CNTL; + VOL32 unused_0cd; + VOL32 GUI_STAT; + VOL32 unused_0cf; + VOL32 TEX_PALETTE_INDEX; + VOL32 STW_EXP; + VOL32 LOG_MAX_INC; + VOL32 S_X_INC; + VOL32 S_Y_INC_2_SCALE_PITCH; + VOL32 S_START; + VOL32 W_X_INC; + VOL32 W_Y_INC; + VOL32 W_START; + VOL32 T_X_INC; + VOL32 T_Y_INC_SECONDARY_SCALE_PITCH; + VOL32 T_START; + VOL32 TEX_SIZE_PITCH; + VOL32 TEX_CNTL; + VOL32 SECONDARY_TEX_OFFSET_SECONDARY_SCALE_OFF; + VOL32 TEX_PALETTE; + VOL32 SCALE_PITCH_BOTH; /* 0xe0 */ + VOL32 SECONDARY_SCALE_OFF_ACC; + VOL32 SCALE_OFF_ACC; + VOL32 SCALE_DST_Y_X; + VOL32 unused_0e4; + VOL32 unused_0e5; + VOL32 COMPOSITE_SHADOW_ID; + VOL32 SECONDARY_SCALE_X_INC_SPECULAR_RED_X_INC; + VOL32 SPECULAR_RED_Y_INC; + VOL32 SPECULAR_RED_START_SECONDARY_SCALE_HACC;; + VOL32 SPECULAR_GREEN_X_INC; + VOL32 SPECULAR_GREEN_Y_INC; + VOL32 SPECULAR_GREEN_START; + VOL32 SPECULAR_BLUE_X_INC; + VOL32 SPECULAR_BLUE_Y_INC; + VOL32 SPECULAR_BLUE_START; + VOL32 RED_X_INC_SCALE_X_INC; + VOL32 RED_Y_INC; + VOL32 RED_START_SCALE_HACC; + VOL32 GREEN_X_INC_SCALE_Y_INC; + VOL32 GREEN_Y_INC_SECONDARY_SCALE_Y_INC; + VOL32 GREEN_START_SECONDARY_SCALE_VACC; + VOL32 BLUE_X_INC; + VOL32 BLUE_Y_INC; + VOL32 BLUE_START; + VOL32 Z_X_INC; + VOL32 Z_Y_INC; + VOL32 Z_START; + VOL32 ALPHA_X_INC; + VOL32 FOG_X_INC; + VOL32 ALPHA_Y_INC; + VOL32 FOG_Y_INC; + VOL32 ALPHA_START; + VOL32 FOG_START; + VOL32 unused_0ff; +} Reg; /* 0x100 */ + +#define DST_X_DIR (1 << 0) +#define DST_Y_DIR (1 << 1) +#define DST_Y_MAJOR (1 << 2) +#define DST_X_TILE (1 << 3) +#define DST_Y_TILE (1 << 4) +#define DST_LAST_PEL (1 << 5) +#define DST_POLYGON_EN (1 << 6) +#define DST_24_ROT_EN (1 << 7) +#define DST_24_ROT(n) ((n) << 8) +#define DST_BRES_ZERO (1 << 11) +#define DST_POLYGON_RTEDGE_DIS (1 << 12) +#define TRAIL_X_DIR (1 << 13) +#define TRAP_FILL_DIR (1 << 14) +#define TRAIL_BRES_SIGN (1 << 15) +#define SRC_PATT_EN (1 << 16) +#define SRC_PATT_ROT_EN (1 << 17) +#define SRC_LINEAR_EN (1 << 18) +#define SRC_BYTE_ALIGN (1 << 19) +#define SRC_LINE_X_DIR (1 << 20) +#define SRC_8x8x8_BRUSH (1 << 21) +#define FAST_FILL_EN (1 << 22) +#define SRC_TRACK_DST (1 << 23) +#define PAT_MONO_EN (1 << 24) +#define PAT_CLR_4x2_EN (1 << 25) +#define PAT_CLR_8x1_EN (1 << 26) +#define HOST_BYTE_ALIGN (1 << 28) +#define HOST_BIG_ENDIAN_EN (1 << 29) + +/* BUS_CNTL bits */ +#define BUS_DBL_RESYNC (1 << 0) +#define BUS_MSTR_RESET (1 << 1) +#define BUS_FLUSH_BUF (1 << 2) +#define BUS_STOP_REQ_DIS (1 << 3) +#define BUS_APER_REG_DIS (1 << 4) +#define BUS_EXTRA_PIPE_DIS (1 << 5) +#define BUS_MASTER_DIS (1 << 6) +#define ROM_WRT_EN (1 << 7) +#define CHIP_HIDDEN_REV (3 << 8) +#define BUS_PCI_READ_RETRY_EN (1 << 13) +#define BUS_PCI_WRT_RETRY_EN (1 << 15) +#define BUS_RETRY_WS (0xf << 16) +#define BUS_MSTR_RD_MULT (1 << 20) +#define BUS_MSTR_RD_LINE (1 << 21) +#define BUS_SUSPEND (1 << 22) +#define LAT16X (1 << 23) +#define BUS_RD_DISCARD_EN (1 << 24) +#define BUS_RD_ABORT_EN (1 << 25) +#define BUS_MSTR_WS (1 << 26) +#define BUS_EXT_REG_EN (1 << 27) +#define BUS_MSTR_DISCONNECT_EN (1 << 28) +#define BUS_WRT_BURST (1 << 29) +#define BUS_READ_BURST (1 << 30) +#define BUS_RDY_READ_DLY (1 << 31) + +#define SCALE_PIX_EXPAND (1 << 0) +#define SCALE_Y2R_TEMP (1 << 1) +#define SCALE_HORZ_MODE (1 << 2) +#define SCALE_VERT_MODE (1 << 3) +#define SCALE_SIGNED_UV (1 << 4) +#define SCALE_GAMMA_SEL (3 << 5) +#define SCALE_GAMMA_BRIGHT (0 << 5) +#define SCALE_GAMMA_22 (1 << 5) +#define SCALE_GAMMA_18 (2 << 5) +#define SCALE_GAMMA_14 (3 << 5) +#define SCALE_DISP_SEL (1 << 7) +#define SCALE_BANDWIDTH (1 << 26) +#define SCALE_DIS_LIMIT (1 << 27) +#define SCALE_CLK_FORCE_ON (1 << 29) +#define SCALE_OVERLAY_EN (1 << 30) +#define SCALE_EN (1 << 31) + +#define VIDEO_IN_VYUY422 (0xb) +#define VIDEO_IN_YVYU422 (0xc) +#define SCALER_IN_15bpp (0x3 << 16) +#define SCALER_IN_16bpp (0x4 << 16) +#define SCALER_IN_32bpp (0x6 << 16) +#define SCALER_IN_YUV_9 (0x9 << 16) +#define SCALER_IN_YUV_12 (0xa << 16) +#define SCALER_IN_VYUY422 (0xb << 16) +#define SCALER_IN_YVYU422 (0xc << 16) + +#define CAP_INPUT_MODE (1 << 0) +#define CAP_BUF_MODE (1 << 2) +#define CAP_START_BUF (1 << 3) +#define CAP_BUF_TYPE_FIELD (0 << 4) +#define CAP_BUF_TYPE_ALTERNATING (1 << 4) +#define CAP_BUF_TYPE_FRAME (2 << 4) + +#define OVL_BUF_MODE (1 << 28) +#define OVL_BUF_NEXT (1 << 29) + +#define CAP_TRIGGER (3 << 0) +#define OVL_CUR_BUF (1 << 5) +#define OVL_BUF_STATUS (1 << 6) +#define CAP_BUF_STATUS (1 << 7) +#define CAPTURE_EN (1 << 31) + +typedef struct _MediaReg { + VOL32 OVERLAY_Y_X_START; /* 0x100 */ + VOL32 OVERLAY_Y_X_END; + VOL32 OVERLAY_VIDEO_KEY_CLR; + VOL32 OVERLAY_VIDEO_KEY_MSK; + VOL32 OVERLAY_GRAPHICS_KEY_CLR; + VOL32 OVERLAY_GRAPHICS_KEY_MSK; + VOL32 OVERLAY_KEY_CNTL; + VOL32 unused_107; + VOL32 OVERLAY_SCALE_INC; + VOL32 OVERLAY_SCALE_CNTL; + VOL32 SCALER_HEIGHT_WIDTH; + VOL32 SCALER_TEST; + VOL32 unused_10c; + VOL32 SCALER_BUF0_OFFSET; + VOL32 SCALER_BUF1_OFFSET; + VOL32 SCALER_BUF_PITCH; + VOL32 CAPTURE_START_END; /* 0x110 */ + VOL32 CAPTURE_X_WIDTH; + VOL32 VIDEO_FORMAT; + VOL32 VBI_START_END; + VOL32 CAPTURE_CONFIG; + VOL32 TRIG_CNTL; + VOL32 OVERLAY_EXCLUSIVE_HORZ; + VOL32 OVERLAY_EXCLUSIVE_VERT; + VOL32 VBI_WIDTH; + VOL32 CAPTURE_DEBUG; + VOL32 VIDEO_SYNC_TEST; + VOL32 unused_11b; + VOL32 SNAPSHOT_VH_COUNTS; + VOL32 SNAPSHOT_F_COUNT; + VOL32 N_VIF_COUNT; + VOL32 SNAPSHOT_VIF_COUNT; + VOL32 CAPTURE_BUF0_OFFSET; /* 0x120 */ + VOL32 CAPTURE_BUF1_OFFSET; + VOL32 ONESHOT_BUF_OFFSET; + VOL32 unused_123; + VOL32 unused_124; + VOL32 unused_125; + VOL32 unused_126; + VOL32 unused_127; + VOL32 unused_128; + VOL32 unused_129; + VOL32 unused_12a; + VOL32 unused_12b; + VOL32 SNAPSHOT2_VH_COUNTS; + VOL32 SNAPSHOT2_F_COUNT; + VOL32 N_VIF2_COUNT; + VOL32 SNAPSHOT2_VIF_COUNT; + VOL32 MPP_CONFIG; /* 0x130 */ + VOL32 MPP_STROBE_SEQ; + VOL32 MPP_ADDR; + VOL32 MPP_DATA; + VOL32 unused_134; + VOL32 unused_135; + VOL32 unused_136; + VOL32 unused_137; + VOL32 unused_138; + VOL32 unused_139; + VOL32 unused_13a; + VOL32 unused_13b; + VOL32 unused_13c; + VOL32 unused_13d; + VOL32 unused_13e; + VOL32 unused_13f; + VOL32 TVO_CNTL; /* 0x140 */ + VOL32 unused_141[15]; + VOL32 unused_150; /* 0x150 */ + VOL32 CRT_HORZ_VERT_LOAD; /* 0x151 */ + VOL32 AGP_BASE; /* 0x152 */ + VOL32 AGP_CNTL; /* 0x153 */ + VOL32 SCALER_COLOUR_CNTL; /* 0x154 */ + VOL32 SCALER_H_COEFF0; /* 0x155 */ + VOL32 SCALER_H_COEFF1; /* 0x156 */ + VOL32 SCALER_H_COEFF2; /* 0x157 */ + VOL32 SCALER_H_COEFF3; /* 0x158 */ + VOL32 SCALER_H_COEFF4; /* 0x159 */ + VOL32 unused_15a; + VOL32 unused_15b; + VOL32 GUI_CMDFIFO_DEBUG; + VOL32 GUI_CMDFIFO_DATA; + VOL32 GUI_CNTL; + VOL32 unused_15f; + VOL32 BM_FRAME_BUF_OFFSET; /* 0x160 */ + VOL32 BM_SYSTEM_MEM_ADDR; + VOL32 BM_COMMAND; + VOL32 BM_STATUS; + VOL32 unused_164[10]; + VOL32 BM_GUI_TABLE; + VOL32 BM_SYSTEM_TABLE; + VOL32 unused_170[5]; /* 0x170 */ + VOL32 SCALER_BUF0_OFFSET_U; + VOL32 SCALER_BUF0_OFFSET_V; + VOL32 SCALER_BUF1_OFFSET_U; + VOL32 SCALER_BUF1_OFFSET_V; + VOL32 unused_179[7]; + VOL32 unused_180[16]; /* 0x180 */ + VOL32 setup_engine[0x40]; /* 0x190 */ + VOL32 dvd_subpicture[0x30]; /* 0x1d0 */ +} MediaReg; + +#define MACH64_XY(x,y) (((x) & 0x7fff) | (((y) & 0x7fff) << 16)) +#define MACH64_YX(x,y) (((y) & 0x7fff) | (((x) & 0x7fff) << 16)) + +typedef struct _mach64Save { + CARD32 LCD_GEN_CTRL; +} Mach64Save; + +typedef struct _mach64CardInfo { + VesaCardPrivRec vesa; + CARD8 *reg_base; + Reg *reg; + MediaReg *media_reg; + Mach64Save save; + Bool lcdEnabled; +} Mach64CardInfo; + +#define getMach64CardInfo(kd) ((Mach64CardInfo *) ((kd)->card->driver)) +#define mach64CardInfo(kd) Mach64CardInfo *mach64c = getMach64CardInfo(kd) + +typedef struct _mach64Cursor { + int width, height; + int xhot, yhot; + Bool has_cursor; + CursorPtr pCursor; + Pixel source, mask; +} Mach64Cursor; + +#define MACH64_CURSOR_WIDTH 64 +#define MACH64_CURSOR_HEIGHT 64 + +/* + * Xv information, optional + */ +typedef struct _mach64PortPriv { + CARD32 YBuf0Offset; + + CARD32 YBuf1Offset; + + CARD8 currentBuf; + + int brightness; + int saturation; + + RegionRec clip; + CARD32 colorKey; + + Bool videoOn; + Time offTime; + Time freeTime; + CARD32 size; + CARD32 offset; +} Mach64PortPrivRec, *Mach64PortPrivPtr; + +Bool mach64InitVideo(ScreenPtr pScreen); + +typedef struct _mach64ScreenInfo { + VesaScreenPrivRec vesa; + CARD8 *cursor_base; + CARD8 *screen; + CARD8 *off_screen; + int off_screen_size; + CARD32 DP_PIX_WIDTH; + CARD32 DP_SET_GUI_ENGINE; + CARD32 USR1_DST_OFF_PITCH; + Bool bpp24; + Mach64Cursor cursor; + CARD32 colorKey; + KdVideoAdaptorPtr pAdaptor; +} Mach64ScreenInfo; + +#define getMach64ScreenInfo(kd) ((Mach64ScreenInfo *) ((kd)->screen->driver)) +#define mach64ScreenInfo(kd) Mach64ScreenInfo *mach64s = getMach64ScreenInfo(kd) + +CARD32 +mach64ReadLCD (Reg *reg, int id); + +void +mach64WriteLCD (Reg *reg, int id, CARD32 data); + +void +mach64Preserve (KdCardInfo *card); + +Bool +mach64MapReg (KdCardInfo *card, Mach64CardInfo *mach64c); + +void +mach64UnmapReg (KdCardInfo *card, Mach64CardInfo *mach64c); + +void +mach64SetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c); + +void +mach64ResetMMIO (KdCardInfo *card, Mach64CardInfo *mach64c); + +Bool +mach64Enable (ScreenPtr pScreen); + +void +mach64Disable (ScreenPtr pScreen); + +void +mach64WaitAvail(Reg *reg, int n); + +void +mach64WaitIdle (Reg *reg); + +Bool +mach64DrawSetup (ScreenPtr pScreen); + +Bool +mach64DrawInit (ScreenPtr pScreen); + +void +mach64DrawReinit (ScreenPtr pScreen); + +void +mach64DrawEnable (ScreenPtr pScreen); + +void +mach64DrawSync (ScreenPtr pScreen); + +void +mach64DrawDisable (ScreenPtr pScreen); + +void +mach64DrawFini (ScreenPtr pScreen); + +CARD8 +mach64ReadIndex (Mach64CardInfo *mach64c, CARD16 port, CARD8 index); + +void +mach64WriteIndex (Mach64CardInfo *mach64c, CARD16 port, CARD8 index, CARD8 value); + +Bool +mach64CursorInit (ScreenPtr pScreen); + +void +mach64CursorEnable (ScreenPtr pScreen); + +void +mach64CursorDisable (ScreenPtr pScreen); + +void +mach64CursorFini (ScreenPtr pScreen); + +void +mach64RecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef); + +extern KdCardFuncs mach64Funcs; + +#endif /* _MACH64_H_ */ diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c new file mode 100644 index 000000000..fd0bdf76d --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c @@ -0,0 +1,389 @@ +/* + * Id: tridentcurs.c,v 1.1 1999/11/02 03:54:47 keithp Exp $ + * + * Copyright © 1999 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64curs.c,v 1.1 2001/06/03 18:48:19 keithp Exp $ */ + +#include "trident.h" +#include "cursorstr.h" + +#define SetupCursor(s) KdScreenPriv(s); \ + tridentCardInfo(pScreenPriv); \ + tridentScreenInfo(pScreenPriv); \ + TridentCursor *pCurPriv = &tridents->cursor + +static void +_tridentMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CARD8 xlow, xhigh, ylow, yhigh; + CARD8 xoff, yoff; + + x -= pCurPriv->xhot; + xoff = 0; + if (x < 0) + { + xoff = -x; + x = 0; + } + y -= pCurPriv->yhot; + yoff = 0; + if (y < 0) + { + yoff = -y; + y = 0; + } + xlow = (CARD8) x; + xhigh = (CARD8) (x >> 8); + ylow = (CARD8) y; + yhigh = (CARD8) (y >> 8); + + + /* This is the recommended order to move the cursor */ + + tridentWriteIndex (tridentc, 0x3d4, 0x41, xhigh); + tridentWriteIndex (tridentc, 0x3d4, 0x40, xlow); + tridentWriteIndex (tridentc, 0x3d4, 0x42, ylow); + tridentWriteIndex (tridentc, 0x3d4, 0x46, xoff); + tridentWriteIndex (tridentc, 0x3d4, 0x47, yoff); + tridentWriteIndex (tridentc, 0x3d4, 0x43, yhigh); +} + +static void +tridentMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor (pScreen); + + if (!pCurPriv->has_cursor) + return; + + if (!pScreenPriv->enabled) + return; + + _tridentMoveCursor (pScreen, x, y); +} + +static void +tridentAllocCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + + KdAllocateCursorPixels (pScreen, 0, pCursor, + &pCurPriv->source, &pCurPriv->mask); + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 4: + pCurPriv->source |= pCurPriv->source << 4; + pCurPriv->mask |= pCurPriv->mask << 4; + case 8: + pCurPriv->source |= pCurPriv->source << 8; + pCurPriv->mask |= pCurPriv->mask << 8; + case 16: + pCurPriv->source |= pCurPriv->source << 16; + pCurPriv->mask |= pCurPriv->mask << 16; + } +} + +static void +tridentSetCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CARD32 fg, bg; + + fg = pCurPriv->source; + bg = pCurPriv->mask; + tridentWriteIndex (tridentc, 0x3d4, 0x48, fg); + tridentWriteIndex (tridentc, 0x3d4, 0x49, fg >> 8); + tridentWriteIndex (tridentc, 0x3d4, 0x4a, fg >> 16); + + tridentWriteIndex (tridentc, 0x3d4, 0x4c, bg); + tridentWriteIndex (tridentc, 0x3d4, 0x4d, bg >> 8); + tridentWriteIndex (tridentc, 0x3d4, 0x4e, bg >> 16); +} + +void +tridentRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + xColorItem sourceColor, maskColor; + + if (!pCurPriv->has_cursor || !pCursor) + return; + + if (!pScreenPriv->enabled) + return; + + if (pdef) + { + while (ndef) + { + if (pdef->pixel == pCurPriv->source || + pdef->pixel == pCurPriv->mask) + break; + ndef--; + } + if (!ndef) + return; + } + tridentAllocCursorColors (pScreen); + tridentSetCursorColors (pScreen); +} + +#define InvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +static void +tridentLoadCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CursorBitsPtr bits = pCursor->bits; + int w, h; + CARD32 *ram, *msk, *mskLine, *src, *srcLine; + int i, j; + int cursor_address; + int lwsrc; + unsigned char ramdac_control_; + CARD32 offset; + + /* + * Allocate new colors + */ + tridentAllocCursorColors (pScreen); + + pCurPriv->pCursor = pCursor; + pCurPriv->xhot = pCursor->bits->xhot; + pCurPriv->yhot = pCursor->bits->yhot; + + /* + * Stick new image into cursor memory + */ + ram = (CARD32 *) tridents->cursor_base; + mskLine = (CARD32 *) bits->mask; + srcLine = (CARD32 *) bits->source; + + h = bits->height; + if (h > TRIDENT_CURSOR_HEIGHT) + h = TRIDENT_CURSOR_HEIGHT; + + lwsrc = BitmapBytePad(bits->width) / 4; /* words per line */ + + for (i = 0; i < TRIDENT_CURSOR_HEIGHT; i++) { + msk = mskLine; + src = srcLine; + mskLine += lwsrc; + srcLine += lwsrc; + for (j = 0; j < TRIDENT_CURSOR_WIDTH / 32; j++) { + + CARD32 m, s; + +#if 1 + if (i < h && j < lwsrc) + { + m = *msk++; + s = *src++; + InvertBits32(m); + InvertBits32(s); + } + else + { + m = 0; + s = 0; + } +#endif + *ram++ = m; + *ram++ = s; + } + } + + /* Set address for cursor bits */ + offset = tridents->cursor_base - (CARD8 *) tridents->screen; + offset >>= 10; + tridentWriteIndex (tridentc, 0x3d4, 0x44, (CARD8) (offset & 0xff)); + tridentWriteIndex (tridentc, 0x3d4, 0x45, (CARD8) (offset >> 8)); + + /* Set new color */ + tridentSetCursorColors (pScreen); + + /* Enable the cursor */ + tridentWriteIndex (tridentc, 0x3d4, 0x50, 0xc1); + + /* Move to new position */ + tridentMoveCursor (pScreen, x, y); +} + +static void +tridentUnloadCursor (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + /* Disable cursor */ + tridentWriteIndex (tridentc, 0x3d4, 0x50, 0); +} + +static Bool +tridentRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + SetupCursor(pScreen); + + if (!pScreenPriv->enabled) + return TRUE; + + /* miRecolorCursor does this */ + if (pCurPriv->pCursor == pCursor) + { + if (pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + tridentLoadCursor (pScreen, x, y); + } + } + return TRUE; +} + +static Bool +tridentUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static void +tridentSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + SetupCursor(pScreen); + + pCurPriv->pCursor = pCursor; + + if (!pScreenPriv->enabled) + return; + + if (pCursor) + tridentLoadCursor (pScreen, x, y); + else + tridentUnloadCursor (pScreen); +} + +miPointerSpriteFuncRec tridentPointerSpriteFuncs = { + tridentRealizeCursor, + tridentUnrealizeCursor, + tridentSetCursor, + tridentMoveCursor, +}; + +static void +tridentQueryBestSize (int class, + unsigned short *pwidth, unsigned short *pheight, + ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + switch (class) + { + case CursorShape: + if (*pwidth > pCurPriv->width) + *pwidth = pCurPriv->width; + if (*pheight > pCurPriv->height) + *pheight = pCurPriv->height; + if (*pwidth > pScreen->width) + *pwidth = pScreen->width; + if (*pheight > pScreen->height) + *pheight = pScreen->height; + break; + default: + fbQueryBestSize (class, pwidth, pheight, pScreen); + break; + } +} + +Bool +tridentCursorInit (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!tridents->cursor_base) + { + pCurPriv->has_cursor = FALSE; + return FALSE; + } + + pCurPriv->width = TRIDENT_CURSOR_WIDTH; + pCurPriv->height= TRIDENT_CURSOR_HEIGHT; + pScreen->QueryBestSize = tridentQueryBestSize; + miPointerInitialize (pScreen, + &tridentPointerSpriteFuncs, + &kdPointerScreenFuncs, + FALSE); + pCurPriv->has_cursor = TRUE; + pCurPriv->pCursor = NULL; + return TRUE; +} + +void +tridentCursorEnable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + tridentLoadCursor (pScreen, x, y); + } + else + tridentUnloadCursor (pScreen); + } +} + +void +tridentCursorDisable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!pScreenPriv->enabled) + return; + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + tridentUnloadCursor (pScreen); + } + } +} + +void +tridentCursorFini (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + pCurPriv->pCursor = NULL; +} diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c new file mode 100644 index 000000000..6bd9d0d53 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c @@ -0,0 +1,420 @@ +/* + * Id: mach64draw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $ + * + * Copyright © 1999 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.c,v 1.7 2001/07/24 19:06:03 keithp Exp $ */ + +#include "mach64.h" +#include "mach64draw.h" + +#include "Xmd.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "regionstr.h" +#include "mistruct.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "fb.h" +#include "migc.h" +#include "miline.h" +#include "picturestr.h" + +CARD8 mach64Rop[16] = { + /* GXclear */ 0x01, /* 0 */ + /* GXand */ 0x0c, /* src AND dst */ + /* GXandReverse */ 0x0d, /* src AND NOT dst */ + /* GXcopy */ 0x07, /* src */ + /* GXandInverted*/ 0x0e, /* NOT src AND dst */ + /* GXnoop */ 0x03, /* dst */ + /* GXxor */ 0x05, /* src XOR dst */ + /* GXor */ 0x0b, /* src OR dst */ + /* GXnor */ 0x0f, /* NOT src AND NOT dst */ + /* GXequiv */ 0x06, /* NOT src XOR dst */ + /* GXinvert */ 0x00, /* NOT dst */ + /* GXorReverse */ 0x0a, /* src OR NOT dst */ + /* GXcopyInverted*/ 0x04, /* NOT src */ + /* GXorInverted */ 0x09, /* NOT src OR dst */ + /* GXnand */ 0x08, /* NOT src OR NOT dst */ + /* GXset */ 0x02, /* 1 */ +}; + +#define MACH64_DRAW_COMBO_SOLID 0x1 +#define MACH64_DRAW_COMBO_COPY 0x8 + +static Reg *reg; +static CARD32 cmd; +static CARD32 avail; +static CARD32 triple; +static CARD32 combo; + +#define IDX(reg,n) (&(reg)->n - &(reg)->CRTC_H_TOTAL_DISP) + +void +mach64WaitAvail(Reg *reg, int n) +{ + if (avail < n) + { + while ((avail = ((reg->GUI_STAT) >> 16) & 0x3ff) < n) + ; + } + avail -= n; +} + +void +mach64WaitIdle (Reg *reg) +{ + while (reg->GUI_STAT & 1) + ; +} + +static Bool +mach64Setup (ScreenPtr pScreen, CARD32 combo, int wait) +{ + KdScreenPriv(pScreen); + mach64ScreenInfo(pScreenPriv); + mach64CardInfo(pScreenPriv); + + avail = 0; + reg = mach64c->reg; + triple = mach64s->bpp24; + if (!reg) + return FALSE; + + mach64WaitAvail(reg, wait + 3); + reg->DP_PIX_WIDTH = mach64s->DP_PIX_WIDTH; + reg->USR1_DST_OFF_PITCH = mach64s->USR1_DST_OFF_PITCH; + reg->DP_SET_GUI_ENGINE = mach64s->DP_SET_GUI_ENGINE | (combo << 20); + return TRUE; +} + +Bool +mach64PrepareSolid (DrawablePtr pDrawable, + int alu, + Pixel pm, + Pixel fg) +{ + if (!mach64Setup (pDrawable->pScreen, 1, 3)) + return FALSE; + reg->DP_MIX = (mach64Rop[alu] << 16) | 0; + reg->DP_WRITE_MSK = pm; + reg->DP_FRGD_CLR = fg; + return TRUE; +} + +void +mach64Solid (int x1, int y1, int x2, int y2) +{ + if (triple) + { + CARD32 traj; + + x1 *= 3; + x2 *= 3; + + traj = (DST_X_DIR | + DST_Y_DIR | + DST_24_ROT_EN | + DST_24_ROT((x1 / 4) % 6)); + mach64WaitAvail (reg, 1); + reg->GUI_TRAJ_CNTL = traj; + } + mach64WaitAvail(reg,2); + reg->DST_X_Y = MACH64_XY(x1,y1); + reg->DST_WIDTH_HEIGHT = MACH64_XY(x2-x1,y2-y1); +} + +void +mach64DoneSolid (void) +{ +} + +static int copyDx; +static int copyDy; + +Bool +mach64PrepareCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + int dx, + int dy, + int alu, + Pixel pm) +{ + CARD32 combo = 8; + + if ((copyDx = dx) > 0) + combo |= 1; + if ((copyDy = dy) > 0) + combo |= 2; + if (!mach64Setup (pDstDrawable->pScreen, combo, 2)) + return FALSE; + + reg->DP_MIX = (mach64Rop[alu] << 16) | 0; + reg->DP_WRITE_MSK = pm; + return TRUE; +} + +void +mach64Copy (int srcX, + int srcY, + int dstX, + int dstY, + int w, + int h) +{ + if (triple) + { + CARD32 traj; + + srcX *= 3; + dstX *= 3; + w *= 3; + + traj = DST_24_ROT_EN | DST_24_ROT((dstX / 4) % 6); + + if (copyDx > 0) + traj |= 1; + if (copyDy > 0) + traj |= 2; + + mach64WaitAvail (reg, 1); + reg->GUI_TRAJ_CNTL = traj; + } + if (copyDx <= 0) + { + srcX += w - 1; + dstX += w - 1; + } + if (copyDy <= 0) + { + srcY += h - 1; + dstY += h - 1; + } + mach64WaitAvail (reg, 4); + reg->SRC_Y_X = MACH64_YX(srcX, srcY); + reg->SRC_WIDTH1 = w; + reg->DST_Y_X = MACH64_YX(dstX, dstY); + reg->DST_HEIGHT_WIDTH = MACH64_YX(w,h); +} + +void +mach64DoneCopy (void) +{ +} + +KaaScreenPrivRec mach64Kaa = { + mach64PrepareSolid, + mach64Solid, + mach64DoneSolid, + + mach64PrepareCopy, + mach64Copy, + mach64DoneCopy, +}; + +Bool +mach64DrawInit (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + + if (pScreenPriv->screen->fb[0].depth == 4) + return FALSE; + + if (!kaaDrawInit (pScreen, &mach64Kaa)) + return FALSE; + + return TRUE; +} + +#define PIX_FORMAT_MONO 0 +#define PIX_FORMAT_PSEUDO_8 2 +#define PIX_FORMAT_TRUE_1555 3 +#define PIX_FORMAT_TRUE_565 4 +#define PIX_FORMAT_TRUE_8888 6 +#define PIX_FORMAT_TRUE_332 7 +#define PIX_FORMAT_GRAY_8 8 +#define PIX_FORMAT_YUV_422 0xb +#define PIX_FORMAT_YUV_444 0xe +#define PIX_FORMAT_TRUE_4444 0xf + +void +mach64DrawEnable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + mach64ScreenInfo(pScreenPriv); + CARD32 DP_PIX_WIDTH; + CARD32 DP_SET_GUI_ENGINE; + CARD32 SET_DP_DST_PIX_WIDTH; + CARD32 DST1_PITCH; + + mach64s->bpp24 = FALSE; + switch (pScreenPriv->screen->fb[0].depth) { + case 1: + DP_PIX_WIDTH = ((PIX_FORMAT_MONO << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_MONO << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_MONO << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_MONO; + break; + case 4: + FatalError ("mach64 can't accelerate 4bpp"); + break; + case 8: + DP_PIX_WIDTH = ((PIX_FORMAT_PSEUDO_8 << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_PSEUDO_8 << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_PSEUDO_8 << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_PSEUDO_8; + break; + case 15: + DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_1555 << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_TRUE_1555 << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_TRUE_1555 << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_1555; + break; + case 16: + DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_565 << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_TRUE_565 << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_TRUE_565 << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_565; + break; + case 24: + if (pScreenPriv->screen->fb[0].bitsPerPixel == 24) + { + mach64s->bpp24 = TRUE; + DP_PIX_WIDTH = ((PIX_FORMAT_PSEUDO_8 << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_PSEUDO_8 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_PSEUDO_8 << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_PSEUDO_8 << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_PSEUDO_8; + } + else + { + DP_PIX_WIDTH = ((PIX_FORMAT_TRUE_8888 << 0) | /* DP_DST_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 4) | /* COMPOSITE_PIX_WIDTH */ + (PIX_FORMAT_TRUE_8888 << 8) | /* DP_SRC_PIX_WIDTH */ + (0 << 13) | /* DP_HOST_TRIPLE_EN */ + (0 << 14) | /* DP_PALETTE_TYPE */ + (PIX_FORMAT_TRUE_8888 << 16) | /* DP_HOST_PIX_WIDTH */ + (0 << 20) | /* DP_C14_RGB_INDEX */ + (0 << 24) | /* DP_BYTE_PIX_ORDER */ + (0 << 25) | /* DP_CONVERSION_TEMP */ + (0 << 26) | /* DP_C14_RGB_LOW_NIBBLE */ + (0 << 27) | /* DP_C14_RGB_HIGH_NIBBLE */ + (PIX_FORMAT_TRUE_8888 << 28) | /* DP_SCALE_PIX_WIDTH */ + 0); + SET_DP_DST_PIX_WIDTH = PIX_FORMAT_TRUE_8888; + } + break; + } + + mach64s->DP_PIX_WIDTH = DP_PIX_WIDTH; + DST1_PITCH = (pScreenPriv->screen->fb[0].pixelStride) >> 3; + if (mach64s->bpp24) + DST1_PITCH *= 3; + mach64s->USR1_DST_OFF_PITCH = ((0 << 0) | /* USR1_DST_OFFSET */ + (DST1_PITCH << 22) | /* USR1_DST_PITCH */ + 0); + mach64s->DP_SET_GUI_ENGINE = ((SET_DP_DST_PIX_WIDTH << 3) | + (1 << 6) | /* SET_DP_SRC_PIX_WIDTH */ + (0 << 7) | /* SET_DST_OFFSET */ + (0 << 10) | /* SET_DST_PITCH */ + (0 << 14) | /* SET_DST_PITCH_BY_2 */ + (1 << 15) | /* SET_SRC_OFFPITCH_COPY */ + (0 << 16) | /* SET_SRC_HGTWID1_2 */ + (0 << 20) | /* SET_DRAWING_COMBO */ + (1 << 24) | /* SET_BUS_MASTER_OP */ + (0 << 26) | /* SET_BUS_MASTER_EN */ + (0 << 27) | /* SET_BUS_MASTER_SYNC */ + (0 << 28) | /* DP_HOST_TRIPLE_EN */ + (0 << 29) | /* FAST_FILL_EN */ + (0 << 30) | /* BLOCK_WRITE_EN */ + 0); + KdMarkSync (pScreen); +} + +void +mach64DrawDisable (ScreenPtr pScreen) +{ +} + +void +mach64DrawFini (ScreenPtr pScreen) +{ +} + +void +mach64DrawSync (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + mach64CardInfo(pScreenPriv); + reg = mach64c->reg; + + mach64WaitIdle (reg); +} diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h new file mode 100644 index 000000000..1a7e4cf73 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h @@ -0,0 +1,72 @@ +/* + * Id: tridentdraw.h,v 1.1 1999/11/02 03:54:47 keithp Exp $ + * + * Copyright © 1999 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64draw.h,v 1.1 2001/06/03 18:48:19 keithp Exp $ */ + +#ifndef _TRIDENTDRAW_H_ +#define _TRIDENTDRAW_H_ + +#define SetupTrident(s) KdScreenPriv(s); \ + tridentCardInfo(pScreenPriv); \ + Cop *cop = tridentc->cop + +#define TridentAlpha (COP_MULTI_ALPHA|COP_ALPHA_WRITE_ENABLE) + +#define _tridentInit(cop,tridentc) { \ + if ((cop)->status == 0xffffffff) tridentSetMMIO(tridentc); \ + (cop)->multi = (tridentc)->cop_depth; \ + (cop)->multi = (tridentc)->cop_stride; \ + (cop)->multi = TridentAlpha; \ +} \ + +#define _tridentSetSolidRect(cop,pix,alu,cmd) {\ + cop->multi = COP_MULTI_PATTERN; \ + cop->multi = COP_MULTI_ROP | tridentRop[alu]; \ + cop->fg = (pix); \ + cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FG; \ +} + +#define _tridentRect(cop,x1,y1,x2,y2,cmd) { \ + (cop)->dst_start_xy = TRI_XY (x1,y1); \ + (cop)->dst_end_xy = TRI_XY(x2,y2); \ + _tridentWaitDone(cop); \ + (cop)->command = (cmd); \ +} + +#define COP_STATUS_BUSY (COP_STATUS_BE_BUSY | \ + COP_STATUS_DPE_BUSY | \ + COP_STATUS_MI_BUSY) + +#define _tridentWaitDone(cop) { \ + int __q__ = 500000; \ + while (__q__-- && (cop)->status & COP_STATUS_BUSY) \ + ; \ + if (!__q__) \ + (cop)->status = 0; \ +} + +#define _tridentWaitIdleEmpty(cop) _tridentWaitDone(cop) + +#define sourceInvarient(alu) (((alu) & 3) == (((alu) >> 2) & 3)) + +#endif diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c new file mode 100644 index 000000000..730275b92 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c @@ -0,0 +1,58 @@ +/* + * Id: mach64stub.c,v 1.1 1999/11/02 08:19:15 keithp Exp $ + * + * Copyright 1999 SuSE, 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64stub.c,v 1.1 2001/06/03 18:48:19 keithp Exp $ */ + +#include "mach64.h" + +void +InitCard (char *name) +{ + KdCardAttr attr; + + if (LinuxFindPci (0x1002, 0x4c4d, 0, &attr)) + KdCardInfoAdd (&mach64Funcs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); +} + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + int ret; + + if (!(ret = vesaProcessArgument (argc, argv, i))) + ret = KdProcessArgument(argc, argv, i); + return ret; +} diff --git a/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c b/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c new file mode 100644 index 000000000..13b83a7f5 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/mach64/mach64video.c @@ -0,0 +1,1045 @@ +/* + * Copyright © 2001 Keith Packard + * + * 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. + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/mach64/mach64video.c,v 1.7 2001/08/09 09:08:55 keithp Exp $ */ +#include "mach64.h" + +#include "Xv.h" +#include "../../xfree86/common/fourcc.h" + +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) + +static Atom xvBrightness, xvSaturation, xvColorKey; + +#define IMAGE_MAX_WIDTH 720 +#define IMAGE_MAX_HEIGHT 576 + +static void +mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + Reg *reg = mach64c->reg; + MediaReg *media = mach64c->media_reg; + + REGION_EMPTY(screen->pScreen, &pPortPriv->clip); + + if (!media) + return; + + if(pPortPriv->videoOn) + { + mach64WaitIdle (reg); + /* wait for buffer to be displayed */ + while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf) + ; + /* wait for buffer to be finished */ + while (((media->TRIG_CNTL >> 6) & 1) != 0) + ; + mach64WaitAvail (reg, 1); + media->OVERLAY_SCALE_CNTL = 0; + pPortPriv->videoOn = FALSE; + mach64WaitIdle (reg); + } +} + +static int +mach64SetPortAttribute(KdScreenInfo *screen, + Atom attribute, + int value, + pointer data) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + MediaReg *media = mach64c->media_reg; + + if(attribute == xvBrightness) + { + if(value < -1000) + value = -1000; + if (value > 1000) + value = 1000; + pPortPriv->brightness = value; + } + else if(attribute == xvSaturation) + { + if (value < -1000) + value = -1000; + if (value > 1000) + value = 1000; + pPortPriv->saturation = value; + } + else if(attribute == xvColorKey) + { + if (pPortPriv->colorKey != value) + { + pPortPriv->colorKey = value; + REGION_EMPTY(screen->pScreen, &pPortPriv->clip); + } + } + else + return BadMatch; + + return Success; +} + +static int +mach64GetPortAttribute(KdScreenInfo *screen, + Atom attribute, + int *value, + pointer data) +{ + Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data; + + if(attribute == xvBrightness) + *value = pPortPriv->brightness; + else if(attribute == xvSaturation) + *value = pPortPriv->saturation; + else if(attribute == xvColorKey) + *value = pPortPriv->colorKey; + else + return BadMatch; + + return Success; +} + +static void +mach64QueryBestSize(KdScreenInfo *screen, + Bool motion, + short vid_w, + short vid_h, + short drw_w, + short drw_h, + unsigned int *p_w, + unsigned int *p_h, + pointer data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + + +static void +mach64CopyPackedData(KdScreenInfo *screen, + unsigned char *buf, + int rotate, + int srcPitch, + int dstPitch, + int srcW, + int srcH, + int top, + int left, + int h, + int w) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + CARD8 *src, *dst; + int srcDown, srcRight, srcNext; + int p; + + switch (rotate) { + case 0: + src = buf; + srcDown = srcPitch; + srcRight = 2; + break; + case 90: + src = src + (srcH - 1) * 2; + srcDown = -2; + srcRight = srcPitch; + break; + case 180: + src = src + srcPitch * (srcH - 1) + (srcW - 1) * 2; + srcDown = -srcPitch; + srcRight = -2; + break; + case 270: + src = src + srcPitch * (srcW - 1); + srcDown = 2; + srcRight = -srcPitch; + break; + } + + src = src + top*srcDown + left*srcRight; + + if (pPortPriv->currentBuf == 0) + dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset; + else + dst = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset; + + w >>= 1; + srcRight >>= 1; + srcNext = srcRight >> 1; + while(h--) + { + CARD16 *s = (CARD16 *) src; + CARD32 *d = (CARD32 *) dst; + p = w; + while (p--) + { + *d++ = s[0] | (s[srcNext] << 16); + s += srcRight; + } + src += srcPitch; + dst += dstPitch; + } +} + +static void +mach64CopyPlanarData(KdScreenInfo *screen, + unsigned char *buf, + int rotate, + int srcPitch, + int srcPitch2, + int dstPitch, /* of chroma */ + int srcW, + int srcH, + int height, + int top, + int left, + int h, + int w, + int id) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + int i, j; + CARD8 *src1, *src2, *src3, *dst1; + int srcDown, srcDown2, srcRight, srcRight2, srcNext; + + /* compute source data pointers */ + src1 = buf; + src2 = src1 + height * srcPitch; + src3 = src2 + (height >> 1) * srcPitch2; + switch (rotate) { + case 0: + srcDown = srcPitch; + srcDown2 = srcPitch2; + srcRight = 2; + srcRight2 = 1; + srcNext = 1; + break; + case 90: + src1 = src1 + srcH - 1; + src2 = src2 + (srcH >> 1) - 1; + src3 = src3 + (srcH >> 1) - 1; + srcDown = -1; + srcDown2 = -1; + srcRight = srcPitch * 2; + srcRight2 = srcPitch2; + srcNext = srcPitch; + break; + case 180: + src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1); + src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); + src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1); + srcDown = -srcPitch; + srcDown2 = -srcPitch2; + srcRight = -2; + srcRight2 = -1; + srcNext = -1; + break; + case 270: + src1 = src1 + srcPitch * (srcW - 1); + src2 = src2 + srcPitch2 * ((srcW >> 1) - 1); + src3 = src3 + srcPitch2 * ((srcW >> 1) - 1); + srcDown = 1; + srcDown2 = 1; + srcRight = -srcPitch * 2; + srcRight2 = -srcPitch2; + srcNext = -srcPitch; + break; + } + + /* adjust for origin */ + src1 += top * srcDown + left * srcNext; + src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; + src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2; + + if (id == FOURCC_I420) + { + CARD8 *srct = src2; + src2 = src3; + src3 = srct; + } + + if (pPortPriv->currentBuf == 0) + dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf0Offset; + else + dst1 = (CARD8 *) mach64s->vesa.fb + pPortPriv->YBuf1Offset; + + w >>= 1; + for (j = 0; j < h; j++) + { + CARD32 *dst = (CARD32 *) dst1; + CARD8 *s1l = src1; + CARD8 *s1r = src1 + srcNext; + CARD8 *s2 = src2; + CARD8 *s3 = src3; + + for (i = 0; i < w; i++) + { + *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24); + s1l += srcRight; + s1r += srcRight; + s2 += srcRight2; + s3 += srcRight2; + } + src1 += srcDown; + dst1 += dstPitch; + if (j & 1) + { + src2 += srcDown2; + src3 += srcDown2; + } + } +} + +/* I really should stick this in miregion */ +static Bool +RegionsEqual(RegionPtr A, RegionPtr B) +{ + int *dataA, *dataB; + int num; + + num = REGION_NUM_RECTS(A); + if(num != REGION_NUM_RECTS(B)) + return FALSE; + + if((A->extents.x1 != B->extents.x1) || + (A->extents.x2 != B->extents.x2) || + (A->extents.y1 != B->extents.y1) || + (A->extents.y2 != B->extents.y2)) + return FALSE; + + dataA = (int*)REGION_RECTS(A); + dataB = (int*)REGION_RECTS(B); + + while(num--) { + if((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) + return FALSE; + dataA += 2; + dataB += 2; + } + + return TRUE; +} + +static void +mach64PaintRegion (ScreenPtr pScreen, RegionPtr pRgn, Pixel fg) +{ + WindowPtr pRoot = WindowTable[pScreen->myNum]; + GCPtr pGC; + CARD32 val[2]; + xRectangle *rects, *r; + BoxPtr pBox = REGION_RECTS (pRgn); + int nBox = REGION_NUM_RECTS (pRgn); + + rects = ALLOCATE_LOCAL (nBox * sizeof (xRectangle)); + if (!rects) + goto bail0; + r = rects; + while (nBox--) + { + r->x = pBox->x1; + r->y = pBox->y1; + r->width = pBox->x2 - pBox->x1; + r->height = pBox->y2 - pBox->y1; + r++; + pBox++; + } + + pGC = GetScratchGC (pRoot->drawable.depth, pScreen); + if (!pGC) + goto bail1; + + val[0] = fg; + val[1] = IncludeInferiors; + ChangeGC (pGC, GCForeground|GCSubwindowMode, val); + + ValidateGC (&pRoot->drawable, pGC); + + (*pGC->ops->PolyFillRect) (&pRoot->drawable, pGC, + REGION_NUM_RECTS (pRgn), rects); + + FreeScratchGC (pGC); +bail1: + DEALLOCATE_LOCAL (rects); +bail0: + ; +} + +/* Mach64ClipVideo - + + Takes the dst box in standard X BoxRec form (top and left + edges inclusive, bottom and right exclusive). The new dst + box is returned. The source boundaries are given (x1, y1 + inclusive, x2, y2 exclusive) and returned are the new source + boundaries in 16.16 fixed point. +*/ + +static void +Mach64ClipVideo(BoxPtr dst, + INT32 *x1, + INT32 *x2, + INT32 *y1, + INT32 *y2, + BoxPtr extents, /* extents of the clip region */ + INT32 width, + INT32 height) +{ + INT32 vscale, hscale, delta; + int diff; + + hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); + vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); + + *x1 <<= 16; *x2 <<= 16; + *y1 <<= 16; *y2 <<= 16; + + diff = extents->x1 - dst->x1; + if(diff > 0) { + dst->x1 = extents->x1; + *x1 += diff * hscale; + } + diff = dst->x2 - extents->x2; + if(diff > 0) { + dst->x2 = extents->x2; + *x2 -= diff * hscale; + } + diff = extents->y1 - dst->y1; + if(diff > 0) { + dst->y1 = extents->y1; + *y1 += diff * vscale; + } + diff = dst->y2 - extents->y2; + if(diff > 0) { + dst->y2 = extents->y2; + *y2 -= diff * vscale; + } + + if(*x1 < 0) { + diff = (- *x1 + hscale - 1)/ hscale; + dst->x1 += diff; + *x1 += diff * hscale; + } + delta = *x2 - (width << 16); + if(delta > 0) { + diff = (delta + hscale - 1)/ hscale; + dst->x2 -= diff; + *x2 -= diff * hscale; + } + if(*y1 < 0) { + diff = (- *y1 + vscale - 1)/ vscale; + dst->y1 += diff; + *y1 += diff * vscale; + } + delta = *y2 - (height << 16); + if(delta > 0) { + diff = (delta + vscale - 1)/ vscale; + dst->y2 -= diff; + *y2 -= diff * vscale; + } +} + +static void +mach64DisplayVideo(KdScreenInfo *screen, + int id, + int dstPitch, /* of chroma for 4:2:0 */ + int x1, + int y1, + int x2, + int y2, + int dst_x1, + int dst_y1, + int dst_x2, + int dst_y2, + short src_w, + short src_h, + short drw_w, + short drw_h) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + Reg *reg = mach64c->reg; + MediaReg *media = mach64c->media_reg; + int xscaleInt, xscaleFract, yscaleInt, yscaleFract; + int xscaleIntUV = 0, xscaleFractUV = 0; + int yscaleIntUV = 0, yscaleFractUV = 0; + int rotate = mach64s->vesa.rotate; + int HORZ_INC, VERT_INC; + CARD32 SCALER_IN; + CARD32 OVERLAY_SCALE_CNTL; + int tmp; + int left; + int bright; + int sat; + + if (id == FOURCC_UYVY) + SCALER_IN = SCALER_IN_YVYU422; + else + SCALER_IN = SCALER_IN_VYUY422; + + mach64WaitAvail (reg, 4); + + media->VIDEO_FORMAT = SCALER_IN | VIDEO_IN_VYUY422; + + /* color key */ + media->OVERLAY_GRAPHICS_KEY_MSK = (1 << screen->fb[0].depth) - 1; + media->OVERLAY_GRAPHICS_KEY_CLR = pPortPriv->colorKey; + /* set key control to obey only graphics color key */ + media->OVERLAY_KEY_CNTL = 0x50; + + mach64WaitAvail (reg, 9); + media->CAPTURE_DEBUG = 0; + /* no exclusive video region */ + media->OVERLAY_EXCLUSIVE_HORZ = 0; + media->OVERLAY_EXCLUSIVE_VERT = 0; + /* scaling coefficients */ + media->SCALER_H_COEFF0 = 0x00002000; + media->SCALER_H_COEFF1 = 0x0D06200D; + media->SCALER_H_COEFF2 = 0x0D0A1C0D; + media->SCALER_H_COEFF3 = 0x0C0E1A0C; + media->SCALER_H_COEFF4 = 0x0C14140C; + media->SCALER_TEST = 0; + + mach64WaitAvail (reg, 2); + media->OVERLAY_SCALE_CNTL = (SCALE_PIX_EXPAND | + SCALE_GAMMA_BRIGHT | + SCALE_BANDWIDTH | + SCALE_OVERLAY_EN | + SCALE_EN); + + bright = (pPortPriv->brightness * 64 / 1000); + if (bright < -0x40) + bright = -0x40; + if (bright > 0x3f) + bright = 0x3f; + bright = bright & 0x7f; + sat = ((pPortPriv->saturation * 31 + 31000) / 2000); + if (sat > 0x1f) + sat = 0x1f; + if (sat < 0) + sat = 0; + + media->SCALER_COLOUR_CNTL = ((bright << 0) | /* BRIGHTNESS */ + (sat << 8) | /* SATURATION_U */ + (sat << 16) | /* SATURATION_V */ + (0 << 21) | /* SCALER_VERT_ADJ_UV */ + (0 << 28)); /* SCALER_HORZ_ADJ_UV */ + + VERT_INC = (src_h << 12) / drw_h; + HORZ_INC = (src_w << 12) / drw_w; + + mach64WaitAvail (reg, 13); + + /* lock registers to prevent non-atomic update */ + media->OVERLAY_Y_X_START = 0x80000000 | MACH64_YX (dst_x1, dst_y1); + /* ending screen coordinate */ + media->OVERLAY_Y_X_END = 0x80000000 | MACH64_YX (dst_x2, dst_y2); + + media->OVERLAY_SCALE_INC = MACH64_YX(HORZ_INC, VERT_INC); + + media->SCALER_BUF0_OFFSET = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET = pPortPriv->YBuf1Offset; + + media->SCALER_BUF0_OFFSET_U = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET_U = pPortPriv->YBuf1Offset; + + media->SCALER_BUF0_OFFSET_V = pPortPriv->YBuf0Offset; + media->SCALER_BUF1_OFFSET_V = pPortPriv->YBuf1Offset; + + media->SCALER_BUF_PITCH = dstPitch >> 1; + media->SCALER_HEIGHT_WIDTH = MACH64_YX(src_w - (x1 >> 16), src_h - (y1 >> 16)); + + media->CAPTURE_CONFIG = pPortPriv->currentBuf << 28; + + /* set XY location and unlock */ + media->OVERLAY_Y_X_START = MACH64_YX (dst_x1, dst_y1); +} + +static int +mach64PutImage(KdScreenInfo *screen, + short src_x, + short src_y, + short drw_x, + short drw_y, + short src_w, + short src_h, + short drw_w, + short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes, + pointer data) +{ + KdCardInfo *card = screen->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data; + Reg *reg = mach64c->reg; + MediaReg *media = mach64c->media_reg; + INT32 x1, x2, y1, y2; + int rotate = mach64s->vesa.rotate; + int srcPitch, srcPitch2, dstPitch; + int top, left, npixels, nlines, size; + BoxRec dstBox; + int dst_width = width, dst_height = height; + int rot_x1, rot_y1, rot_x2, rot_y2; + int dst_x1, dst_y1, dst_x2, dst_y2; + int rot_src_w, rot_src_h, rot_drw_w, rot_drw_h; + + /* Clip */ + x1 = src_x; + x2 = src_x + src_w; + y1 = src_y; + y2 = src_y + src_h; + + dstBox.x1 = drw_x; + dstBox.x2 = drw_x + drw_w; + dstBox.y1 = drw_y; + dstBox.y2 = drw_y + drw_h; + + Mach64ClipVideo(&dstBox, &x1, &x2, &y1, &y2, + REGION_EXTENTS(pScreen, clipBoxes), width, height); + + if((x1 >= x2) || (y1 >= y2)) + return Success; + + if (!media) + return BadAlloc; + + switch (rotate) { + case 0: + case 180: + dst_width = width; + dst_height = height; + rot_src_w = src_w; + rot_src_h = src_h; + rot_drw_w = drw_w; + rot_drw_h = drw_h; + break; + case 90: + case 270: + dst_width = height; + dst_height = width; + rot_src_w = src_h; + rot_src_h = src_w; + rot_drw_w = drw_h; + rot_drw_h = drw_w; + break; + } + + switch (rotate) { + case 0: + dst_x1 = dstBox.x1; + dst_y1 = dstBox.y1; + dst_x2 = dstBox.x2; + dst_y2 = dstBox.y2; + rot_x1 = x1; + rot_y1 = y1; + rot_x2 = x2; + rot_y2 = y2; + break; + case 90: + dst_x1 = dstBox.y1; + dst_y1 = screen->height - dstBox.x2; + dst_x2 = dstBox.y2; + dst_y2 = screen->height - dstBox.x1; + + rot_x1 = y1; + rot_y1 = (src_w << 16) - x2; + rot_x2 = y2; + rot_y2 = (src_w << 16) - x1; + break; + case 180: + dst_x1 = screen->width - dstBox.x2; + dst_y1 = screen->height - dstBox.y2; + dst_x2 = screen->width - dstBox.x1; + dst_y2 = screen->height - dstBox.y1; + rot_x1 = (src_w << 16) - x2; + rot_y1 = (src_h << 16) - y2; + rot_x2 = (src_w << 16) - x1; + rot_y2 = (src_h << 16) - y1; + break; + case 270: + dst_x1 = screen->width - dstBox.y2; + dst_y1 = dstBox.x1; + dst_x2 = screen->width - dstBox.y1; + dst_y2 = dstBox.x2; + rot_x1 = (src_h << 16) - y2; + rot_y1 = x1; + rot_x2 = (src_h << 16) - y1; + rot_y2 = x2; + break; + } + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + dstPitch = ((dst_width << 1) + 15) & ~15; + srcPitch = (width + 3) & ~3; + srcPitch2 = ((width >> 1) + 3) & ~3; + size = dstPitch * (int) dst_height; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + dstPitch = ((dst_width << 1) + 15) & ~15; + srcPitch = (width << 1); + size = dstPitch * (int) dst_height; + break; + } + + pPortPriv->offset = mach64s->off_screen - (CARD8 *) mach64s->vesa.fb; + /* fixup pointers */ + + pPortPriv->YBuf0Offset = pPortPriv->offset; + pPortPriv->YBuf1Offset = pPortPriv->offset + size; + +#if 0 + mach64WaitIdle (reg); + + if (pPortPriv->videoOn) + { + /* wait for buffer to be displayed */ + while (((media->TRIG_CNTL >> 5) & 1) != pPortPriv->currentBuf) + ; + } +#endif + /* + * Use the other buffer + */ + pPortPriv->currentBuf = 1 - pPortPriv->currentBuf; + + /* copy data */ + top = rot_y1 >> 16; + left = (rot_x1 >> 16) & ~1; + npixels = ((((rot_x2 + 0xffff) >> 16) + 1) & ~1) - left; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + top &= ~1; + nlines = ((((rot_y2 + 0xffff) >> 16) + 1) & ~1) - top; + mach64CopyPlanarData(screen, buf, rotate, + srcPitch, srcPitch2, dstPitch, + rot_src_w, rot_src_h, height, + top, left, nlines, npixels, id); + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + nlines = ((rot_y2 + 0xffff) >> 16) - top; + mach64CopyPackedData(screen, buf, rotate, + srcPitch, dstPitch, + rot_src_w, rot_src_h, + top, left, nlines, + npixels); + break; + } + + mach64DisplayVideo(screen, id, dstPitch, + rot_x1, rot_y1, rot_x2, rot_y2, + dst_x1, dst_y1, + dst_x2, dst_y2, + rot_src_w, rot_src_h, rot_drw_w, rot_drw_h); + + /* update cliplist */ + if (!RegionsEqual (&pPortPriv->clip, clipBoxes)) + { + REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); + mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); + } + + pPortPriv->videoOn = TRUE; + + return Success; +} + +static int +mach64QueryImageAttributes(KdScreenInfo *screen, + int id, + unsigned short *w, + unsigned short *h, + int *pitches, + int *offsets) +{ + int size, tmp; + + if(*w > IMAGE_MAX_WIDTH) + *w = IMAGE_MAX_WIDTH; + if(*h > IMAGE_MAX_HEIGHT) + *h = IMAGE_MAX_HEIGHT; + + *w = (*w + 1) & ~1; + if(offsets) offsets[0] = 0; + + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + *h = (*h + 1) & ~1; + size = (*w + 3) & ~3; + if(pitches) + pitches[0] = size; + size *= *h; + if(offsets) + offsets[1] = size; + tmp = ((*w >> 1) + 3) & ~3; + if(pitches) + pitches[1] = pitches[2] = tmp; + tmp *= (*h >> 1); + size += tmp; + if(offsets) + offsets[2] = size; + size += tmp; + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + default: + size = *w << 1; + if(pitches) + pitches[0] = size; + size *= *h; + break; + } + + return size; +} + + +/* client libraries expect an encoding */ +static KdVideoEncodingRec DummyEncoding[1] = +{ + { + 0, + "XV_IMAGE", + IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, + {1, 1} + } +}; + +#define NUM_FORMATS 3 + +static KdVideoFormatRec Formats[NUM_FORMATS] = +{ + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +#define NUM_ATTRIBUTES 3 + +static KdAttributeRec Attributes[NUM_ATTRIBUTES] = +{ + {XvSettable | XvGettable, 0, ~0, "XV_COLORKEY"}, + {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"}, + {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"} +}; + +#define NUM_IMAGES 4 + +static KdImageRec Images[NUM_IMAGES] = +{ + XVIMAGE_YUY2, + XVIMAGE_YV12, + XVIMAGE_I420, + XVIMAGE_UYVY +}; + +static void mach64ResetVideo(KdScreenInfo *screen) +{ + ScreenPtr pScreen = screen->pScreen; + KdScreenPriv(pScreen); + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + Mach64PortPrivPtr pPortPriv = mach64s->pAdaptor->pPortPrivates[0].ptr; + MediaReg *media = mach64c->media_reg; + + /* + * Default to maximum image size in YV12 + */ + +} + +static int +mach64ReputImage (KdScreenInfo *screen, + short drw_x, + short drw_y, + RegionPtr clipBoxes, + pointer data) +{ + ScreenPtr pScreen = screen->pScreen; + Mach64PortPrivPtr pPortPriv = (Mach64PortPrivPtr)data; + BoxPtr pOldExtents = REGION_EXTENTS (pScreen, &pPortPriv->clip); + BoxPtr pNewExtents = REGION_EXTENTS (pScreen, clipBoxes); + + if (pOldExtents->x1 == pNewExtents->x1 && + pOldExtents->x2 == pNewExtents->x2 && + pOldExtents->y1 == pNewExtents->y1 && + pOldExtents->y2 == pNewExtents->y2) + { + /* update cliplist */ + if (!RegionsEqual (&pPortPriv->clip, clipBoxes)) + { + REGION_COPY (screen->pScreen, &pPortPriv->clip, clipBoxes); + mach64PaintRegion (screen->pScreen, &pPortPriv->clip, pPortPriv->colorKey); + } + return Success; + } + return BadMatch; +} + +static KdVideoAdaptorPtr +mach64SetupImageVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + mach64CardInfo(pScreenPriv); + mach64ScreenInfo(pScreenPriv); + KdScreenInfo *screen = pScreenPriv->screen; + KdCardInfo *card = pScreenPriv->card; + KdVideoAdaptorPtr adapt; + Mach64PortPrivPtr pPortPriv; + + if(!(adapt = xcalloc(1, sizeof(KdVideoAdaptorRec) + + sizeof(Mach64PortPrivRec) + + sizeof(DevUnion)))) + return NULL; + + adapt->type = XvWindowMask | XvInputMask | XvImageMask; + adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; + adapt->name = "Mach64 Video Overlay"; + adapt->nEncodings = 1; + adapt->pEncodings = DummyEncoding; + adapt->nFormats = NUM_FORMATS; + adapt->pFormats = Formats; + adapt->nPorts = 1; + adapt->pPortPrivates = (DevUnion*)(&adapt[1]); + + pPortPriv = (Mach64PortPrivPtr)(&adapt->pPortPrivates[1]); + + adapt->pPortPrivates[0].ptr = (pointer)(pPortPriv); + adapt->pAttributes = Attributes; + adapt->nImages = NUM_IMAGES; + adapt->nAttributes = NUM_ATTRIBUTES; + adapt->pImages = Images; + adapt->PutVideo = NULL; + adapt->PutStill = NULL; + adapt->GetVideo = NULL; + adapt->GetStill = NULL; + adapt->StopVideo = mach64StopVideo; + adapt->SetPortAttribute = mach64SetPortAttribute; + adapt->GetPortAttribute = mach64GetPortAttribute; + adapt->QueryBestSize = mach64QueryBestSize; + adapt->PutImage = mach64PutImage; + adapt->ReputImage = mach64ReputImage; + adapt->QueryImageAttributes = mach64QueryImageAttributes; + + pPortPriv->colorKey = mach64s->colorKey; + pPortPriv->videoOn = FALSE; + pPortPriv->brightness = 0; + pPortPriv->saturation = 0; + pPortPriv->currentBuf = 0; + + /* gotta uninit this someplace */ + REGION_INIT(pScreen, &pPortPriv->clip, NullBox, 0); + + mach64s->pAdaptor = adapt; + + xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); + xvSaturation = MAKE_ATOM("XV_SATURATION"); + xvColorKey = MAKE_ATOM("XV_COLORKEY"); + + mach64ResetVideo(screen); + + return adapt; +} + +Bool mach64InitVideo(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + KdVideoAdaptorPtr *adaptors, *newAdaptors = NULL; + KdVideoAdaptorPtr newAdaptor = NULL; + int num_adaptors; + KdCardInfo *card = pScreenPriv->card; + Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; + Mach64CardInfo *mach64c = (Mach64CardInfo *) card->driver; + + if (!mach64c->media_reg) + return FALSE; + + newAdaptor = mach64SetupImageVideo(pScreen); + + num_adaptors = KdXVListGenericAdaptors(screen, &adaptors); + + if(newAdaptor) + { + if(!num_adaptors) + { + num_adaptors = 1; + adaptors = &newAdaptor; + } + else + { + newAdaptors = xalloc((num_adaptors + 1) * + sizeof(KdVideoAdaptorPtr*)); + if(newAdaptors) + { + memcpy(newAdaptors, adaptors, + num_adaptors * sizeof(KdVideoAdaptorPtr)); + newAdaptors[num_adaptors] = newAdaptor; + adaptors = newAdaptors; + num_adaptors++; + } + } + } + + if(num_adaptors) + KdXVScreenInit(pScreen, adaptors, num_adaptors); + + if(newAdaptors) + xfree(newAdaptors); + return TRUE; +} diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile b/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile new file mode 100644 index 000000000..4a2c059ba --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile @@ -0,0 +1,13 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/Imakefile,v 1.1 2001/05/23 08:56:08 alanh Exp $ +KDRIVE=.. +#include "../Kdrive.tmpl" + +SRCS = pcmcia.c pcmciacurs.c pcmciastub.c pcmciashadow.c + +OBJS = pcmcia.o pcmciacurs.o pcmciastub.o pcmciashadow.o + +INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev + +NormalLibraryObjectRule() +NormalLibraryTarget(pcmcia,$(OBJS)) +DependTarget() diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h b/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h new file mode 100644 index 000000000..49c7d5f42 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/modes.h @@ -0,0 +1,66 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/modes.h,v 1.1 2001/05/23 08:56:08 alanh Exp $ */ + +#define V_NHSYNC 0x01 +#define V_NVSYNC 0x02 +#define V_PHSYNC 0x04 +#define V_PVSYNC 0x08 +#define V_INTERLACE 0x10 + +pcmciaDisplayModeRec pcmciaDefaultModes [] = { +/* 640x400 @ 70Hz (VGA) hsync: 37.9kHz */ + {640, 400, 70 ,31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC}, +/* 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz */ + {640, 480, 60 ,25200, 640,656,752,800,0, 480,490,492,525,0, V_NHSYNC | V_NVSYNC}, +/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */ + {640, 480, 72 ,31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC}, +/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */ + {640, 480, 75 ,31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC}, +/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */ + {640, 480, 85 ,36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC}, +/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */ + {800, 600, 56 ,36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC}, +/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */ + {800, 600, 60 ,40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC}, +/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */ + {800, 600, 72 ,50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC}, +/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */ + {800, 600, 75 ,49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC}, +/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */ + {800, 600, 85 ,56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC}, +/* 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz */ + {1024, 768, 43 ,44900, 1024,1032,1208,1264,0, 768,768,776,817,0, V_PHSYNC | V_PVSYNC | V_INTERLACE}, +/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */ + {1024, 768, 60 ,65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC}, +/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */ + {1024, 768, 70 ,75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC}, +/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */ + {1024, 768, 75 ,78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC}, +/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */ + {1024, 768, 85 ,94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC}, +/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */ + {1152, 864, 75 ,108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} +}; diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c new file mode 100644 index 000000000..88bab0237 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c @@ -0,0 +1,1251 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + * + * A driver for the following PCMCIA cards... + * Hewlett Packards HP VGA Out (Model F1252A) + * Colorgraphics Voyager VGA + * + * Tested running under a Compaq IPAQ Pocket PC running Linux + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.c,v 1.5 2001/07/20 19:35:30 keithp Exp $ */ + +#include "pcmcia.h" +#define extern +#include <asm/io.h> +#undef extern + +#define CLOCK 14318 /* KHz */ +#define CLK_N(a,b) (a & 0xff) +#define CLK_M(a,b) ((b) & 0x3f) +#define CLK_K(a,b) (((b) >> 6) & 3) +#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b))) + +#include "modes.h" + +extern void +tridentUpdatePacked (ScreenPtr pScreen, + shadowBufPtr pBuf); +extern void +cirrusUpdatePacked (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +pcmciaCardInit (KdCardInfo *card) +{ + pcmciaCardInfo *pcmciac; + CARD8 r9; + + pcmciac = (pcmciaCardInfo *) xalloc (sizeof (pcmciaCardInfo)); + if (!pcmciac) + return FALSE; + + pcmciac->cop_base = (CARD8 *) KdMapDevice (PCMCIA_COP_BASE(card), + PCMCIA_COP_SIZE(card)); + + r9 = pcmciaReadIndex (pcmciac, 0x3c4, 0x09); + /* + * Crude detection.... + * The trident chip has a read only register at 0x09, which returns 0x4. + * If it's not that, we assume the cirrus chip. + * BREAKAGE.! If we have an anonymous PCMCIA card inserted, we could + * potentially smash something here. FIXME ! + */ + if (r9 == 0x04) { + ErrorF("PCMCIA: Found HP VGA card\n"); + pcmciac->HP = TRUE; /* Select HP VGA Out Card */ + } else { + ErrorF("PCMCIA: Found Voyager VGA card\n"); + pcmciac->HP = FALSE; /* Select Voyager VGA Card */ + } + + if (pcmciac->HP) { + /* needed by the accelerator - later */ + pcmciac->cop = (Cop *) (pcmciac->cop_base + TRIDENT_COP_OFF(card)); + } + + /* + * Map frame buffer + */ + if (pcmciac->HP) + pcmciac->fb = KdMapDevice (0x2ce00000, 0x80000); + else + pcmciac->fb = KdMapDevice (0x2c0a0000, 0x10000); /*64K bank switched*/ + + if (!pcmciac->fb) + return FALSE; + + pcmciac->window = 0; + + card->driver = pcmciac; + + return TRUE; +} + +Bool +pcmciaScreenInit (KdScreenInfo *screen) +{ + pcmciaCardInfo *pcmciac = screen->card->driver; + pcmciaScreenInfo *pcmcias; + int screen_size, memory; + int i; + + pcmcias = (pcmciaScreenInfo *) xalloc (sizeof (pcmciaScreenInfo)); + if (!pcmcias) + return FALSE; + memset (pcmcias, '\0', sizeof (pcmciaScreenInfo)); + + /* if (!pcmciac->cop) */ + screen->dumb = TRUE; + + /* default to 8bpp */ + if (!screen->fb[0].depth) + screen->fb[0].depth = 8; + + /* default to 60Hz refresh */ + if (!screen->rate) + screen->rate = 60; + + i = 0; + pcmcias->Mode = -1; + while (pcmciaDefaultModes[i].Width != 0) { + if ( (screen->width == pcmciaDefaultModes[i].Width) && + (screen->height == pcmciaDefaultModes[i].Height) && + (screen->rate == pcmciaDefaultModes[i].Refresh) ) { + pcmcias->Mode = i; + break; + } + i++; + } + + if ( pcmcias->Mode == -1 ) { + ErrorF("PCMCIA: no matching vesa mode for screen selection, aborting.\n"); + ErrorF("PCMCIA: use -listmodes to check for supported list of modes.\n"); + return FALSE; /* end of list */ + } + + pcmcias->rotation = screen->rotation; + + memory = 512 * 1024; + pcmcias->screen = pcmciac->fb; + + if (pcmciac->HP && !screen->softCursor && screen->fb[0].depth == 8) { + /* Let's do hw cursor for the HP card, only in 8bit mode though */ + pcmcias->cursor_base = pcmcias->screen + memory - 4096; + memory -= 4096; + } + + if (screen->fb[0].depth == 4) { + ErrorF("PCMCIA: depth 4 isn't supported.\n"); + return FALSE; /* screen->fb[0].bitsPerPixel = 4; need fb to support it*/ + } else + if (screen->fb[0].depth == 8) + screen->fb[0].bitsPerPixel = 8; + else + if (screen->fb[0].depth == 15 || + screen->fb[0].depth == 16) + screen->fb[0].bitsPerPixel = 16; + + if ( (screen->width * screen->height * + (screen->fb[0].bitsPerPixel / 8)) > memory) { + ErrorF("PCMCIA: Not enough memory for resolution requested, aborting.\n"); + return FALSE; + } + + screen->fb[0].pixelStride = screen->width; + screen->fb[0].byteStride = screen->width * (screen->fb[0].bitsPerPixel >>3); + + screen->fb[0].frameBuffer = pcmciac->fb; + switch (screen->fb[0].depth) { + case 4: + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor)); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + case 8: + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + case 15: + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].blueMask = 0x001f; + screen->fb[0].greenMask = 0x03e0; + screen->fb[0].redMask = 0x7c00; + break; + case 16: + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].blueMask = 0x001f; + screen->fb[0].greenMask = 0x07e0; + screen->fb[0].redMask = 0xf800; + break; + } + screen_size = screen->fb[0].byteStride * screen->height; + + screen->driver = pcmcias; + + return TRUE; +} + +void * +tridentWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + + if (!pScreenPriv->enabled) + return 0; + + *size = pScreenPriv->screen->fb[0].byteStride; + return (CARD8 *) pcmciac->fb + row * pScreenPriv->screen->fb[0].byteStride + offset; +} + +void * +cirrusWindowWindowed (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + int bank, boffset; + + if (!pScreenPriv->enabled) + return 0; + + bank = (row * pScreenPriv->screen->fb[0].byteStride) / 0x1000; + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0B, 0x0c); + pcmciaWriteIndex(pcmciac, 0x3ce, 0x09, bank); + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0A, bank); + *size = pScreenPriv->screen->fb[0].byteStride; + return (CARD8 *) pcmciac->fb + (row * pScreenPriv->screen->fb[0].byteStride) - (bank * 0x1000) + offset; +} + +LayerPtr +pcmciaLayerCreate (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver; + ShadowUpdateProc update; + ShadowWindowProc window; + KdMouseMatrix m; + PixmapPtr pPixmap; + int kind; + + switch (pcmcias->rotation) { + case 0: + pScreen->width = screen->width; + pScreen->height = screen->height; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0; + m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0; + break; + case 90: + pScreen->width = screen->height; + pScreen->height = screen->width; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = screen->height - 1; + m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0; + break; + case 180: + pScreen->width = screen->width; + pScreen->height = screen->height; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = screen->width - 1; + m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = screen->height - 1; + break; + case 270: + pScreen->width = screen->height; + pScreen->height = screen->width; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0; + m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = screen->width - 1; + break; + } + KdSetMouseMatrix (&m); + + if (pcmciac->HP) { + window = tridentWindowLinear; + switch (pcmcias->rotation) { + case 0: + update = tridentUpdatePacked; + break; + case 90: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_90; break; + case 16: + update = shadowUpdateRotate16_90; break; + } + break; + case 180: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_180; break; + case 16: + update = shadowUpdateRotate16_180; break; + } + break; + case 270: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_270; break; + case 16: + update = shadowUpdateRotate16_270; break; + } + break; + } + } else { + window = cirrusWindowWindowed; + switch (pcmcias->rotation) { + case 0: + update = cirrusUpdatePacked; + break; + case 90: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_90; break; + case 16: + update = shadowUpdateRotate16_90; break; + } + break; + case 180: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_180; break; + case 16: + update = shadowUpdateRotate16_180; break; + } + break; + case 270: + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 8: + update = shadowUpdateRotate8_270; break; + case 16: + update = shadowUpdateRotate16_270; break; + } + break; + } + } + + if (!update) + abort (); + + kind = LAYER_SHADOW; + pPixmap = 0; + + return LayerCreate (pScreen, kind, screen->fb[0].depth, + pPixmap, update, window, pcmcias->rotation, 0); +} + +#ifdef RANDR +Bool +pcmciaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + KdScreenInfo *screen = pScreenPriv->screen; + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver; + RRVisualGroupPtr pVisualGroup; + RRGroupOfVisualGroupPtr pGroupOfVisualGroup; + RRScreenSizePtr pSize; + Rotation rotateKind; + int rotation; + int n; + + *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270; + + for (n = 0; n < pScreen->numDepths; n++) + if (pScreen->allowedDepths[n].numVids) + break; + if (n == pScreen->numDepths) + return FALSE; + + pVisualGroup = RRCreateVisualGroup (pScreen); + if (!pVisualGroup) + return FALSE; + if (!RRAddDepthToVisualGroup (pScreen, + pVisualGroup, + &pScreen->allowedDepths[n])) + { + RRDestroyVisualGroup (pScreen, pVisualGroup); + return FALSE; + } + + pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup); + if (!pVisualGroup) + return FALSE; + + pGroupOfVisualGroup = RRCreateGroupOfVisualGroup (pScreen); + + if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen, + pGroupOfVisualGroup, + pVisualGroup)) + { + RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + /* pVisualGroup left until screen closed */ + return FALSE; + } + + pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + if (!pGroupOfVisualGroup) + return FALSE; + + pSize = RRRegisterSize (pScreen, + screen->width, + screen->height, + screen->width_mm, + screen->height_mm, + pGroupOfVisualGroup); + + rotation = pcmcias->rotation - screen->rotation; + if (rotation < 0) + rotation += 360; + + switch (rotation) + { + case 0: + rotateKind = RR_Rotate_0; + break; + case 90: + rotateKind = RR_Rotate_90; + break; + case 180: + rotateKind = RR_Rotate_180; + break; + case 270: + rotateKind = RR_Rotate_270; + break; + } + + RRSetCurrentConfig (pScreen, rotateKind, pSize, pVisualGroup); + + return TRUE; + } + +int +pcmciaLayerAdd (WindowPtr pWin, pointer value) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + LayerPtr pLayer = (LayerPtr) value; + + if (!LayerWindowAdd (pScreen, pLayer, pWin)) + return WT_STOPWALKING; + + return WT_WALKCHILDREN; +} + +int +pcmciaLayerRemove (WindowPtr pWin, pointer value) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + LayerPtr pLayer = (LayerPtr) value; + + LayerWindowRemove (pScreen, pLayer, pWin); + + return WT_WALKCHILDREN; +} + +pcmciaRandRSetConfig (ScreenPtr pScreen, + Rotation rotateKind, + RRScreenSizePtr pSize, + RRVisualGroupPtr pVisualGroup) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + FbdevPriv *priv = pScreenPriv->card->driver; + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver; + int rotation; + Bool wasEnabled = pScreenPriv->enabled; + + /* + * The only thing that can change is rotation + */ + switch (rotateKind) + { + case RR_Rotate_0: + rotation = screen->rotation; + break; + case RR_Rotate_90: + rotation = screen->rotation + 90; + break; + case RR_Rotate_180: + rotation = screen->rotation + 180; + break; + case RR_Rotate_270: + rotation = screen->rotation + 270; + break; + } + if (rotation >= 360) + rotation -= 360; + + if (pcmcias->rotation != rotation) + { + LayerPtr pNewLayer; + int kind; + int oldrotation = pcmcias->rotation; + int oldwidth = pScreen->width; + int oldheight = pScreen->height; + PixmapPtr pPixmap; + + if (wasEnabled) + KdDisableScreen (pScreen); + + pcmcias->rotation = rotation; + pNewLayer = pcmciaLayerCreate (pScreen); + if (!pNewLayer) + { + pcmcias->rotation = oldrotation; + } + if (WalkTree (pScreen, pcmciaLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING) + { + WalkTree (pScreen, pcmciaLayerRemove, (pointer) pNewLayer); + LayerDestroy (pScreen, pNewLayer); + pcmcias->rotation = oldrotation; + pScreen->width = oldwidth; + pScreen->height = oldheight; + if (wasEnabled) + KdEnableScreen (pScreen); + return FALSE; + } + WalkTree (pScreen, pcmciaLayerRemove, (pointer) pcmcias->pLayer); + LayerDestroy (pScreen, pcmcias->pLayer); + pcmcias->pLayer = pNewLayer; + if (wasEnabled) + KdEnableScreen (pScreen); + } + return TRUE; +} + +Bool +pcmciaRandRInit (ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRScreenInit (pScreen)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = pcmciaRandRGetInfo; + pScrPriv->rrSetConfig = pcmciaRandRSetConfig; + return TRUE; +} +#endif + +Bool +pcmciaInitScreen (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver; + + if (!LayerStartInit (pScreen)) + return FALSE; + if (!LayerFinishInit (pScreen)) + return FALSE; + pcmcias->pLayer = pcmciaLayerCreate (pScreen); + if (!pcmcias->pLayer) + return FALSE; +#ifdef RANDR + if (!pcmciaRandRInit (pScreen)) + return FALSE; +#endif + return TRUE; +} + +CARD8 +pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index) +{ + CARD8 value; + + pcmciac->cop_base[port] = index; + value = pcmciac->cop_base[port+1]; + return value; +} + +void +pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value) +{ + pcmciac->cop_base[port] = index; + pcmciac->cop_base[port+1] = value; +} + +CARD8 +pcmciaReadReg (pcmciaCardInfo *pcmciac, CARD16 port) +{ + CARD8 value; + + value = pcmciac->cop_base[port]; + + return value; +} + +void +pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value) +{ + pcmciac->cop_base[port] = value; +} + + +void +pcmciaPause () +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = 50 * 1000; + select (1, 0, 0, 0, &tv); +} + +void +pcmciaPreserve (KdCardInfo *card) +{ +} + +/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */ +#define CLOCK_FACTOR 28636 + +/* stability constraints for internal VCO -- MAX_VCO also determines the maximum Video pixel clock */ +#define MIN_VCO CLOCK_FACTOR +#define MAX_VCO 111000 + +/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */ +#define VCOVAL(n, d) \ + ((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) ) + +#define CLOCKVAL(n, d) \ + (VCOVAL(n, d) >> ((d) & 1)) + +int CirrusFindClock(freq, max_clock, num_out, den_out) + int freq; + int max_clock; + int *num_out; + int *den_out; +{ + int n; + int num = 0, den = 0; + int mindiff; + + /* + * If max_clock is greater than the MAX_VCO default, ignore + * MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock, + * make use of the higher MAX_VCO value. + */ + if (MAX_VCO > max_clock) + max_clock = MAX_VCO; + + mindiff = freq; + for (n = 0x10; n < 0x7f; n++) { + int d; + for (d = 0x14; d < 0x3f; d++) { + int c, diff; + /* Avoid combinations that can be unstable. */ + if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock)) + continue; + c = CLOCKVAL(n, d); + diff = abs(c - freq); + if (diff < mindiff) { + mindiff = diff; + num = n; + den = d; + } + } + } + + *num_out = num; + *den_out = den; + + return 0; +} + + +void +tridentSetCLK(int clock, CARD8 *a, CARD8 *b) +{ + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m, n, k; + int p, q, r, s; + int startn, endn; + int endm, endk; + + p = q = r = s = 0; + + startn = 0; + endn = 121; + endm = 31; + endk = 1; + + freq = clock; + + for (k=0;k<=endk;k++) + for (n=startn;n<=endn;n++) + for (m=1;m<=endm;m++) + { + ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) )); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; + } + } + +#if 0 + ErrorF ("ffreq %d clock %d\n", s, clock); +#endif + if (s == 0) + { + FatalError("Unable to set programmable clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + /* N is first 7bits, first M bit is 8th bit */ + *a = ((1 & q) << 7) | p; + /* first 4bits are rest of M, 1bit for K value */ + *b = (((q & 0xFE) >> 1) | (r << 4)); +} + +Bool +pcmciaEnable (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) pScreenPriv->screen->driver; + int i,j; + unsigned char Sequencer[6]; + unsigned char CRTC[31]; + unsigned char Graphics[9]; + unsigned char Attribute[21]; + unsigned char MiscOutReg; + pcmciaDisplayModeRec mode = pcmciaDefaultModes[pcmcias->Mode]; + + /* + * compute correct Hsync & Vsync polarity + */ + if ((mode.Flags & (V_PHSYNC | V_NHSYNC)) + && (mode.Flags & (V_PVSYNC | V_NVSYNC))) + { + MiscOutReg = 0x23; + if (mode.Flags & V_NHSYNC) MiscOutReg |= 0x40; + if (mode.Flags & V_NVSYNC) MiscOutReg |= 0x80; + } + else + { + int VDisplay = mode.VDisplay; + if (VDisplay < 400) + MiscOutReg = 0xA3; /* +hsync -vsync */ + else if (VDisplay < 480) + MiscOutReg = 0x63; /* -hsync +vsync */ + else if (VDisplay < 768) + MiscOutReg = 0xE3; /* -hsync -vsync */ + else + MiscOutReg = 0x23; /* +hsync +vsync */ + } + + /* + * Time Sequencer + */ + if (pScreenPriv->screen->fb[0].depth == 4) + Sequencer[0] = 0x02; + else + Sequencer[0] = 0x00; + Sequencer[1] = 0x01; + Sequencer[2] = 0x0F; + Sequencer[3] = 0x00; /* Font select */ + if (pScreenPriv->screen->fb[0].depth < 8) + Sequencer[4] = 0x06; /* Misc */ + else + Sequencer[4] = 0x0E; /* Misc */ + Sequencer[5] = 0x00; + + /* + * CRTC Controller + */ + CRTC[0] = (mode.HTotal >> 3) - 5; + CRTC[1] = (mode.HDisplay >> 3) - 1; + CRTC[2] = ((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1; + CRTC[3] = ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F) | 0x80; + i = (((mode.HSkew << 2) + 0x10) & ~0x1F); + if (i < 0x80) + CRTC[3] |= i; + CRTC[4] = (mode.HSyncStart >> 3); + CRTC[5] = (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2) + | (((mode.HSyncEnd >> 3)) & 0x1F); + CRTC[6] = (mode.VTotal - 2) & 0xFF; + CRTC[7] = (((mode.VTotal - 2) & 0x100) >> 8) + | (((mode.VDisplay - 1) & 0x100) >> 7) + | ((mode.VSyncStart & 0x100) >> 6) + | ((((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0x100) >> 5) + | 0x10 + | (((mode.VTotal - 2) & 0x200) >> 4) + | (((mode.VDisplay - 1) & 0x200) >> 3) + | ((mode.VSyncStart & 0x200) >> 2); + CRTC[8] = 0x00; + CRTC[9] = ((((min(mode.VSyncStart,mode.VDisplay))-1) & 0x200) >> 4) | 0x40; + CRTC[10] = 0x00; + CRTC[11] = 0x00; + CRTC[12] = 0x00; + CRTC[13] = 0x00; + CRTC[14] = 0x00; + CRTC[15] = 0x00; + CRTC[16] = mode.VSyncStart & 0xFF; + CRTC[17] = (mode.VSyncEnd & 0x0F) | 0x20; + CRTC[18] = (mode.VDisplay - 1) & 0xFF; + if (pScreenPriv->screen->fb[0].depth == 4) + CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 4; + else + if (pScreenPriv->screen->fb[0].depth == 8) + CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 3; + else + if (pScreenPriv->screen->fb[0].depth == 16 || + pScreenPriv->screen->fb[0].depth == 15) + CRTC[19] = pScreenPriv->screen->fb[0].pixelStride >> 2; + CRTC[20] = 0x00; + CRTC[21] = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF; + CRTC[22] = ((min(mode.VSyncEnd,mode.VDisplay)) - 1) & 0xFF; + if (pScreenPriv->screen->fb[0].depth < 8) + CRTC[23] = 0xE3; + else + CRTC[23] = 0xC3; + CRTC[24] = 0xFF; + CRTC[25] = 0x00; + CRTC[26] = 0x00; + if (!pcmciac->HP) + if (mode.Flags & V_INTERLACE) CRTC[26] |= 0x01; + if (pcmciac->HP) + CRTC[27] = 0x00; + else + CRTC[27] = 0x22; + CRTC[28] = 0x00; + CRTC[29] = 0x00; + CRTC[30] = 0x80; + if (pcmciac->HP) + if (mode.Flags & V_INTERLACE) CRTC[30] |= 0x04; + +{ + int nExtBits = 0; + CARD32 ExtBits; + CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6; + + CRTC[3] = (CRTC[3] & ~0x1F) + | ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x1F); + CRTC[5] = (CRTC[5] & ~0x80) + | (((((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & 0x20) << 2); + ExtBits = (((min(mode.HSyncEnd,mode.HTotal)) >> 3) - 1) & ExtBitMask; + + /* First the horizontal case */ + if ((((min(mode.HSyncEnd,mode.HTotal)) >> 3) == (mode.HTotal >> 3))) + { + int i = (CRTC[3] & 0x1F) + | ((CRTC[5] & 0x80) >> 2) + | ExtBits; + if ((i-- > ((((min(mode.HSyncStart,mode.HDisplay)) >> 3) - 1) + & (0x3F | ExtBitMask))) + && ((min(mode.HSyncEnd,mode.HTotal)) == mode.HTotal)) + i = 0; + CRTC[3] = (CRTC[3] & ~0x1F) | (i & 0x1F); + CRTC[5] = (CRTC[5] & ~0x80) | ((i << 2) & 0x80); + ExtBits = i & ExtBitMask; + } +} +{ + CARD32 ExtBits; + CARD32 ExtBitMask = 0; + /* If width is not known nBits should be 0. In this + * case BitMask is set to 0 so we can check for it. */ + CARD32 BitMask = 0; + int VBlankStart = ((min(mode.VSyncStart,mode.VDisplay)) - 1) & 0xFF; + CRTC[22] = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & 0xFF; + ExtBits = ((min(mode.VSyncEnd,mode.VTotal)) - 1) & ExtBitMask; + + if ((min(mode.VSyncEnd,mode.VTotal)) == mode.VTotal) + /* Null top overscan */ + { + int i = CRTC[22] | ExtBits; + if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask))) + || ((i > VBlankStart) && /* 8-bit case */ + ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */ + !(CRTC[9] & 0x9F)) /* 1 scanline/row */ + i = 0; + else + i = (i - 1); + CRTC[22] = i & 0xFF; + ExtBits = i & 0xFF00; + } +} + + /* + * Graphics Display Controller + */ + Graphics[0] = 0x00; + Graphics[1] = 0x00; + Graphics[2] = 0x00; + Graphics[3] = 0x00; + Graphics[4] = 0x00; + if (pScreenPriv->screen->fb[0].depth == 4) + Graphics[5] = 0x02; + else + Graphics[5] = 0x40; + Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */ + Graphics[7] = 0x0F; + Graphics[8] = 0xFF; + + Attribute[0] = 0x00; /* standard colormap translation */ + Attribute[1] = 0x01; + Attribute[2] = 0x02; + Attribute[3] = 0x03; + Attribute[4] = 0x04; + Attribute[5] = 0x05; + Attribute[6] = 0x06; + Attribute[7] = 0x07; + Attribute[8] = 0x08; + Attribute[9] = 0x09; + Attribute[10] = 0x0A; + Attribute[11] = 0x0B; + Attribute[12] = 0x0C; + Attribute[13] = 0x0D; + Attribute[14] = 0x0E; + Attribute[15] = 0x0F; + if (pScreenPriv->screen->fb[0].depth == 4) + Attribute[16] = 0x81; + else + Attribute[16] = 0x41; + if (pScreenPriv->screen->fb[0].bitsPerPixel == 16) + Attribute[17] = 0x00; + else + Attribute[17] = 0xFF; + Attribute[18] = 0x0F; + Attribute[19] = 0x00; + Attribute[20] = 0x00; + + /* Wake up the card */ + if (pcmciac->HP) { + pcmciaWriteReg(pcmciac, 0x3c3, 0x1); + pcmciaWriteReg(pcmciac, 0x46e8, 0x10); + } else { + pcmciaWriteReg(pcmciac, 0x105, 0x1); + pcmciaWriteReg(pcmciac, 0x46e8, 0x1f); + pcmciaWriteReg(pcmciac, 0x102, 0x1); + pcmciaWriteReg(pcmciac, 0x46e8, 0xf); + pcmciaWriteReg(pcmciac, 0x3c3, 0x1); + } + + if (pcmciac->HP) { + /* unlock */ + pcmciaWriteIndex(pcmciac, 0x3c4, 0x11, 0x92); + j = pcmciaReadIndex(pcmciac, 0x3c4, 0xb); + pcmciaWriteIndex(pcmciac, 0x3c4, 0xe, 0xc2); + + /* switch on dac */ + pcmciaWriteIndex(pcmciac, 0x3d4, 0x29, 0x24); + /* switch on the accelerator */ + pcmciaWriteIndex(pcmciac, 0x3d4, 0x36, 0x80); + + /* bump up memory clk */ + pcmciaWriteReg(pcmciac, 0x43c6, 0x65); + pcmciaWriteReg(pcmciac, 0x43c7, 0x00); + } else { + /* unlock */ + pcmciaWriteIndex(pcmciac, 0x3c4, 0x06, 0x12); + pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg); + } + + /* synchronous reset */ + pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0); + + pcmciaWriteReg(pcmciac, 0x3da, 0x10); + + for (i=0;i<6;i++) + pcmciaWriteIndex(pcmciac, 0x3c4, i, Sequencer[i]); + + if (pcmciac->HP) { + /* Stick chip into color mode */ + pcmciaWriteIndex(pcmciac, 0x3ce, 0x2f, 0x06); + /* Switch on Linear addressing */ + pcmciaWriteIndex(pcmciac, 0x3d4, 0x21, 0x2e); + } else { + /* Stick chip into 8bit access mode - ugh! */ + pcmciaWriteIndex(pcmciac, 0x3c4, 0x0F, 0x20); /* 0x26 ? */ + /* reset mclk */ + pcmciaWriteIndex(pcmciac, 0x3c4, 0x1F, 0); + } + + pcmciaWriteIndex(pcmciac, 0x3c4, 0, 0x3); + + for (i=0;i<31;i++) + pcmciaWriteIndex(pcmciac, 0x3d4, i, CRTC[i]); + + for (i=0;i<9;i++) + pcmciaWriteIndex(pcmciac, 0x3ce, i, Graphics[i]); + + j = pcmciaReadReg(pcmciac, 0x3da); + + for (i=0;i<21;i++) { + pcmciaWriteReg(pcmciac, 0x3c0, i); + pcmciaWriteReg(pcmciac, 0x3c0, Attribute[i]); + } + + j = pcmciaReadReg(pcmciac, 0x3da); + pcmciaWriteReg(pcmciac, 0x3c0, 0x20); + + j = pcmciaReadReg(pcmciac, 0x3c8); + j = pcmciaReadReg(pcmciac, 0x3c6); + j = pcmciaReadReg(pcmciac, 0x3c6); + j = pcmciaReadReg(pcmciac, 0x3c6); + j = pcmciaReadReg(pcmciac, 0x3c6); + switch (pScreenPriv->screen->fb[0].depth) { + /* This is here for completeness, when/if we ever do 4bpp */ + case 4: + pcmciaWriteReg(pcmciac, 0x3c6, 0x0); + if (pcmciac->HP) { + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x90); + pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00); + } else + pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x00); + break; + case 8: + pcmciaWriteReg(pcmciac, 0x3c6, 0x0); + if (pcmciac->HP) { + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x92); + pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x00); + } else + pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x01); + break; + case 15: + if (pcmciac->HP) { + pcmciaWriteReg(pcmciac, 0x3c6, 0x10); + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a); + pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04); + } else { + pcmciaWriteReg(pcmciac, 0x3c6, 0xC0); + pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03); + } + break; + case 16: + if (pcmciac->HP) { + pcmciaWriteReg(pcmciac, 0x3c6, 0x30); + pcmciaWriteIndex(pcmciac, 0x3ce, 0x0f, 0x9a); + pcmciaWriteIndex(pcmciac, 0x3d4, 0x38, 0x04); + } else { + pcmciaWriteReg(pcmciac, 0x3c6, 0xC1); + pcmciaWriteIndex(pcmciac, 0x3c4, 0x07, 0x03); + } + break; + } + j = pcmciaReadReg(pcmciac, 0x3c8); + + pcmciaWriteReg(pcmciac, 0x3c6, 0xff); + + for (i=0;i<256;i++) { + pcmciaWriteReg(pcmciac, 0x3c8, i); + pcmciaWriteReg(pcmciac, 0x3c9, i); + pcmciaWriteReg(pcmciac, 0x3c9, i); + pcmciaWriteReg(pcmciac, 0x3c9, i); + } + + /* Set the Clock */ + if (pcmciac->HP) { + CARD8 a,b; + int clock = mode.Clock; + if (pScreenPriv->screen->fb[0].bitsPerPixel == 16) + clock *= 2; + tridentSetCLK(clock, &a, &b); + pcmciaWriteReg(pcmciac, 0x43c8, a); + pcmciaWriteReg(pcmciac, 0x43c9, b); + } else { + int num, den; + unsigned char tmp; + int clock = mode.Clock; + if (pScreenPriv->screen->fb[0].bitsPerPixel == 16) + clock *= 2; + + CirrusFindClock(clock, MAX_VCO, &num, &den); + + tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x0d); + pcmciaWriteIndex(pcmciac, 0x3c4, 0x0d, (tmp & 0x80) | num); + tmp = pcmciaReadIndex(pcmciac, 0x3c4, 0x1d); + pcmciaWriteIndex(pcmciac, 0x3c4, 0x1d, (tmp & 0xc0) | den); + } + pcmciaWriteReg(pcmciac, 0x3c2, MiscOutReg | 0x08); + +#if 0 /* for debugging */ + for (i=1;i<0x3f;i++) + ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3c4, i)); + + ErrorF("\n"); + + for (i=0;i<0x3f;i++) + ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3ce, i)); + + ErrorF("\n"); + + for (i=0;i<0x3f;i++) + ErrorF("0x%x, ",pcmciaReadIndex(pcmciac, 0x3d4, i)); +#endif + + return TRUE; +} + +void +pcmciaDisable (ScreenPtr pScreen) +{ +} + +const CARD8 tridentDPMSModes[4] = { + 0x00, /* KD_DPMS_NORMAL */ + 0x01, /* KD_DPMS_STANDBY */ + 0x02, /* KD_DPMS_SUSPEND */ + 0x03, /* KD_DPMS_POWERDOWN */ +}; + +Bool +pcmciaDPMS (ScreenPtr pScreen, int mode) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + + if (pcmciac->HP) { + pcmciaWriteIndex (pcmciac, 0x3ce, 0x23, tridentDPMSModes[mode]); + pcmciaPause (); + } else { + /* Voyager */ + } + + return TRUE; +} + +void +pcmciaRestore (KdCardInfo *card) +{ +} + +void +pcmciaScreenFini (KdScreenInfo *screen) +{ + pcmciaScreenInfo *pcmcias = (pcmciaScreenInfo *) screen->driver; + + xfree (pcmcias); + screen->driver = 0; +} + +void +pcmciaCardFini (KdCardInfo *card) +{ + pcmciaCardInfo *pcmciac = card->driver; + + if (pcmciac->cop_base) + KdUnmapDevice ((void *) pcmciac->cop_base, PCMCIA_COP_SIZE(card)); +} + +void +pcmciaGetColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + + while (ndef--) + { + pcmciaWriteReg (pcmciac, 0x3C7, pdefs->pixel); + pdefs->red = pcmciaReadReg (pcmciac, 0x3C9) << 10; + pdefs->green = pcmciaReadReg (pcmciac, 0x3C9) << 10; + pdefs->blue = pcmciaReadReg (pcmciac, 0x3C9) << 10; + pdefs++; + } +} + +void +pcmciaPutColors (ScreenPtr pScreen, int fb, int ndef, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + pcmciaCardInfo *pcmciac = pScreenPriv->card->driver; + + while (ndef--) + { + pcmciaWriteReg (pcmciac, 0x3C8, pdefs->pixel); + pcmciaWriteReg (pcmciac, 0x3C9, pdefs->red >> 10); + pcmciaWriteReg (pcmciac, 0x3C9, pdefs->green >> 10); + pcmciaWriteReg (pcmciac, 0x3C9, pdefs->blue >> 10); + pdefs++; + } +} + + +KdCardFuncs pcmciaFuncs = { + pcmciaCardInit, /* cardinit */ + pcmciaScreenInit, /* scrinit */ + pcmciaInitScreen, /* initScreen */ + pcmciaPreserve, /* preserve */ + pcmciaEnable, /* enable */ + pcmciaDPMS, /* dpms */ + pcmciaDisable, /* disable */ + pcmciaRestore, /* restore */ + pcmciaScreenFini, /* scrfini */ + pcmciaCardFini, /* cardfini */ + + pcmciaCursorInit, /* initCursor */ + pcmciaCursorEnable, /* enableCursor */ + pcmciaCursorDisable, /* disableCursor */ + pcmciaCursorFini, /* finiCursor */ + pcmciaRecolorCursor, /* recolorCursor */ + +#if 0 /* not yet */ + pcmciaDrawInit, /* initAccel */ + pcmciaDrawEnable, /* enableAccel */ + pcmciaDrawSync, /* syncAccel */ + pcmciaDrawDisable, /* disableAccel */ + pcmciaDrawFini, /* finiAccel */ +#else + 0, + 0, + 0, + 0, + 0, +#endif + + pcmciaGetColors, /* getColors */ + pcmciaPutColors, /* putColors */ +}; diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h new file mode 100644 index 000000000..58eb58bd9 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h @@ -0,0 +1,264 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmcia.h,v 1.2 2001/06/20 21:53:31 alanh Exp $ */ + +#ifndef _PCMCIA_H_ +#define _PCMCIA_H_ + +#include <fbdev.h> + +/* + * offset from ioport beginning + */ + +#define PCMCIA_COP_BASE(c) 0x20000000 +#define PCMCIA_COP_SIZE(c) 0x10000 +#define TRIDENT_COP_OFF(c) 0x2100 + +typedef volatile CARD8 VOL8; +typedef volatile CARD16 VOL16; +typedef volatile CARD32 VOL32; + +typedef struct _cop { + VOL32 src_start_xy; /* 0x00 */ + VOL32 src_end_xy; /* 0x04 */ + VOL32 dst_start_xy; /* 0x08 */ + VOL32 dst_end_xy; /* 0x0c */ + VOL32 alpha; /* 0x10 */ + CARD8 pad14[0xc]; /* 0x14 */ + VOL32 multi; /* 0x20 */ + +#define COP_MULTI_CLIP_TOP_LEFT 0x10000000 +#define COP_MULTI_DEPTH 0x40000000 +#define COP_MULTI_COLOR_KEY 0x70000000 +#define COP_MULTI_STYLE 0x50000000 +#define COP_MULTI_PATTERN 0x80000000 +#define COP_MULTI_ROP 0x90000000 +#define COP_MULTI_STRIDE 0x60000000 +#define COP_MULTI_Z 0xa0000000 +#define COP_MULTI_ALPHA 0xb0000000 +#define COP_MULTI_TEXTURE 0xd0000000 +#define COP_MULTI_TEXTURE_BOUND 0xe0000000 +#define COP_MULTI_TEXTURE_ADVANCED 0x20000000 +#define COP_MULTI_MASK 0xf0000000 + +#define COP_DEPTH_8 0x00000000 +#define COP_DEPTH_16 0x00000001 +#define COP_DEPTH_24_32 0x00000002 +#define COP_DEPTH_15 0x00000005 +#define COP_DEPTH_DITHER_DISABLE 0x00000008 + + +#define COP_ALPHA_SRC_BLEND_0 0x00000000 +#define COP_ALPHA_SRC_BLEND_1 0x00000001 +#define COP_ALPHA_SRC_BLEND_SRC_C 0x00000002 +#define COP_ALPHA_SRC_BLEND_1_SRC_C 0x00000003 +#define COP_ALPHA_SRC_BLEND_SRC_A 0x00000004 +#define COP_ALPHA_SRC_BLEND_1_SRC_A 0x00000005 +#define COP_ALPHA_SRC_BLEND_DST_A 0x00000006 +#define COP_ALPHA_SRC_BLEND_1_DST_A 0x00000007 +#define COP_ALPHA_SRC_BLEND_DST_C 0x00000008 +#define COP_ALPHA_SRC_BLEND_1_DST_C 0x00000009 +#define COP_ALPHA_SRC_BLEND_SAT 0x0000000A +#define COP_ALPHA_SRC_BLEND_BG 0x0000000B + +#define COP_ALPHA_DST_BLEND_0 0x00000000 +#define COP_ALPHA_DST_BLEND_1 0x00000010 +#define COP_ALPHA_DST_BLEND_SRC_C 0x00000020 +#define COP_ALPHA_DST_BLEND_1_SRC_C 0x00000030 +#define COP_ALPHA_DST_BLEND_SRC_A 0x00000040 +#define COP_ALPHA_DST_BLEND_1_SRC_A 0x00000050 +#define COP_ALPHA_DST_BLEND_DST_A 0x00000060 +#define COP_ALPHA_DST_BLEND_1_DST_A 0x00000070 +#define COP_ALPHA_DST_BLEND_DST_C 0x00000080 +#define COP_ALPHA_DST_BLEND_1_DST_C 0x00000090 +#define COP_ALPHA_DST_BLEND_OTHER 0x000000A0 + +#define COP_ALPHA_RESULT_ALPHA 0x00100000 +#define COP_ALPHA_DEST_ALPHA 0x00200000 +#define COP_ALPHA_SOURCE_ALPHA 0x00400000 +#define COP_ALPHA_WRITE_ENABLE 0x00800000 +#define COP_ALPHA_TEST_ENABLE 0x01000000 +#define COP_ALPHA_BLEND_ENABLE 0x02000000 +#define COP_ALPHA_DEST_VALUE 0x04000000 +#define COP_ALPHA_SOURCE_VALUE 0x08000000 + + VOL32 command; /* 0x24 */ +#define COP_OP_NULL 0x00000000 +#define COP_OP_LINE 0x20000000 +#define COP_OP_BLT 0x80000000 +#define COP_OP_TEXT 0x90000000 +#define COP_OP_POLY 0xb0000000 +#define COP_OP_POLY2 0xe0000000 +#define COP_SCL_EXPAND 0x00800000 +#define COP_SCL_OPAQUE 0x00400000 +#define COP_SCL_REVERSE 0x00200000 +#define COP_SCL_MONO_OFF 0x001c0000 +#define COP_LIT_TEXTURE 0x00004000 +#define COP_BILINEAR 0x00002000 +#define COP_OP_ZBUF 0x00000800 +#define COP_OP_ROP 0x00000400 +#define COP_OP_FG 0x00000200 +#define COP_OP_FB 0x00000080 +#define COP_X_REVERSE 0x00000004 +#define COP_CLIP 0x00000001 + VOL32 texture_format; /* 0x28 */ + CARD8 pad2c[0x4]; /* 0x2c */ + + VOL32 clip_bottom_right; /* 0x30 */ + VOL32 dataIII; /* 0x34 */ + VOL32 dataIV; /* 0x38 */ + CARD8 pad3c[0x8]; /* 0x3c */ + + VOL32 fg; /* 0x44 */ + VOL32 bg; /* 0x48 */ + CARD8 pad4c[0x4]; /* 0x4c */ + + VOL32 pattern_fg; /* 0x50 */ + VOL32 pattern_bg; /* 0x54 */ + CARD8 pad58[0xc]; /* 0x58 */ + + VOL32 status; /* 0x64 */ +#define COP_STATUS_BE_BUSY 0x80000000 +#define COP_STATUS_DPE_BUSY 0x20000000 +#define COP_STATUS_MI_BUSY 0x10000000 +#define COP_STATUS_FIFO_BUSY 0x08000000 +#define COP_STATUS_WB_BUSY 0x00800000 +#define COP_STATUS_Z_FAILED 0x00400000 +#define COP_STATUS_EFFECTIVE 0x00200000 +#define COP_STATUS_LEFT_VIEW 0x00080000 + + CARD8 pad68[0x4]; /* 0x68 */ + + VOL32 src_offset; /* 0x6c */ + VOL32 z_offset; /* 0x70 */ + CARD8 pad74[0x4]; /* 0x74 */ + + VOL32 display_offset; /* 0x78 */ + VOL32 dst_offset; /* 0x7c */ + CARD8 pad80[0x34]; /* 0x80 */ + + VOL32 semaphore; /* 0xb4 */ +} Cop; + +#define TRI_XY(x,y) ((y) << 16 | (x)) + +typedef struct _pcmciaCardInfo { + CARD8 *fb; + Bool HP; + CARD8 *cop_base; + Cop *cop; + CARD32 *window; + CARD32 cop_depth; + CARD32 cop_stride; +} pcmciaCardInfo; + +#define getpcmciaCardInfo(kd) ((pcmciaCardInfo *) ((kd)->card->driver)) +#define pcmciaCardInfo(kd) pcmciaCardInfo *pcmciac = getpcmciaCardInfo(kd) + +typedef struct _pcmciaCursor { + int width, height; + int xhot, yhot; + Bool has_cursor; + CursorPtr pCursor; + Pixel source, mask; +} pcmciaCursor; + +#define PCMCIA_CURSOR_WIDTH 64 +#define PCMCIA_CURSOR_HEIGHT 64 + +typedef struct _pcmciaScreenInfo { + int Mode; + CARD8 *cursor_base; + CARD8 *screen; + CARD8 *off_screen; + int off_screen_size; + int rotation; + LayerPtr pLayer; + pcmciaCursor cursor; +} pcmciaScreenInfo; + +#define getpcmciaScreenInfo(kd) ((pcmciaScreenInfo *) ((kd)->screen->driver)) +#define pcmciaScreenInfo(kd) pcmciaScreenInfo *pcmcias = getpcmciaScreenInfo(kd) + +Bool +pcmciaDrawInit (ScreenPtr pScreen); + +void +pcmciaDrawEnable (ScreenPtr pScreen); + +void +pcmciaDrawSync (ScreenPtr pScreen); + +void +pcmciaDrawDisable (ScreenPtr pScreen); + +void +pcmciaDrawFini (ScreenPtr pScreen); + +CARD8 +pcmciaReadIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index); + +void +pcmciaWriteIndex (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 index, CARD8 value); + +void +pcmciaWriteReg (pcmciaCardInfo *pcmciac, CARD16 port, CARD8 value); + +Bool +pcmciaCursorInit (ScreenPtr pScreen); + +void +pcmciaCursorEnable (ScreenPtr pScreen); + +void +pcmciaCursorDisable (ScreenPtr pScreen); + +void +pcmciaCursorFini (ScreenPtr pScreen); + +void +pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef); + +typedef struct _pcmciaDisplayModeRec { + int Width; + int Height; + int Refresh; + int Clock; /* pixel clock freq */ + int HDisplay; /* horizontal timing */ + int HSyncStart; + int HSyncEnd; + int HTotal; + int HSkew; + int VDisplay; /* vertical timing */ + int VSyncStart; + int VSyncEnd; + int VTotal; + int VScan; + int Flags; +} pcmciaDisplayModeRec, *pcmciaDisplayModePtr; + +extern KdCardFuncs pcmciaFuncs; + +#endif /* _PCMCIA_H_ */ diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c new file mode 100644 index 000000000..78d50fb75 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c @@ -0,0 +1,449 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciacurs.c,v 1.1 2001/05/23 08:56:09 alanh Exp $ */ + +#include "pcmcia.h" +#include "cursorstr.h" + +#define SetupCursor(s) KdScreenPriv(s); \ + pcmciaCardInfo(pScreenPriv); \ + pcmciaScreenInfo(pScreenPriv); \ + pcmciaCursor *pCurPriv = &pcmcias->cursor + +static void +_pcmciaMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CARD8 xlow, xhigh, ylow, yhigh; + CARD8 xoff, yoff; + + x -= pCurPriv->xhot; + xoff = 0; + if (x < 0) + { + xoff = -x; + x = 0; + } + y -= pCurPriv->yhot; + yoff = 0; + if (y < 0) + { + yoff = -y; + y = 0; + } + + /* This is the recommended order to move the cursor */ + if (pcmciac->HP) { + xlow = (CARD8) x; + xhigh = (CARD8) (x >> 8); + ylow = (CARD8) y; + yhigh = (CARD8) (y >> 8); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x40, xlow); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x41, xhigh); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x42, ylow); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x43, yhigh); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x46, xoff); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x47, yoff); + } else { + x >>= 3; + y >>= 3; + xlow = (CARD8) x; + xhigh = (CARD8) (x >> 8); + ylow = (CARD8) y; + yhigh = (CARD8) (y >> 8); + /* Don't be alarmed, yes the upper 3bits of the index are correct */ + pcmciaWriteIndex (pcmciac, 0x3c4, 0x10 | xhigh << 5, xlow); + pcmciaWriteIndex (pcmciac, 0x3c4, 0x11 | yhigh << 5, ylow); + } +} + +static void +pcmciaMoveCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor (pScreen); + + if (!pCurPriv->has_cursor) + return; + + if (!pScreenPriv->enabled) + return; + + _pcmciaMoveCursor (pScreen, x, y); +} + +static void +pcmciaAllocCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + + KdAllocateCursorPixels (pScreen, 0, pCursor, + &pCurPriv->source, &pCurPriv->mask); + switch (pScreenPriv->screen->fb[0].bitsPerPixel) { + case 4: + pCurPriv->source |= pCurPriv->source << 4; + pCurPriv->mask |= pCurPriv->mask << 4; + case 8: + pCurPriv->source |= pCurPriv->source << 8; + pCurPriv->mask |= pCurPriv->mask << 8; + case 16: + pCurPriv->source |= pCurPriv->source << 16; + pCurPriv->mask |= pCurPriv->mask << 16; + } +} + +static void +pcmciaSetCursorColors (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CARD32 fg, bg; + + fg = pCurPriv->source; + bg = pCurPriv->mask; + + if (pcmciac->HP) { + /* + * This trident chip uses the palette for it's cursor colors - ouch! + * We enforce it to always stay the black/white colors as we don't + * want it to muck with the overscan color. Tough. Use softCursor + * if you want to change cursor colors. + */ + pcmciaWriteReg (pcmciac, 0x3c8, 0xff); /* DAC 0 */ + pcmciaWriteReg (pcmciac, 0x3c9, 0x00); + pcmciaWriteReg (pcmciac, 0x3c9, 0x00); + pcmciaWriteReg (pcmciac, 0x3c9, 0x00); + pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 255 */ + pcmciaWriteReg (pcmciac, 0x3c9, 0x3f); + pcmciaWriteReg (pcmciac, 0x3c9, 0x3f); + pcmciaWriteReg (pcmciac, 0x3c9, 0x3f); + } else { + CARD8 temp; + temp = pcmciaReadIndex(pcmciac, 0x3c4, 0x12); + pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, (temp & 0xFE) | 0x02); + + pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 256 */ + pcmciaWriteReg (pcmciac, 0x3c9, fg); + pcmciaWriteReg (pcmciac, 0x3c9, fg >> 8); + pcmciaWriteReg (pcmciac, 0x3c9, fg >> 16); + pcmciaWriteReg (pcmciac, 0x3c8, 0x00); /* DAC 257 */ + pcmciaWriteReg (pcmciac, 0x3c9, bg); + pcmciaWriteReg (pcmciac, 0x3c9, bg >> 8); + pcmciaWriteReg (pcmciac, 0x3c9, bg >> 16); + + pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, temp); + } +} + +void +pcmciaRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef) +{ + SetupCursor (pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + xColorItem sourceColor, maskColor; + + if (!pCurPriv->has_cursor || !pCursor) + return; + + if (!pScreenPriv->enabled) + return; + + if (pdef) + { + while (ndef) + { + if (pdef->pixel == pCurPriv->source || + pdef->pixel == pCurPriv->mask) + break; + ndef--; + } + if (!ndef) + return; + } + pcmciaAllocCursorColors (pScreen); + pcmciaSetCursorColors (pScreen); +} + +#define InvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +static void +pcmciaLoadCursor (ScreenPtr pScreen, int x, int y) +{ + SetupCursor(pScreen); + CursorPtr pCursor = pCurPriv->pCursor; + CursorBitsPtr bits = pCursor->bits; + int w, h; + CARD8 *ram; + CARD32 *msk, *mskLine, *src, *srcLine; + int i, j; + int cursor_address; + int lwsrc; + unsigned char ramdac_control_; + CARD32 offset; + + /* + * Allocate new colors + */ + pcmciaAllocCursorColors (pScreen); + + pCurPriv->pCursor = pCursor; + pCurPriv->xhot = pCursor->bits->xhot; + pCurPriv->yhot = pCursor->bits->yhot; + + /* + * Stick new image into cursor memory + */ + if (pcmciac->HP) { + ram = (CARD8 *) pcmcias->cursor_base; + } else { + /* The last bank */ + ram = (CARD8 *) pcmciac->fb; + pcmciaWriteIndex (pcmciac, 0x3ce, 0x09, 0x7f); + pcmciaWriteIndex (pcmciac, 0x3ce, 0x0A, 0x7f); + } + + mskLine = (CARD32 *) bits->mask; + srcLine = (CARD32 *) bits->source; + + h = bits->height; + if (h > PCMCIA_CURSOR_HEIGHT) + h = PCMCIA_CURSOR_HEIGHT; + + lwsrc = BitmapBytePad(bits->width) / 4; + + for (i = 0; i < PCMCIA_CURSOR_HEIGHT; i++) { + msk = mskLine; + src = srcLine; + mskLine += lwsrc; + srcLine += lwsrc; + for (j = 0; j < PCMCIA_CURSOR_WIDTH / 32; j++) { + + CARD32 m, s; + + if (i < h && j < lwsrc) + { + m = *msk++; + s = *src++; + InvertBits32(m); + InvertBits32(s); + } + else + { + m = 0; + s = 0; + } + + /* Do 8bit access */ + *ram++ = (m & 0xff); + *ram++ = (m & 0xff00) >> 8; + *ram++ = (m & 0xff0000) >> 16; + *ram++ = (m & 0xff000000) >> 24; + *ram++ = (s & 0xff); + *ram++ = (s & 0xff00) >> 8; + *ram++ = (s & 0xff0000) >> 16; + *ram++ = (s & 0xff000000) >> 24; + } + } + + /* Set address for cursor bits */ + if (pcmciac->HP) { + offset = pcmcias->cursor_base - (CARD8 *) pcmcias->screen; + offset >>= 10; + pcmciaWriteIndex (pcmciac, 0x3d4, 0x44, (CARD8) (offset & 0xff)); + pcmciaWriteIndex (pcmciac, 0x3d4, 0x45, (CARD8) (offset >> 8)); + } else { + pcmciaWriteIndex (pcmciac, 0x3c4, 0x13, 15); /* ?? */ + } + + /* Set new color */ + pcmciaSetCursorColors (pScreen); + + /* Enable the cursor */ + if (pcmciac->HP) + pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0xc1); + else + pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0x05); + + /* Move to new position */ + pcmciaMoveCursor (pScreen, x, y); +} + +static void +pcmciaUnloadCursor (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + /* Disable cursor */ + if (pcmciac->HP) + pcmciaWriteIndex (pcmciac, 0x3d4, 0x50, 0); + else + pcmciaWriteIndex (pcmciac, 0x3c4, 0x12, 0); +} + +static Bool +pcmciaRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + SetupCursor(pScreen); + + if (!pScreenPriv->enabled) + return TRUE; + + /* miRecolorCursor does this */ + if (pCurPriv->pCursor == pCursor) + { + if (pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + pcmciaLoadCursor (pScreen, x, y); + } + } + return TRUE; +} + +static Bool +pcmciaUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor) +{ + return TRUE; +} + +static void +pcmciaSetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +{ + SetupCursor(pScreen); + + pCurPriv->pCursor = pCursor; + + if (!pScreenPriv->enabled) + return; + + if (pCursor) + pcmciaLoadCursor (pScreen, x, y); + else + pcmciaUnloadCursor (pScreen); +} + +miPointerSpriteFuncRec pcmciaPointerSpriteFuncs = { + pcmciaRealizeCursor, + pcmciaUnrealizeCursor, + pcmciaSetCursor, + pcmciaMoveCursor, +}; + +static void +pcmciaQueryBestSize (int class, + unsigned short *pwidth, unsigned short *pheight, + ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + switch (class) + { + case CursorShape: + if (*pwidth > pCurPriv->width) + *pwidth = pCurPriv->width; + if (*pheight > pCurPriv->height) + *pheight = pCurPriv->height; + if (*pwidth > pScreen->width) + *pwidth = pScreen->width; + if (*pheight > pScreen->height) + *pheight = pScreen->height; + break; + default: + fbQueryBestSize (class, pwidth, pheight, pScreen); + break; + } +} + +Bool +pcmciaCursorInit (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!pcmcias->cursor_base) + { + pCurPriv->has_cursor = FALSE; + return FALSE; + } + + pCurPriv->width = PCMCIA_CURSOR_WIDTH; + pCurPriv->height= PCMCIA_CURSOR_HEIGHT; + pScreen->QueryBestSize = pcmciaQueryBestSize; + miPointerInitialize (pScreen, + &pcmciaPointerSpriteFuncs, + &kdPointerScreenFuncs, + FALSE); + pCurPriv->has_cursor = TRUE; + pCurPriv->pCursor = NULL; + return TRUE; +} + +void +pcmciaCursorEnable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + int x, y; + + miPointerPosition (&x, &y); + pcmciaLoadCursor (pScreen, x, y); + } + else + pcmciaUnloadCursor (pScreen); + } +} + +void +pcmciaCursorDisable (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + if (!pScreenPriv->enabled) + return; + + if (pCurPriv->has_cursor) + { + if (pCurPriv->pCursor) + { + pcmciaUnloadCursor (pScreen); + } + } +} + +void +pcmciaCursorFini (ScreenPtr pScreen) +{ + SetupCursor (pScreen); + + pCurPriv->pCursor = NULL; +} diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c new file mode 100644 index 000000000..eb6e64873 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c @@ -0,0 +1,197 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciashadow.c,v 1.2 2001/05/29 17:47:55 keithp Exp $ */ + +#include "X.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "font.h" +#include "dixfontstr.h" +#include "fontstruct.h" +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" + +void +tridentUpdatePacked (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); + FbBits *shaBase, *shaLine, *sha; + 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, *win; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + scrLine = (x >> FB_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + x &= FB_MASK; + w = (w + x + FB_MASK) >> FB_SHIFT; + + while (h--) + { + winSize = 0; + scrBase = 0; + width = w; + scr = scrLine; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof (FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (FbBits); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + { + CARD16 *sha16 = (CARD16*)sha; + CARD16 *win16 = (CARD16*)win; + while (i--) + { + *win16++ = *sha16++; + *win16++ = *sha16++; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} + +void +cirrusUpdatePacked (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); + FbBits *shaBase, *shaLine, *sha; + 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, *win; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + scrLine = (x >> FB_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + x &= FB_MASK; + w = (w + x + FB_MASK) >> FB_SHIFT; + + while (h--) + { + winSize = 0; + scrBase = 0; + width = w; + scr = scrLine; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof (FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (FbBits); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + { + CARD8 *sha8 = (CARD8*)sha; + CARD8 *win8 = (CARD8*)win; + while (i--) + { + *win8++ = *sha8++; + *win8++ = *sha8++; + *win8++ = *sha8++; + *win8++ = *sha8++; + } + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} diff --git a/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c new file mode 100644 index 000000000..be5498ec9 --- /dev/null +++ b/xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c @@ -0,0 +1,54 @@ +/* + * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales, UK. + * + * 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 Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk> + */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/pcmcia/pcmciastub.c,v 1.1 2001/05/23 08:56:09 alanh Exp $ */ + +#include "pcmcia.h" + +void +InitCard (char *name) +{ + KdCardAttr attr; + + KdCardInfoAdd (&pcmciaFuncs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); +} + +extern pcmciaDisplayModeRec pcmciaDefaultModes[]; + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + return KdProcessArgument (argc, argv, i); +} diff --git a/xc/programs/Xserver/hw/kdrive/savage/s3draw.c b/xc/programs/Xserver/hw/kdrive/savage/s3draw.c index e4205ba40..1cc9956b8 100644 --- a/xc/programs/Xserver/hw/kdrive/savage/s3draw.c +++ b/xc/programs/Xserver/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.5 2000/08/09 17:52:41 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.6 2001/05/29 04:54:11 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/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c b/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c index 1863b9011..439134760 100644 --- a/xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c +++ b/xc/programs/Xserver/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.5 2000/08/09 17:52:44 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/sis530/sisdraw.c,v 1.6 2001/05/29 04:54:12 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/xc/programs/Xserver/hw/kdrive/trident/trident.c b/xc/programs/Xserver/hw/kdrive/trident/trident.c index c2d3eae00..efe17001f 100644 --- a/xc/programs/Xserver/hw/kdrive/trident/trident.c +++ b/xc/programs/Xserver/hw/kdrive/trident/trident.c @@ -19,12 +19,10 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.16 2001/03/21 16:43:16 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.18 2001/06/04 09:45:42 keithp Exp $ */ #include "trident.h" -#define extern -#include <asm/io.h> -#undef extern +#include <sys/io.h> #undef TRI_DEBUG @@ -157,6 +155,14 @@ tridentInitScreen (ScreenPtr pScreen) #endif } +Bool +tridentFinishInitScreen (ScreenPtr pScreen) +{ +#ifdef VESA + return vesaFinishInitScreen (pScreen); +#endif +} + CARD8 tridentReadIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index) { @@ -600,4 +606,5 @@ KdCardFuncs tridentFuncs = { fbdevGetColors, /* getColors */ fbdevPutColors, /* putColors */ #endif + tridentFinishInitScreen /* finishInitScreen */ }; diff --git a/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c index 09a7d817d..db71a7677 100644 --- a/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c +++ b/xc/programs/Xserver/hw/kdrive/trident/tridentdraw.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/trident/tridentdraw.c,v 1.7 2000/11/29 08:42:25 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentdraw.c,v 1.10 2001/06/03 18:48:19 keithp Exp $ */ #include "trident.h" #include "tridentdraw.h" @@ -70,620 +70,101 @@ 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++; - } - KdMarkSync(pDstDrawable->pScreen); -} - -RegionPtr -tridentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - KdScreenPriv(pDstDrawable->pScreen); - FbBits depthMask; - - depthMask = FbFullMask (pDstDrawable->depth); - if ((pGC->planemask & 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(pDrawable->pScreen); + tridentCardInfo(pScreenPriv); + cop = tridentc->cop; + + tridentFillPix(pDrawable->bitsPerPixel,fg); + _tridentInit(cop,tridentc); + _tridentSetSolidRect(cop,fg,alu,cmd); 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) +tridentSolid (int x1, int y1, int x2, int y2) { - 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); + _tridentRect (cop, x1, y1, x2 - 1, y2 - 1, cmd); } -#define NUM_STACK_RECTS 1024 - void -tridentPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrectFill, xRectangle *prectInit) +tridentDoneSolid (void) { - 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) +Bool +tridentPrepareCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + int dx, + int dy, + int alu, + Pixel pm) { - SetupTrident (pDrawable->pScreen); - BoxPtr pbox; - int nbox; - int partX1, partX2, partY1, partY2; - CARD32 cmd; - - _tridentInit (cop, tridentc); - _tridentSetSolidRect (cop, fg, GXcopy, cmd); + FbBits depthMask; - for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); - nbox--; - pbox++) + if ((pm & depthMask) == depthMask) { - 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); + 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 (dx < 0 || dy < 0) + cmd |= COP_X_REVERSE; + return TRUE; } - KdMarkSync(pDrawable->pScreen); + else + return FALSE; } void -tridentImageGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppciInit, - pointer pglyphBase) +tridentCopy (int srcX, + int srcY, + int dstX, + int dstY, + int w, + int h) { - 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) + if (cmd & COP_X_REVERSE) { - opaque = TRUE; + 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 { - 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; + 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; } -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) +tridentDoneCopy (void) { - if (!fbCreateGC (pGC)) - return FALSE; - - if (pGC->depth != 1) - pGC->funcs = &tridentGCFuncs; - - return TRUE; } void @@ -710,10 +191,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 +250,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 +323,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 +397,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; - - 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; +KaaScreenPrivRec tridentKaa = { + tridentPrepareSolid, + tridentSolid, + tridentDoneSolid, - 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 +414,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/xc/programs/Xserver/hw/kdrive/vesa/vbe.c b/xc/programs/Xserver/hw/kdrive/vesa/vbe.c index c955d924d..f9c05d59b 100644 --- a/xc/programs/Xserver/hw/kdrive/vesa/vbe.c +++ b/xc/programs/Xserver/hw/kdrive/vesa/vbe.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/vbe.c,v 1.8 2000/11/29 08:42:25 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.c,v 1.9 2001/05/29 04:54:12 keithp Exp $ */ #include "vesa.h" @@ -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/xc/programs/Xserver/hw/kdrive/vesa/vbe.h b/xc/programs/Xserver/hw/kdrive/vesa/vbe.h index 0633e4084..f52fa673e 100644 --- a/xc/programs/Xserver/hw/kdrive/vesa/vbe.h +++ b/xc/programs/Xserver/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: xc/programs/Xserver/hw/kdrive/vesa/vbe.h,v 1.5 2000/10/20 00:19:50 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vbe.h,v 1.6 2001/05/29 04:54:12 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/xc/programs/Xserver/hw/kdrive/vesa/vesa.c b/xc/programs/Xserver/hw/kdrive/vesa/vesa.c index 90f4215a1..59c4ceeab 100644 --- a/xc/programs/Xserver/hw/kdrive/vesa/vesa.c +++ b/xc/programs/Xserver/hw/kdrive/vesa/vesa.c @@ -19,9 +19,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.9 2000/11/29 08:42:25 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesa.c,v 1.16 2001/07/24 19:06:04 keithp Exp $ */ #include "vesa.h" +#ifdef RANDR +#include <randrstr.h> +#endif int vesa_video_mode = 0; Bool vesa_force_mode = FALSE; @@ -29,14 +32,12 @@ Bool vesa_swap_rgb = FALSE; Bool vesa_shadow = FALSE; Bool vesa_linear_fb = TRUE; Bool vesa_restore = FALSE; -Bool vesa_rotate = FALSE; Bool vesa_verbose = FALSE; #define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver) -#define ScreenRotated(scr) (VesaPriv(scr)->rotate) -#define vesaWidth(scr,vmib) (ScreenRotated(scr) ? vmib->YResolution : vmib->XResolution) -#define vesaHeight(scr,vmib) (ScreenRotated(scr) ? vmib->XResolution : vmib->YResolution) +#define vesaWidth(scr,vmib) ((vmib)->XResolution) +#define vesaHeight(scr,vmib) ((vmib)->YResolution) static Bool vesaModeSupportable (VesaModePtr mode, Bool complain) @@ -368,13 +369,8 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) VesaCardPrivPtr priv = screen->card->driver; VesaModePtr mode; Pixel allbits; - int depth; - int bpp, fbbpp; screen->driver = pscr; - pscr->rotate = FALSE; - if (screen->width < screen->height) - pscr->rotate = TRUE; if (!screen->width || !screen->height) { @@ -388,70 +384,40 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) ErrorF ("Mode requested %dx%dx%d\n", screen->width, screen->height, screen->fb[0].depth); - pscr->mode = vesaSelectMode (screen); + mode = vesaSelectMode (screen); - if (!pscr->mode) + if (!mode) { if (vesa_verbose) ErrorF ("No selectable mode\n"); return FALSE; } + pscr->mode = *mode; if (vesa_verbose) { ErrorF ("\t"); - vesaReportMode (pscr->mode); + vesaReportMode (&pscr->mode); } + pscr->rotate = screen->rotation; pscr->shadow = vesa_shadow; pscr->origDepth = screen->fb[0].depth; - if (vesa_linear_fb) - pscr->mapping = VESA_LINEAR; - else - pscr->mapping = VESA_WINDOWED; - - mode = pscr->mode; + pscr->layerKind = LAYER_FB; - depth = vesaDepth (mode); - bpp = mode->BitsPerPixel; - - if (bpp > 24) - bpp = 32; - else if (bpp > 16) - bpp = 24; - else if (bpp > 8) - bpp = 16; - else if (bpp > 4) - bpp = 8; - else if (bpp > 1) - bpp = 4; - else - bpp = 1; - fbbpp = bpp; - - switch (mode->MemoryModel) { + /* + * Compute visual support for the selected depth + */ + switch (pscr->mode.MemoryModel) { case MEMORY_DIRECT: /* TrueColor or DirectColor */ screen->fb[0].visuals = (1 << TrueColor); screen->fb[0].redMask = - FbStipMask(mode->RedFieldPosition, mode->RedMaskSize); + FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize); screen->fb[0].greenMask = - FbStipMask(mode->GreenFieldPosition, mode->GreenMaskSize); + FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize); screen->fb[0].blueMask = - FbStipMask(mode->BlueFieldPosition, mode->BlueMaskSize); - allbits = - screen->fb[0].redMask | - screen->fb[0].greenMask | - screen->fb[0].blueMask; - depth = 32; - while (depth && !(allbits & (1 << (depth - 1)))) - depth--; - if (vesa_verbose) - ErrorF ("\tTrue Color bpp %d depth %d red 0x%x green 0x%x blue 0x%x\n", - bpp, depth, - screen->fb[0].redMask, - screen->fb[0].greenMask, - screen->fb[0].blueMask); + FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize); break; case MEMORY_PSEUDO: /* PseudoColor */ @@ -464,98 +430,25 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) screen->fb[0].blueMask = 0x00; screen->fb[0].greenMask = 0x00; screen->fb[0].redMask = 0x00; - if (vesa_verbose) - ErrorF ("\tPseudo Color bpp %d depth %d\n", - bpp, depth); break; case MEMORY_PLANAR: /* 4 plane planar */ - if (mode->ModeAttributes & MODE_COLOUR) + if (pscr->mode.ModeAttributes & MODE_COLOUR) screen->fb[0].visuals = (1 << StaticColor); else screen->fb[0].visuals = (1 << StaticGray); screen->fb[0].blueMask = 0x00; screen->fb[0].greenMask = 0x00; screen->fb[0].redMask = 0x00; - if (bpp == 4) - { - bpp = screen->fb[0].bitsPerPixel; - if (bpp != 8) - bpp = 4; - depth = bpp; - } - if (bpp == 1) - { - pscr->mapping = VESA_MONO; - if (vesa_verbose) - ErrorF ("\tMonochrome\n"); - } - else - { - pscr->mapping = VESA_PLANAR; - if (vesa_verbose) - ErrorF ("\tStatic color bpp %d depth %d\n", - bpp, depth); - } - pscr->rotate = FALSE; break; default: ErrorF("Unsupported VESA MemoryModel 0x%02X\n", - mode->MemoryModel); + pscr->mode.MemoryModel); return FALSE; } - - screen->width = vesaWidth(screen, mode); - screen->height = vesaHeight(screen, mode); - screen->fb[0].depth = depth; - screen->fb[0].bitsPerPixel = bpp; - screen->fb[0].byteStride = mode->BytesPerScanLine; - screen->fb[0].pixelStride = ((mode->BytesPerScanLine * 8) / fbbpp); - - if (pscr->mapping == VESA_LINEAR && !(mode->ModeAttributes & MODE_LINEAR)) - pscr->mapping = VESA_WINDOWED; - - if (pscr->rotate) - pscr->shadow = TRUE; - - switch (pscr->mapping) { - case VESA_MONO: - pscr->shadow = TRUE; - /* fall through */ - case VESA_LINEAR: - if (mode->vbe) - pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, - pscr->mode->mode, - &pscr->fb_size); - else - pscr->fb = VgaMapFramebuffer (priv->vi, - pscr->mode->mode, - &pscr->fb_size); - break; - case VESA_WINDOWED: - pscr->fb = NULL; - pscr->shadow = TRUE; - break; - case VESA_PLANAR: - pscr->fb = NULL; - pscr->shadow = TRUE; - break; - } - screen->rate = 72; - screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb); - if (pscr->rotate) - screen->softCursor = TRUE; - - if (pscr->shadow) - return KdShadowScreenInit (screen); - - if (vesa_verbose) - ErrorF ("Mode selected %dx%dx%d\n", - screen->width, screen->height, screen->fb[0].depth); - - return TRUE; + return vesaMapFramebuffer (screen); } Bool @@ -588,19 +481,19 @@ vesaSetWindowPlanar(ScreenPtr pScreen, plane = offset & 3; VgaSetWritePlaneMask (priv->vi, (1 << plane)); offset = offset >> 2; - if (pscr->mode->vbe) + if (pscr->mode.vbe) { base = VbeSetWindow (priv->vi, priv->vbeInfo, - pscr->mode->BytesPerScanLine * row + offset, + pscr->mode.BytesPerScanLine * row + offset, mode, &winSize); } else { base = VgaSetWindow (priv->vi, - pscr->mode->mode, - pscr->mode->BytesPerScanLine * row + offset, + pscr->mode.mode, + pscr->mode.BytesPerScanLine * row + offset, mode, &winSize); } @@ -619,8 +512,8 @@ vesaSetWindowLinear (ScreenPtr pScreen, VesaCardPrivPtr priv = pScreenPriv->card->driver; VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; - *size = pscr->mode->BytesPerScanLine; - return (CARD8 *) pscr->fb + row * pscr->mode->BytesPerScanLine + offset; + *size = pscr->mode.BytesPerScanLine; + return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset; } void * @@ -636,19 +529,19 @@ vesaSetWindowWindowed (ScreenPtr pScreen, int winSize; void *base; - if (pscr->mode->vbe) + if (pscr->mode.vbe) { base = VbeSetWindow (priv->vi, priv->vbeInfo, - pscr->mode->BytesPerScanLine * row + offset, + pscr->mode.BytesPerScanLine * row + offset, mode, &winSize); } else { base = VgaSetWindow (priv->vi, - pscr->mode->mode, - pscr->mode->BytesPerScanLine * row + offset, + pscr->mode.mode, + pscr->mode.BytesPerScanLine * row + offset, mode, &winSize); } @@ -661,7 +554,8 @@ vesaWindowPlanar (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -675,7 +569,8 @@ vesaWindowLinear (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -689,7 +584,8 @@ vesaWindowWindowed (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); @@ -709,7 +605,8 @@ vesaWindowCga (ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, - CARD32 *size) + CARD32 *size, + void *closure) { KdScreenPriv(pScreen); VesaCardPrivPtr priv = pScreenPriv->card->driver; @@ -718,16 +615,17 @@ vesaWindowCga (ScreenPtr pScreen, if (!pScreenPriv->enabled) return 0; - *size = pscr->mode->BytesPerScanLine; - line = ((row & 1) << 13) + (row >> 1) * pscr->mode->BytesPerScanLine; + *size = pscr->mode.BytesPerScanLine; + line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine; return (CARD8 *) pscr->fb + line + offset; } void -vesaUpdateMono (ScreenPtr pScreen, - PixmapPtr pShadow, - RegionPtr damage) +vesaUpdateMono (ScreenPtr pScreen, + shadowBufPtr pBuf) { + RegionPtr damage = &pBuf->damage; + PixmapPtr pShadow = pBuf->pPixmap; shadowScrPriv(pScreen); int nbox = REGION_NUM_RECTS (damage); BoxPtr pbox = REGION_RECTS (damage); @@ -736,6 +634,7 @@ vesaUpdateMono (ScreenPtr pScreen, FbStride shaStride; int scrBase, scrLine, scr; int shaBpp; + int shaXoff, shaYoff; /* XXX assumed to be zero */ int x, y, w, h, width; int i; FbBits *winBase, *winLine, *win; @@ -743,7 +642,7 @@ vesaUpdateMono (ScreenPtr pScreen, FbBits bits; int plane; - fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp); + fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); while (nbox--) { x = pbox->x1 * shaBpp; @@ -769,11 +668,12 @@ vesaUpdateMono (ScreenPtr pScreen, i = scrBase + winSize - scr; if (i <= 0 || scr < scrBase) { - winBase = (FbBits *) (*pScrPriv->window) (pScreen, - y, - scr * sizeof (FbBits), - SHADOW_WINDOW_WRITE, - &winSize); + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof (FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); if(!winBase) return; scrBase = scr; @@ -823,6 +723,7 @@ vesaCreateColormap16 (ColormapPtr pmap) { int i, j; + if (pmap->pVisual->ColormapEntries == 16) for (i = 0; i < pmap->pVisual->ColormapEntries; i++) { j = i & 0xf; @@ -833,24 +734,89 @@ vesaCreateColormap16 (ColormapPtr pmap) return TRUE; } +void +vesaConfigureScreen (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; -Bool -vesaInitScreen(ScreenPtr pScreen) + KdMouseMatrix m; + + if (pscr->mapping == VESA_PLANAR || pscr->mapping == VESA_MONO) + { + pscr->shadow = TRUE; + pscr->rotate = 0; + } + else switch (pscr->rotate) { + case 0: + pScreen->width = pscr->mode.XResolution; + pScreen->height = pscr->mode.YResolution; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + if (pscr->mapping == VESA_WINDOWED) + pscr->shadow = TRUE; + else + pscr->shadow = vesa_shadow; + m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0; + m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0; + break; + case 90: + pScreen->width = pscr->mode.YResolution; + pScreen->height = pscr->mode.XResolution; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + pscr->shadow = TRUE; + m.matrix[0][0] = 0; m.matrix[0][1] = -1; m.matrix[0][2] = pscr->mode.YResolution - 1; + m.matrix[1][0] = 1; m.matrix[1][1] = 0; m.matrix[1][2] = 0; + break; + case 180: + pScreen->width = pscr->mode.XResolution; + pScreen->height = pscr->mode.YResolution; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + pscr->shadow = TRUE; + m.matrix[0][0] = -1; m.matrix[0][1] = 0; m.matrix[0][2] = pscr->mode.XResolution - 1; + m.matrix[1][0] = 0; m.matrix[1][1] = -1; m.matrix[1][2] = pscr->mode.YResolution - 1; + break; + case 270: + pScreen->width = pscr->mode.YResolution; + pScreen->height = pscr->mode.XResolution; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + pscr->shadow = TRUE; + m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0; + m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = pscr->mode.XResolution - 1; + break; + } + KdSetMouseMatrix (&m); +} + +LayerPtr +vesaLayerCreate (ScreenPtr pScreen) { KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + LayerPtr pLayer; ShadowUpdateProc update; ShadowWindowProc window; - + PixmapPtr pPixmap; + int kind; + if (pscr->shadow) { + if (pscr->rotate) + update = shadowUpdateRotatePacked; + else + update = shadowUpdatePacked; switch (pscr->mapping) { case VESA_LINEAR: - update = shadowUpdatePacked; window = vesaWindowLinear; break; case VESA_WINDOWED: - update = shadowUpdatePacked; window = vesaWindowWindowed; break; case VESA_PLANAR: @@ -860,68 +826,653 @@ vesaInitScreen(ScreenPtr pScreen) else update = shadowUpdatePlanar4; window = vesaWindowPlanar; - pscr->rotate = FALSE; break; case VESA_MONO: update = vesaUpdateMono; - if (pscr->mode->mode < 8) + if (pscr->mode.mode < 8) window = vesaWindowCga; else window = vesaWindowLinear; - pscr->rotate = FALSE; break; } - if (pscr->rotate) + + kind = LAYER_SHADOW; + pPixmap = 0; + } + else + { + kind = pscr->layerKind; + pPixmap = LAYER_SCREEN_PIXMAP; + update = 0; + window = 0; + } + + if (vesa_verbose) + ErrorF ("Mode selected %dx%dx%d\n", + pScreen->width, pScreen->height, screen->fb[0].depth); + + return LayerCreate (pScreen, kind, screen->fb[0].depth, + pPixmap, update, window, pscr->rotate, 0); +} + +Bool +vesaMapFramebuffer (KdScreenInfo *screen) +{ + VesaCardPrivPtr priv = screen->card->driver; + VesaScreenPrivPtr pscr = screen->driver; + int depth, bpp, fbbpp; + Pixel allbits; + + if (vesa_linear_fb) + pscr->mapping = VESA_LINEAR; + else + pscr->mapping = VESA_WINDOWED; + + depth = vesaDepth (&pscr->mode); + bpp = pscr->mode.BitsPerPixel; + + if (bpp > 24) + bpp = 32; + else if (bpp > 16) + bpp = 24; + else if (bpp > 8) + bpp = 16; + else if (bpp > 4) + bpp = 8; + else if (bpp > 1) + bpp = 4; + else + bpp = 1; + fbbpp = bpp; + + switch (pscr->mode.MemoryModel) { + case MEMORY_DIRECT: + allbits = (screen->fb[0].redMask | + screen->fb[0].greenMask | + screen->fb[0].blueMask); + depth = 32; + while (depth && !(allbits & (1 << (depth - 1)))) + depth--; + if (vesa_verbose) + ErrorF ("\tTrue Color red 0x%x green 0x%x blue 0x%x\n", + bpp, depth, + screen->fb[0].redMask, + screen->fb[0].greenMask, + screen->fb[0].blueMask); + break; + case MEMORY_PSEUDO: + if (vesa_verbose) + ErrorF ("\tPseudo Color bpp %d depth %d\n", + bpp, depth); + break; + case MEMORY_PLANAR: + if (bpp == 4) + { + bpp = screen->fb[0].bitsPerPixel; + if (bpp != 8) + bpp = 4; + depth = bpp; + } + if (bpp == 1) + { + pscr->mapping = VESA_MONO; + if (vesa_verbose) + ErrorF ("\tMonochrome\n"); + } + else + { + pscr->mapping = VESA_PLANAR; + if (vesa_verbose) + ErrorF ("\tStatic color bpp %d depth %d\n", + bpp, depth); + } + pscr->rotate = 0; + break; + default: + return 0; + } + + switch (fbbpp) { + case 8: + case 16: + case 32: + break; + default: + pscr->rotate = 0; + } + + screen->width = pscr->mode.XResolution; + screen->height = pscr->mode.YResolution; + screen->fb[0].depth = depth; + screen->fb[0].bitsPerPixel = bpp; + screen->fb[0].byteStride = pscr->mode.BytesPerScanLine; + screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) / fbbpp); + + if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR)) + pscr->mapping = VESA_WINDOWED; + + screen->softCursor = TRUE; + + switch (pscr->mapping) { + case VESA_MONO: + case VESA_LINEAR: + if (pscr->mode.vbe) + pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, + pscr->mode.mode, + &pscr->fb_size); + else + pscr->fb = VgaMapFramebuffer (priv->vi, + pscr->mode.mode, + &pscr->fb_size); + if (!pscr->fb) + return FALSE; + break; + case VESA_WINDOWED: + pscr->fb = NULL; + break; + case VESA_PLANAR: + pscr->fb = NULL; + break; + } + screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb); + return TRUE; +} + +void +vesaUnmapFramebuffer (KdScreenInfo *screen) +{ + VesaCardPrivPtr priv = screen->card->driver; + VesaScreenPrivPtr pscr = screen->driver; + + if (pscr->fb) + { + if (pscr->mode.vbe) + VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb); + else + VgaUnmapFramebuffer (priv->vi); + pscr->fb = 0; + } +} + +#ifdef RANDR +Bool +vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + KdScreenPriv(pScreen); + VesaModePtr modes, mode; + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int nmode; + int n; + RRVisualGroupPtr pVisualGroup; + RRGroupOfVisualGroupPtr pGroupOfVisualGroup; + RRScreenSizePtr pSize; + + *rotations = RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270; + /* + * Get mode information from BIOS -- every time in case + * something changes, like an external monitor is plugged in + */ + modes = vesaGetModes (priv->vi, &nmode); + if (!modes) + return FALSE; + if (priv->modes) + xfree (priv->modes); + priv->modes = modes; + priv->nmode = nmode; + /* + * XXX Create a single set of visual sets that has all of the visuals + * for the root depth + */ + for (n = 0; n < pScreen->numDepths; n++) + if (pScreen->allowedDepths[n].numVids) + break; + if (n == pScreen->numDepths) + return FALSE; + + pVisualGroup = RRCreateVisualGroup (pScreen); + if (!pVisualGroup) + return FALSE; + + if (!RRAddDepthToVisualGroup (pScreen, + pVisualGroup, + &pScreen->allowedDepths[n])) + { + RRDestroyVisualGroup (pScreen, pVisualGroup); + return FALSE; + } + pVisualGroup = RRRegisterVisualGroup (pScreen, pVisualGroup); + if (!pVisualGroup) + return FALSE; + + pGroupOfVisualGroup = RRCreateGroupOfVisualGroup (pScreen); + + if (!RRAddVisualGroupToGroupOfVisualGroup (pScreen, + pGroupOfVisualGroup, + pVisualGroup)) + { + RRDestroyGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + /* pVisualGroup left until screen closed */ + return FALSE; + } + + pGroupOfVisualGroup = RRRegisterGroupOfVisualGroup (pScreen, pGroupOfVisualGroup); + if (!pGroupOfVisualGroup) + return FALSE; + + for (n = 0; n < nmode; n++) + { + mode = &priv->modes[n]; + if (vesaModeSupported (priv, mode, FALSE)) { - switch (pScreenPriv->screen->fb[0].bitsPerPixel) { - case 8: - update = shadowUpdateRotate8; break; - case 16: - update = shadowUpdateRotate16; break; - case 32: - update = shadowUpdateRotate32; break; + /* + * XXX limit reported modes to those matching the current + * format + */ + if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes && + mode->BitsPerPixel == pscr->mode.BitsPerPixel && + mode->MemoryModel == pscr->mode.MemoryModel && + mode->RedMaskSize == pscr->mode.RedMaskSize && + mode->RedFieldPosition == pscr->mode.RedFieldPosition && + mode->GreenMaskSize == pscr->mode.GreenMaskSize && + mode->GreenFieldPosition == pscr->mode.GreenFieldPosition && + mode->BlueMaskSize == pscr->mode.BlueMaskSize && + mode->BlueFieldPosition == pscr->mode.BlueFieldPosition) + { + int width, height, width_mm, height_mm; + if (screen->rotation == 0 || screen->rotation == 180) + { + width = mode->XResolution; + height = mode->YResolution; + width_mm = screen->width_mm; + height_mm = screen->height_mm; + } + else + { + width = mode->YResolution; + height = mode->XResolution; + width_mm = screen->height_mm; + height_mm = screen->width_mm; + } + pSize = RRRegisterSize (pScreen, + width, height, + width_mm, height_mm, + pGroupOfVisualGroup); + if (mode->XResolution == screen->width && + mode->YResolution == screen->height) + { + int rotate = pscr->rotate - screen->rotation; + int rot; + if (rotate < 0) + rotate += 360; + switch (rotate) { + case 0: rot = RR_Rotate_0; break; + case 90: rot = RR_Rotate_90; break; + case 180: rot = RR_Rotate_180; break; + case 270: rot = RR_Rotate_270; break; + } + RRSetCurrentConfig (pScreen, rot, pSize, + pVisualGroup); + } } } + } + return TRUE; +} + +int +vesaLayerAdd (WindowPtr pWin, pointer value) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + LayerPtr pLayer = (LayerPtr) value; + + if (!LayerWindowAdd (pScreen, pLayer, pWin)) + return WT_STOPWALKING; + + return WT_WALKCHILDREN; +} + +int +vesaLayerRemove (WindowPtr pWin, pointer value) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + LayerPtr pLayer = (LayerPtr) value; + + LayerWindowRemove (pScreen, pLayer, pWin); + + return WT_WALKCHILDREN; +} + +Bool +vesaRandRSetConfig (ScreenPtr pScreen, + Rotation rotation, + RRScreenSizePtr pSize, + RRVisualGroupPtr pVisualGroup) +{ + KdScreenPriv(pScreen); + VesaModePtr mode; + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int n; + Bool wasEnabled = pScreenPriv->enabled; + Bool ret = FALSE; + VesaScreenPrivRec oldscr; + int oldwidth; + int oldheight; + int oldmmwidth; + int oldmmheight; + LayerPtr pNewLayer; + int newwidth, newheight; + + if (screen->rotation == 0 || screen->rotation == 180) + { + newwidth = pSize->width; + newheight = pSize->height; + } + else + { + newwidth = pSize->height; + newheight = pSize->width; + } + for (n = 0; n < priv->nmode; n++) + { + mode = &priv->modes[n]; + if (vesaModeSupported (priv, mode, FALSE)) + { + /* + * XXX all we have to match is the size + */ + if (mode->XResolution == newwidth && + mode->YResolution == newheight && + mode->NumberOfPlanes == pscr->mode.NumberOfPlanes && + mode->BitsPerPixel == pscr->mode.BitsPerPixel && + mode->RedMaskSize == pscr->mode.RedMaskSize && + mode->RedFieldPosition == pscr->mode.RedFieldPosition && + mode->GreenMaskSize == pscr->mode.GreenMaskSize && + mode->GreenFieldPosition == pscr->mode.GreenFieldPosition && + mode->BlueMaskSize == pscr->mode.BlueMaskSize && + mode->BlueFieldPosition == pscr->mode.BlueFieldPosition) + break; + } + } + if (n == priv->nmode) + goto bail0; + + if (wasEnabled) + KdDisableScreen (pScreen); + + if (mode->mode != pscr->mode.mode) + { + ret = vesaSetMode (pScreen, mode); + if (!ret) + goto bail1; + } + + oldscr = *pscr; + + oldwidth = screen->width; + oldheight = screen->height; + oldmmwidth = pScreen->mmWidth; + oldmmheight = pScreen->mmHeight; + + /* + * Set new configuration + */ + + pscr->mode = *mode; + switch (rotation) { + case RR_Rotate_0: pscr->rotate = 0; break; + case RR_Rotate_90: pscr->rotate = 90; break; + case RR_Rotate_180: pscr->rotate = 180; break; + case RR_Rotate_270: pscr->rotate = 270; break; + } + + pscr->rotate += screen->rotation; + if (pscr->rotate >= 360) + pscr->rotate -= 360; + + /* + * Can't rotate some formats + */ + switch (screen->fb[0].bitsPerPixel) { + case 8: + case 16: + case 32: + break; + default: + if (pscr->rotate) + goto bail2; + break; + } + + vesaUnmapFramebuffer (screen); + if (!vesaMapFramebuffer (screen)) + goto bail3; + +#if 0 + /* + * XXX can't switch depths yet + */ + screen->fb[0].depth = depth; + screen->fb[0].bitsPerPixel = bpp; +#endif + screen->fb[0].byteStride = mode->BytesPerScanLine; + screen->fb[0].pixelStride = ((mode->BytesPerScanLine * 8) / screen->fb[0].bitsPerPixel); + + /* + * Compute screen geometry + */ + vesaConfigureScreen (pScreen); + + /* + * Set frame buffer mapping + */ + if (!pscr->shadow) + { + (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), + pScreen->width, + pScreen->height, + screen->fb[0].depth, + screen->fb[0].bitsPerPixel, + screen->fb[0].byteStride, + screen->fb[0].frameBuffer); + } - return KdShadowInitScreen (pScreen, update, window); + /* + * Create the layer + */ + pNewLayer = vesaLayerCreate (pScreen); + if (!pNewLayer) + goto bail4; + + if (WalkTree (pScreen, vesaLayerAdd, (pointer) pNewLayer) == WT_STOPWALKING) + goto bail5; + + WalkTree (pScreen, vesaLayerRemove, (pointer) pscr->pLayer); + LayerDestroy (pScreen, pscr->pLayer); + + pscr->pLayer = pNewLayer; + + + if (wasEnabled) + KdEnableScreen (pScreen); + + return TRUE; + +bail5: + WalkTree (pScreen, vesaLayerRemove, (pointer) pNewLayer); + LayerDestroy (pScreen, pNewLayer); +bail4: + vesaUnmapFramebuffer (screen); + *pscr = oldscr; + (void) vesaMapFramebuffer (screen); + +bail3: + pScreen->width = oldwidth; + pScreen->height = oldheight; + pScreen->mmWidth = oldmmwidth; + pScreen->mmHeight = oldmmheight; + +bail2: + *pscr = oldscr; + + /* + * Set frame buffer mapping + */ + if (!pscr->shadow) + { + (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), + pScreen->width, + pScreen->height, + screen->fb[0].depth, + screen->fb[0].bitsPerPixel, + screen->fb[0].byteStride, + screen->fb[0].frameBuffer); } + + (void) vesaSetMode (pScreen, &pscr->mode); + +bail1: + if (wasEnabled) + KdEnableScreen (pScreen); +bail0: + + return FALSE; +} + +Bool +vesaRandRInit (ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + if (!RRScreenInit (pScreen)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = vesaRandRGetInfo; + pScrPriv->rrSetConfig = vesaRandRSetConfig; return TRUE; } +#endif Bool -vesaEnable(ScreenPtr pScreen) +vesaInitScreen(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + + if (!LayerStartInit (pScreen)) + return FALSE; + + return TRUE; +} + +Bool +vesaFinishInitScreen (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + + pscr->layerKind = LayerNewKind (pScreen); + + if (!LayerFinishInit (pScreen)) + return FALSE; + + vesaConfigureScreen (pScreen); + + pscr->pLayer = vesaLayerCreate (pScreen); + if (!pscr->pLayer) + return FALSE; + +#ifdef RANDR + if (!vesaRandRInit (pScreen)) + return FALSE; +#endif + + return TRUE; +} + +Bool +vesaSetMode (ScreenPtr pScreen, + VesaModePtr mode) { KdScreenPriv(pScreen); VesaCardPrivPtr priv = pScreenPriv->card->driver; VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; int code; - int i; - CARD32 size; - char *p; - KdMouseMatrix m; - - if (pscr->mode->vbe) + + if (mode->vbe) { if (vesa_verbose) - ErrorF ("Enable VBE mode 0x%x\n", pscr->mode->mode); - code = VbeSetMode(priv->vi, priv->vbeInfo, pscr->mode->mode, - pscr->mapping == VESA_LINEAR); + ErrorF ("Enable VBE mode 0x%x\n", mode->mode); + code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode, + pscr->mapping == VESA_LINEAR, + mode->MemoryModel == MEMORY_DIRECT); } else { if (vesa_verbose) - ErrorF ("Enable BIOS mode 0x%x\n", pscr->mode->mode); - code = VgaSetMode (priv->vi, pscr->mode->mode); + ErrorF ("Enable BIOS mode 0x%x\n", mode->mode); + code = VgaSetMode (priv->vi, mode->mode); } if(code < 0) return FALSE; + return TRUE; +} + +Bool +vesaEnable(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + KdScreenInfo *screen = pScreenPriv->screen; + int code; + int i; + CARD32 size; + char *p; + + if (!vesaSetMode (pScreen, &pscr->mode)) + return FALSE; + switch (pscr->mapping) { case VESA_MONO: VgaSetWritePlaneMask (priv->vi, 0x1); case VESA_LINEAR: + /* + * Remap the frame buffer if necessary + */ + if (!pscr->fb) + { + if (pscr->mode.vbe) + pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, + pscr->mode.mode, + &pscr->fb_size); + else + pscr->fb = VgaMapFramebuffer (priv->vi, + pscr->mode.mode, + &pscr->fb_size); + if (!pscr->fb) + return FALSE; + screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb); + /* + * Set frame buffer mapping + */ + if (!pscr->shadow) + { + (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), + pScreen->width, + pScreen->height, + screen->fb[0].depth, + screen->fb[0].bitsPerPixel, + screen->fb[0].byteStride, + screen->fb[0].frameBuffer); + } + } memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE); break; case VESA_WINDOWED: @@ -947,17 +1498,6 @@ vesaEnable(ScreenPtr pScreen) } break; } - if (pscr->rotate) - { - m.matrix[0][0] = 0; m.matrix[0][1] = 1; m.matrix[0][2] = 0; - m.matrix[1][0] = -1; m.matrix[1][1] = 0; m.matrix[1][2] = pScreen->height - 1; - } - else - { - m.matrix[0][0] = 1; m.matrix[0][1] = 0; m.matrix[0][2] = 0; - m.matrix[1][0] = 0; m.matrix[1][1] = 1; m.matrix[1][2] = 0; - } - KdSetMouseMatrix (&m); return TRUE; } @@ -965,8 +1505,9 @@ void vesaDisable(ScreenPtr pScreen) { KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; VesaCardPrivPtr priv = pScreenPriv->card->driver; - VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + VesaScreenPrivPtr pscr = screen->driver; int i=0; CARD32 size; char *p; @@ -999,6 +1540,7 @@ vesaDisable(ScreenPtr pScreen) } break; } + vesaUnmapFramebuffer (screen); } void @@ -1035,7 +1577,7 @@ vesaRestore(KdCardInfo *card) { if (vesa_verbose) ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode); - VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0); + VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0); } else { @@ -1052,6 +1594,8 @@ vesaCardFini(KdCardInfo *card) if (priv->vbeInfo) VbeCleanup (priv->vi, priv->vbeInfo); + if (priv->modes) + xfree (priv->modes); Vm86Cleanup(priv->vi); } @@ -1061,16 +1605,7 @@ vesaScreenFini(KdScreenInfo *screen) VesaScreenPrivPtr pscr = screen->driver; VesaCardPrivPtr priv = screen->card->driver; - if (pscr->fb) - { - if (pscr->mode->vbe) - VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode->mode, pscr->fb); - else - VgaUnmapFramebuffer (priv->vi); - } - - if (pscr->shadow) - KdShadowScreenFini (screen); + vesaUnmapFramebuffer (screen); screen->fb[0].depth = pscr->origDepth; } @@ -1110,8 +1645,9 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; VesaCardPrivPtr priv = pScreenPriv->card->driver; int p; - CARD8 scratch[4]; + CARD8 *scratch; int red, green, blue; + int min, max; if (vesa_swap_rgb) { @@ -1126,13 +1662,20 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) blue = 2; } + min = 256; + max = 0; while (n--) { + p = pdefs->pixel; + if (p < min) + min = p; + if (p > max) + max = p; + scratch = priv->cmap + (p * 4); scratch[red] = pdefs->red >> 8; scratch[green] = pdefs->green >> 8; scratch[blue] = pdefs->blue >> 8; scratch[3] = 0; - p = pdefs->pixel; pdefs++; if (pscr->mapping == VESA_PLANAR) { @@ -1150,19 +1693,22 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) vesaSetPalette (priv, 0x14, 1, scratch); } } - else - vesaSetPalette(priv, p, 1, scratch); } + if (pscr->mapping != VESA_PLANAR) + vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4); } void vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) { KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; VesaCardPrivPtr priv = pScreenPriv->card->driver; int first, i, j, k; - CARD8 scratch[4]; int red, green, blue; + int min, max; + int p; + CARD8 *scratch; if (vesa_swap_rgb) { @@ -1177,8 +1723,24 @@ vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) blue = 2; } - for(i = 0; i<n; i++) { - vesaGetPalette(priv, pdefs[i].pixel, 1, scratch); + min = 256; + max = 0; + for(i = 0; i < n; i++) + { + p = pdefs[i].pixel; + if (p < min) + min = p; + if (p > max) + max = p; + if (pscr->mapping == VESA_PLANAR) + vesaGetPalette (priv, p, 1, priv->cmap + p * 4); + } + if (pscr->mapping != VESA_PLANAR) + vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4); + for (i = 0; i < n; i++) + { + p = pdefs[i].pixel; + scratch = priv->cmap + p * 4; pdefs[i].red = scratch[red]<<8; pdefs[i].green = scratch[green]<<8; pdefs[i].blue = scratch[blue]<<8; diff --git a/xc/programs/Xserver/hw/kdrive/vesa/vesa.h b/xc/programs/Xserver/hw/kdrive/vesa/vesa.h index 2f23ec054..7b69cf6dc 100644 --- a/xc/programs/Xserver/hw/kdrive/vesa/vesa.h +++ b/xc/programs/Xserver/hw/kdrive/vesa/vesa.h @@ -19,13 +19,17 @@ 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.11 2001/07/20 19:35:30 keithp Exp $ */ #ifndef _VESA_H_ #define _VESA_H_ #include "kdrive.h" +#include "layer.h" #include "vm86.h" +#ifdef RANDR +#include "randrstr.h" +#endif #define VESA_TEXT_SAVE (64*1024) @@ -72,14 +76,15 @@ typedef struct _VesaMode { typedef struct _VesaCardPriv { int vbe; - Vm86InfoPtr vi; VesaModePtr modes; int nmode; + Vm86InfoPtr vi; int vga_palette; int old_vbe_mode; int old_vga_mode; VbeInfoPtr vbeInfo; char text[VESA_TEXT_SAVE]; + CARD8 cmap[256*4]; } VesaCardPrivRec, *VesaCardPrivPtr; #define VESA_LINEAR 0 @@ -88,13 +93,15 @@ typedef struct _VesaCardPriv { #define VESA_MONO 3 typedef struct _VesaScreenPriv { - VesaModePtr mode; + VesaModeRec mode; Bool shadow; - Bool rotate; + int rotate; int mapping; int origDepth; + int layerKind; void *fb; int fb_size; + LayerPtr pLayer; } VesaScreenPrivRec, *VesaScreenPrivPtr; extern int vesa_video_mode; @@ -118,10 +125,16 @@ vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr); Bool vesaScreenInit(KdScreenInfo *screen); +LayerPtr +vesaLayerCreate (ScreenPtr pScreen); + Bool vesaInitScreen(ScreenPtr pScreen); Bool +vesaFinishInitScreen(ScreenPtr pScreen); + +Bool vesaEnable(ScreenPtr pScreen); void diff --git a/xc/programs/Xserver/hw/kdrive/vesa/vesainit.c b/xc/programs/Xserver/hw/kdrive/vesa/vesainit.c index 3ea1a9264..7d12b5cc6 100644 --- a/xc/programs/Xserver/hw/kdrive/vesa/vesainit.c +++ b/xc/programs/Xserver/hw/kdrive/vesa/vesainit.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/vesainit.c,v 1.5 2000/12/08 21:40:29 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/vesa/vesainit.c,v 1.6 2001/06/04 09:45:42 keithp Exp $ */ #include "vesa.h" @@ -49,6 +49,8 @@ const KdCardFuncs vesaFuncs = { vesaGetColors, /* getColors */ vesaPutColors, /* putColors */ + + vesaFinishInitScreen, /* finishInitScreen */ }; void |