diff options
author | Keith Packard <keithp@keithp.com> | 2000-09-22 06:25:29 +0000 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2000-09-22 06:25:29 +0000 |
commit | 2bbb90ebd927607e0b2c7cd8f3a402b44705fe03 (patch) | |
tree | 4b36c1e6c7c30d75822261a6230c5e17fc1977cb | |
parent | 02777941e6ac8c79f934ba95b6b2e7f388ffbd14 (diff) |
Changes for PPC support under linux and a few overlay additions
-rw-r--r-- | hw/kdrive/fbdev/fbdev.c | 191 | ||||
-rw-r--r-- | hw/kdrive/fbdev/fbdev.h | 1 | ||||
-rw-r--r-- | hw/kdrive/fbdev/fbinit.c | 4 | ||||
-rw-r--r-- | hw/kdrive/linux/Imakefile | 4 | ||||
-rw-r--r-- | hw/kdrive/linux/bus.c | 92 | ||||
-rw-r--r-- | hw/kdrive/src/kasync.c | 19 | ||||
-rw-r--r-- | hw/kdrive/src/kcmap.c | 37 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.c | 2 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 18 |
9 files changed, 327 insertions, 41 deletions
diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index a80479b7f..a63e69736 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -21,14 +21,18 @@ * 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.5 2000/09/03 05:11:17 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.6 2000/09/15 07:25:12 keithp Exp $ */ #include "fbdev.h" +/* this code was used to debug MSB 24bpp code on a 16bpp frame buffer */ +#undef FAKE24_ON_16 + Bool fbdevInitialize (KdCardInfo *card, FbdevPriv *priv) { - int k; + int k; + unsigned long off; if ((priv->fd = open("/dev/fb0", O_RDWR)) < 0) { perror("Error opening /dev/fb0\n"); return FALSE; @@ -44,18 +48,21 @@ fbdevInitialize (KdCardInfo *card, FbdevPriv *priv) return FALSE; } - priv->fb = (unsigned char *) mmap ((caddr_t) NULL, - priv->fix.smem_len, - PROT_READ|PROT_WRITE, - MAP_SHARED, - priv->fd, 0); + priv->fb_base = (unsigned char *) mmap ((caddr_t) NULL, + priv->fix.smem_len, + PROT_READ|PROT_WRITE, + MAP_SHARED, + priv->fd, 0); - if (priv->fb == (char *)-1) + if (priv->fb_base == (char *)-1) { perror("ERROR: mmap framebuffer fails!"); close (priv->fd); return FALSE; } + off = (unsigned long) priv->fix.smem_start % (unsigned long) getpagesize(); + priv->fb = priv->fb_base + off; + return TRUE; } Bool @@ -87,7 +94,12 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) int depth; Bool rotate; Bool shadow; +#ifdef FAKE24_ON_16 + Bool fake24; +#endif + depth = priv->var.bits_per_pixel; + switch (priv->fix.visual) { case FB_VISUAL_PSEUDOCOLOR: screen->fb[0].visuals = ((1 << StaticGray) | @@ -101,15 +113,16 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) screen->fb[0].redMask = 0x00; break; case FB_VISUAL_TRUECOLOR: + case FB_VISUAL_DIRECTCOLOR: screen->fb[0].visuals = (1 << TrueColor); - screen->fb[0].redMask = FbStipMask (priv->var.red.offset, priv->var.red.length); - screen->fb[0].greenMask = FbStipMask (priv->var.green.offset, priv->var.green.length); - screen->fb[0].blueMask = FbStipMask (priv->var.blue.offset, priv->var.blue.length); +#define Mask(o,l) (((1 << l) - 1) << o) + 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); allbits = screen->fb[0].redMask | screen->fb[0].greenMask | screen->fb[0].blueMask; depth = 32; while (depth && !(allbits & (1 << (depth - 1)))) depth--; - screen->fb[0].depth = depth; break; default: return FALSE; @@ -118,24 +131,41 @@ fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv) screen->rate = 72; scrpriv->rotate = ((priv->var.xres < priv->var.yres) != (screen->width < screen->height)); - screen->fb[0].depth = priv->var.bits_per_pixel; - screen->fb[0].bitsPerPixel = priv->var.bits_per_pixel; - if (!scrpriv->rotate) +#ifdef FAKE24_ON_16 + if (screen->fb[0].depth == 24 && screen->fb[0].bitsPerPixel == 24 && + priv->var.bits_per_pixel == 16) { + fake24 = TRUE; + screen->fb[0].redMask = 0xff0000; + screen->fb[0].greenMask = 0x00ff00; + screen->fb[0].blueMask = 0x0000ff; 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; + screen->softCursor = TRUE; + return KdShadowScreenInit (screen); } else +#endif { - screen->width = priv->var.yres; - screen->height = priv->var.xres; - screen->softCursor = TRUE; - return KdShadowScreenInit (screen); + 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; + return KdShadowScreenInit (screen); + } } } @@ -172,6 +202,88 @@ fbdevWindowLinear (ScreenPtr pScreen, return (CARD8 *) priv->fb + row * priv->fix.line_length + offset; } +#ifdef FAKE24_ON_16 +void +fbdevUpdateFake24 (ScreenPtr pScreen, + PixmapPtr pShadow, + RegionPtr damage) +{ + shadowScrPriv(pScreen); + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + FbBits *shaBits; + CARD8 *shaBase, *shaLine, *sha; + CARD16 s; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + int x, y, w, h, width; + int i; + CARD16 *winBase, *winLine, *win; + CARD32 winSize; + + fbGetDrawable (&pShadow->drawable, shaBits, shaStride, shaBpp); + shaStride = shaStride * sizeof (FbBits) / sizeof (CARD8); + shaBase = (CARD8 *) shaBits; + while (nbox--) + { + x = pbox->x1; + y = pbox->y1; + w = (pbox->x2 - pbox->x1); + h = pbox->y2 - pbox->y1; + + shaLine = shaBase + y * shaStride + x * 3; + + while (h--) + { + winSize = 0; + scrBase = 0; + width = w; + scr = x; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (CARD16 *) (*pScrPriv->window) (pScreen, + y, + scr * sizeof (CARD16), + SHADOW_WINDOW_WRITE, + &winSize); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (CARD16); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + while (i--) + { +#if IMAGE_BYTE_ORDER == MSBFirst + *win++ = ((sha[2] >> 3) | + ((sha[1] & 0xf8) << 2) | + ((sha[0] & 0xf8) << 7)); +#else + *win++ = ((sha[0] >> 3) | + ((sha[1] & 0xfc) << 3) | + ((sha[2] & 0xf8) << 8)); +#endif + sha += 3; + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} +#endif /* FAKE24_ON_16 */ + Bool fbdevInitScreen (ScreenPtr pScreen) { @@ -181,6 +293,13 @@ fbdevInitScreen (ScreenPtr pScreen) ShadowUpdateProc update; ShadowWindowProc window; +#ifdef FAKE24_ON_16 + if (pScreenPriv->screen->fb[0].bitsPerPixel == 24 && priv->var.bits_per_pixel == 16) + { + return KdShadowInitScreen (pScreen, fbdevUpdateFake24, fbdevWindowLinear); + } + else +#endif /* FAKE24_ON_16 */ if (scrpriv->rotate) { window = fbdevWindowLinear; @@ -230,6 +349,28 @@ fbdevEnable (ScreenPtr pScreen) 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; + int i; + + for (i = 0; + i < (1 << priv->var.red.length) || + i < (1 << priv->var.green.length) || + i < (1 << priv->var.blue.length); i++) + { + priv->red[i] = i * 65535 / ((1 << priv->var.red.length) - 1); + priv->green[i] = i * 65535 / ((1 << priv->var.green.length) - 1); + priv->blue[i] = i * 65535 / ((1 << priv->var.blue.length) - 1); + } + cmap.start = 0; + cmap.len = i; + cmap.red = &priv->red[0]; + cmap.green = &priv->green[0]; + cmap.blue = &priv->blue[0]; + cmap.transp = 0; + ioctl (priv->fd, FBIOPUTCMAP, &cmap); + } KdSetMouseMatrix (&m); return TRUE; } @@ -268,7 +409,7 @@ fbdevCardFini (KdCardInfo *card) int k; FbdevPriv *priv = card->driver; - munmap (priv->fb, priv->fix.smem_len); + munmap (priv->fb_base, priv->fix.smem_len); close (priv->fd); xfree (priv); } diff --git a/hw/kdrive/fbdev/fbdev.h b/hw/kdrive/fbdev/fbdev.h index e5b8aef1a..9846cdce4 100644 --- a/hw/kdrive/fbdev/fbdev.h +++ b/hw/kdrive/fbdev/fbdev.h @@ -39,6 +39,7 @@ typedef struct _fbdevPriv { __u16 blue[256]; int fd; char *fb; + char *fb_base; Bool rotate; } FbdevPriv; diff --git a/hw/kdrive/fbdev/fbinit.c b/hw/kdrive/fbdev/fbinit.c index e20520c6b..26380e233 100644 --- a/hw/kdrive/fbdev/fbinit.c +++ b/hw/kdrive/fbdev/fbinit.c @@ -70,7 +70,11 @@ InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput (int argc, char **argv) { +#ifdef __powerpc__ + KdInitInput (&BusMouseFuncs, &LinuxKeyboardFuncs); +#else KdInitInput (&Ps2MouseFuncs, &LinuxKeyboardFuncs); +#endif } int diff --git a/hw/kdrive/linux/Imakefile b/hw/kdrive/linux/Imakefile index e69d80322..f7f0879ea 100644 --- a/hw/kdrive/linux/Imakefile +++ b/hw/kdrive/linux/Imakefile @@ -3,9 +3,9 @@ XCOMM $XFree86: $ KDRIVE=.. #include "../Kdrive.tmpl" -SRCS = keyboard.c linux.c ps2.c +SRCS = keyboard.c linux.c ps2.c bus.c -OBJS = keyboard.o linux.o ps2.o +OBJS = keyboard.o linux.o ps2.o bus.o INCLUDES = -I. $(KDINCS) diff --git a/hw/kdrive/linux/bus.c b/hw/kdrive/linux/bus.c new file mode 100644 index 000000000..9e4bce0c8 --- /dev/null +++ b/hw/kdrive/linux/bus.c @@ -0,0 +1,92 @@ +/* + * $XFree86$ + * + * Copyright © 2000 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. + */ + +#define NEED_EVENTS +#include "X.h" +#include "Xproto.h" +#include "inputstr.h" +#include "scrnintstr.h" +#include "kdrive.h" +#include "Xpoll.h" + +/* /dev/adbmouse is a busmouse */ + +void +BusRead (int adbPort) +{ + unsigned char buf[3]; + unsigned char *b; + int n; + int dx, dy; + unsigned long flags; + + n = read (adbPort, buf, 3); + if (n == 3) + { + flags = KD_MOUSE_DELTA; + dx = (char) buf[1]; + dy = -(char) buf[2]; + if ((buf[0] & 4) == 0) + flags |= KD_BUTTON_1; + if ((buf[0] & 2) == 0) + flags |= KD_BUTTON_2; + if ((buf[0] & 1) == 0) + flags |= KD_BUTTON_3; + KdEnqueueMouseEvent (flags, dx, dy); + } +} + +char *BusNames[] = { + "/dev/adbmouse", + "/dev/mouse", +}; + +#define NUM_BUS_NAMES (sizeof (BusNames) / sizeof (BusNames[0])) + +int +BusInit (void) +{ + int i; + int busPort; + + for (i = 0; i < NUM_BUS_NAMES; i++) + { + busPort = open (BusNames[i], 0); + if (busPort >= 0) + return busPort; + } +} + +void +BusFini (int busPort) +{ + if (busPort >= 0) + close (busPort); +} + +KdMouseFuncs BusMouseFuncs = { + BusInit, + BusRead, + BusFini +}; diff --git a/hw/kdrive/src/kasync.c b/hw/kdrive/src/kasync.c index 660d58247..4664e3f19 100644 --- a/hw/kdrive/src/kasync.c +++ b/hw/kdrive/src/kasync.c @@ -235,6 +235,25 @@ KdCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) fbCopyWindow (pWin, ptOldOrg, prgnSrc); } +#if KD_MAX_FB > 1 +void +KdCheckPaintKey(DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer) +{ + KdCheckSync (pDrawable->pScreen); + fbOverlayPaintKey (pDrawable, pRegion, pixel, layer); +} + +void +KdCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) +{ + KdCheckSync (pWin->drawable.pScreen); + fbOverlayCopyWindow (pWin, ptOldOrg, prgnSrc); +} +#endif + void KdScreenInitAsync (ScreenPtr pScreen) { diff --git a/hw/kdrive/src/kcmap.c b/hw/kdrive/src/kcmap.c index c20286b9d..742c34ace 100644 --- a/hw/kdrive/src/kcmap.c +++ b/hw/kdrive/src/kcmap.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/kcmap.c,v 1.3 2000/05/06 22:17:39 keithp Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/kcmap.c,v 1.4 2000/05/24 23:57:56 keithp Exp $ */ #include "kdrive.h" @@ -189,14 +189,15 @@ KdInstallColormap (ColormapPtr pCmap) KdSetColormap (pCmap->pScreen, fb); - /* Tell X clients of the new colorscreen-> */ + /* Tell X clients of the new colormap */ WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid)); } /* * KdUninstallColormap * - * This function uninstalls a colormap by installing the default X colorscreen-> + * This function uninstalls a colormap by either installing + * the default X colormap or erasing the installed colormap pointer. * The default X colormap itself cannot be uninstalled. */ void @@ -204,18 +205,28 @@ KdUninstallColormap (ColormapPtr pCmap) { KdScreenPriv(pCmap->pScreen); int fb = KdColormapFb (pCmap); + Colormap defMapID; + ColormapPtr defMap; - if (pCmap == pScreenPriv->pInstalledmap[0]) - { - Colormap defMapID = pCmap->pScreen->defColormap; + /* ignore if not installed */ + if (pCmap != pScreenPriv->pInstalledmap[fb]) + return; - if ((Colormap) pCmap->mid != defMapID) - { - ColormapPtr defMap = (ColormapPtr) LookupIDByType(defMapID, - RT_COLORMAP); - if (defMap) - (*pCmap->pScreen->InstallColormap)(defMap); - } + /* ignore attempts to uninstall default colormap */ + defMapID = pCmap->pScreen->defColormap; + if ((Colormap) pCmap->mid == defMapID) + return; + + /* install default if on same fb */ + defMap = (ColormapPtr) LookupIDByType(defMapID, RT_COLORMAP); + if (defMap && KdColormapFb (defMap) == fb) + (*pCmap->pScreen->InstallColormap)(defMap); + else + { + /* uninstall and clear colormap pointer */ + WalkTree(pCmap->pScreen, TellLostMap, + (pointer) &(pCmap->mid)); + pScreenPriv->pInstalledmap[fb] = 0; } } diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index b4ce55353..c6a6fc36f 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -646,6 +646,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) pScreenPriv->BackingStoreFuncs.GetSpansPixmap = 0; #endif +#if KD_MAX_FB > 1 if (screen->fb[1].depth) { if (!fbOverlayFinishScreenInit (pScreen, @@ -664,6 +665,7 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) } } else +#endif { if (!fbFinishScreenInit (pScreen, screen->fb[0].frameBuffer, diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index 5c709a2bc..04013ade6 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -52,7 +52,7 @@ extern WindowPtr *WindowTable; #define KD_DPMS_MAX KD_DPMS_POWERDOWN #ifndef KD_MAX_FB -#define KD_MAX_FB 2 +#define KD_MAX_FB FB_OVERLAY_MAX #endif #ifndef KD_MAX_CARD_ADDRESS @@ -350,6 +350,21 @@ KdCheckRestoreAreas (PixmapPtr pPixmap, WindowPtr pWin); void +KdCheckPaintWindow (WindowPtr pWin, RegionPtr pRegion, int what); + +void +KdCheckCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void +KdCheckPaintKey(DrawablePtr pDrawable, + RegionPtr pRegion, + CARD32 pixel, + int layer); + +void +KdCheckOverlayCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void KdScreenInitAsync (ScreenPtr pScreen); void @@ -522,6 +537,7 @@ void ProcessInputEvents (); extern KdMouseFuncs Ps2MouseFuncs; +extern KdMouseFuncs BusMouseFuncs; extern KdKeyboardFuncs LinuxKeyboardFuncs; extern KdOsFuncs LinuxFuncs; |