summaryrefslogtreecommitdiff
path: root/hw/kdrive/fbdev/fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/fbdev/fbdev.c')
-rw-r--r--hw/kdrive/fbdev/fbdev.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c
new file mode 100644
index 000000000..c268ae2b1
--- /dev/null
+++ b/hw/kdrive/fbdev/fbdev.c
@@ -0,0 +1,256 @@
+/*
+ * $Id$
+ *
+ * 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: $ */
+
+#include "fbdev.h"
+
+Bool
+fbdevInitialize (KdCardInfo *card, FbdevPriv *priv)
+{
+ int k;
+ if ((priv->fd = open("/dev/fb0", O_RDWR)) < 0) {
+ perror("Error opening /dev/fb0\n");
+ return FALSE;
+ }
+ if ((k=ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix)) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_FSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+ if ((k=ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var)) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_VSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+
+ priv->fb = (unsigned char *) mmap ((caddr_t) NULL,
+ priv->fix.smem_len,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ priv->fd, 0);
+
+ if (priv->fb == (char *)-1)
+ {
+ perror("ERROR: mmap framebuffer fails!");
+ close (priv->fd);
+ return FALSE;
+ }
+}
+
+Bool
+fbdevCardInit (KdCardInfo *card)
+{
+ int k;
+ char *pixels;
+ FbdevPriv *priv;
+
+ priv = (FbdevPriv *) xalloc (sizeof (FbdevPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!fbdevInitialize (card, priv))
+ {
+ xfree (priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+fbdevScreenInit (KdScreenInfo *screen)
+{
+ FbdevPriv *priv = screen->card->driver;
+ Pixel allbits;
+ int depth;
+
+ screen->width = priv->var.xres;
+ screen->height = priv->var.yres;
+ screen->depth = priv->var.bits_per_pixel;
+ screen->bitsPerPixel = priv->var.bits_per_pixel;
+ screen->byteStride = priv->fix.line_length;
+ screen->pixelStride = (priv->fix.line_length * 8 /
+ priv->var.bits_per_pixel);
+ switch (priv->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ screen->visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ screen->blueMask = 0x00;
+ screen->greenMask = 0x00;
+ screen->redMask = 0x00;
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ screen->visuals = (1 << TrueColor);
+ screen->redMask = FbStipMask (priv->var.red.offset, priv->var.red.length);
+ screen->greenMask = FbStipMask (priv->var.green.offset, priv->var.green.length);
+ screen->blueMask = FbStipMask (priv->var.blue.offset, priv->var.blue.length);
+ allbits = screen->redMask | screen->greenMask | screen->blueMask;
+ depth = 32;
+ while (depth && !(allbits & (1 << (depth - 1))))
+ depth--;
+ screen->depth = depth;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ screen->rate = 72;
+ screen->frameBuffer = (CARD8 *) (priv->fb);
+ return TRUE;
+}
+
+void
+fbdevPreserve (KdCardInfo *card)
+{
+}
+
+void
+fbdevEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ int k;
+
+ priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL;
+
+ /* display it on the LCD */
+ k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
+ if (k < 0)
+ perror ("FBIOPUT_VSCREENINFO");
+}
+
+Bool
+fbdevDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+
+ if (!ioctl (priv->fd, FBIOPUT_POWERMODE, &mode))
+ return TRUE;
+ return FALSE;
+}
+
+void
+fbdevDisable (ScreenPtr pScreen)
+{
+}
+
+void
+fbdevRestore (KdCardInfo *card)
+{
+}
+
+void
+fbdevScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+fbdevCardFini (KdCardInfo *card)
+{
+ int k;
+ FbdevPriv *priv = card->driver;
+
+ munmap (priv->fb, priv->fix.smem_len);
+ close (priv->fd);
+ xfree (priv);
+}
+
+void
+fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ struct fb_cmap cmap;
+ int p;
+ int k;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ for (k = 0; k < n; k++)
+ {
+ if (pdefs[k].pixel < min)
+ min = pdefs[k].pixel;
+ if (pdefs[k].pixel > max)
+ max = pdefs[k].pixel;
+ }
+ cmap.start = min;
+ cmap.len = max - min + 1;
+ cmap.red = &priv->red[min];
+ cmap.green = &priv->green[min];;
+ cmap.blue = &priv->blue[min];
+ cmap.transp = 0;
+ k = ioctl (priv->fd, FBIOGETCMAP, &cmap);
+ if (k < 0)
+ {
+ perror ("can't get colormap");
+ return;
+ }
+ while (n--)
+ {
+ p = pdefs->pixel;
+ pdefs->red = priv->red[p];
+ pdefs->green = priv->green[p];
+ pdefs->blue = priv->blue[p];
+ pdefs++;
+ }
+}
+
+void
+fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ struct fb_cmap cmap;
+ int p;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ while (n--)
+ {
+ p = pdefs->pixel;
+ priv->red[p] = pdefs->red;
+ priv->green[p] = pdefs->green;
+ priv->blue[p] = pdefs->blue;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+ pdefs++;
+ }
+ cmap.start = min;
+ cmap.len = max - min + 1;
+ cmap.red = &priv->red[min];
+ cmap.green = &priv->green[min];
+ cmap.blue = &priv->blue[min];
+ cmap.transp = 0;
+ ioctl (priv->fd, FBIOPUTCMAP, &cmap);
+}