summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2000-09-22 06:25:29 +0000
committerKeith Packard <keithp@keithp.com>2000-09-22 06:25:29 +0000
commit2bbb90ebd927607e0b2c7cd8f3a402b44705fe03 (patch)
tree4b36c1e6c7c30d75822261a6230c5e17fc1977cb
parent02777941e6ac8c79f934ba95b6b2e7f388ffbd14 (diff)
Changes for PPC support under linux and a few overlay additions
-rw-r--r--hw/kdrive/fbdev/fbdev.c191
-rw-r--r--hw/kdrive/fbdev/fbdev.h1
-rw-r--r--hw/kdrive/fbdev/fbinit.c4
-rw-r--r--hw/kdrive/linux/Imakefile4
-rw-r--r--hw/kdrive/linux/bus.c92
-rw-r--r--hw/kdrive/src/kasync.c19
-rw-r--r--hw/kdrive/src/kcmap.c37
-rw-r--r--hw/kdrive/src/kdrive.c2
-rw-r--r--hw/kdrive/src/kdrive.h18
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;