summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-29 20:07:11 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-29 20:07:11 +0000
commitc77a38c368cb8b91d7096a52cc8075d991aab533 (patch)
treea3c7c1d7a08769e8e7d0b86a1ab4571b47b19831 /driver
parent929b7a08aff7ef617f24a4795474bf7d9b0ecc49 (diff)
Add support for vesafb to the wsfb driver. This makes it possible to
run an unaccelerated and unprivileged X server with machdep.allowaperture=0 on i386.
Diffstat (limited to 'driver')
-rw-r--r--driver/xf86-video-wsfb/src/wsfb_driver.c169
1 files changed, 134 insertions, 35 deletions
diff --git a/driver/xf86-video-wsfb/src/wsfb_driver.c b/driver/xf86-video-wsfb/src/wsfb_driver.c
index 621927ce0..0d0bb80c3 100644
--- a/driver/xf86-video-wsfb/src/wsfb_driver.c
+++ b/driver/xf86-video-wsfb/src/wsfb_driver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsfb_driver.c,v 1.2 2006/11/28 19:59:08 matthieu Exp $ */
+/* $OpenBSD: wsfb_driver.c,v 1.3 2006/11/29 20:07:10 matthieu Exp $ */
/*
* Copyright (c) 2001 Matthieu Herrb
* All rights reserved.
@@ -413,7 +413,7 @@ static Bool
WsfbPreInit(ScrnInfoPtr pScrn, int flags)
{
WsfbPtr fPtr;
- int default_depth, wstype;
+ int defaultDepth, depths, flags24, wstype;
char *dev, *s;
char *mod = NULL;
const char *reqSym = NULL;
@@ -441,17 +441,100 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags)
if (fPtr->fd == -1) {
return FALSE;
}
-
- if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) {
+ if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl WSDISPLAY_GINFO: %s\n",
+ "ioctl WSDISPLAY_GTYPE: %s\n",
strerror(errno));
return FALSE;
}
- if (ioctl(fPtr->fd, WSDISPLAYIO_GTYPE, &wstype) == -1) {
+ /*
+ * depth
+ */
+ defaultDepth = 0;
+ if (ioctl(fPtr->fd, WSDISPLAYIO_GETSUPPORTEDDEPTH,
+ &depths) == 0) {
+ /* Preferred order for default depth selection. */
+ if (depths & WSDISPLAYIO_DEPTH_16)
+ defaultDepth = 16;
+ else if (depths & WSDISPLAYIO_DEPTH_15)
+ defaultDepth = 15;
+ else if (depths & WSDISPLAYIO_DEPTH_8)
+ defaultDepth = 8;
+ else if (depths & WSDISPLAYIO_DEPTH_24)
+ defaultDepth = 24;
+ else if (depths & WSDISPLAYIO_DEPTH_4)
+ defaultDepth = 4;
+ else if (depths & WSDISPLAYIO_DEPTH_1)
+ defaultDepth = 1;
+
+ flags24 = 0;
+ if (depths & WSDISPLAYIO_DEPTH_24_24)
+ flags24 |= Support24bppFb;
+ if (depths & WSDISPLAYIO_DEPTH_24_32)
+ flags24 |= Support32bppFb;
+ if (!flags24)
+ flags24 = Support24bppFb;
+ } else {
+ /* Old way */
+ if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "no way to get depth info: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ if (fPtr->info.depth == 8) {
+ /*
+ * We might run on a byte addressable frame buffer,
+ * but with less than 8 bits per pixel.
+ * We can know this from the colormap size.
+ */
+ defaultDepth = 1;
+ while ((1 << defaultDepth) < fPtr->info.cmsize)
+ defaultDepth++;
+ } else
+ defaultDepth =
+ fPtr->info.depth <= 24 ? fPtr->info.depth : 24;
+
+ if (fPtr->info.depth >= 24)
+ flags24 = Support24bppFb|Support32bppFb;
+ else
+ flags24 = 0;
+ }
+
+ /* Prefer 24bpp for fb since it potentially allows larger modes. */
+ if (flags24 & Support24bppFb)
+ flags24 |= SupportConvert32to24 | PreferConvert32to24;
+
+ if (!xf86SetDepthBpp(pScrn, defaultDepth, 0, 0, flags24))
+ return FALSE;
+
+ if (wstype == WSDISPLAY_TYPE_PCIVGA) {
+ /* Set specified mode */
+ if (pScrn->display->modes != NULL &&
+ pScrn->display->modes[0] != NULL) {
+ struct wsdisplay_gfx_mode gfxmode;
+
+ if (sscanf(pScrn->display->modes[0], "%dx%d",
+ &gfxmode.width, &gfxmode.height) != 2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Can't parse mode name %s\n",
+ pScrn->display->modes[0]);
+ return FALSE;
+ }
+ gfxmode.depth = pScrn->bitsPerPixel;
+ if (ioctl(fPtr->fd, WSDISPLAYIO_SETGFXMODE,
+ &gfxmode) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl WSDISPLAY_SETGFXMODE: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ }
+ }
+ if (ioctl(fPtr->fd, WSDISPLAYIO_GINFO, &fPtr->info) == -1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl WSDISPLAY_GTYPE: %s\n",
- strerror(errno));
+ "ioctl WSDISPLAY_GINFO: %s\n",
+ strerror(errno));
return FALSE;
}
if (ioctl(fPtr->fd, WSDISPLAYIO_LINEBYTES, &fPtr->linebytes) == -1) {
@@ -490,25 +573,6 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags)
}
}
- /*
- * Handle depth
- */
- if (fPtr->info.depth == 8) {
- /*
- * We might run on a byte addressable frame buffer,
- * but with less than 8 bits per pixel. We can know this
- * from the colormap size.
- */
- default_depth = 1;
- while ((1 << default_depth) < fPtr->info.cmsize)
- default_depth++;
- } else
- default_depth = fPtr->info.depth <= 24 ? fPtr->info.depth : 24;
-
- if (!xf86SetDepthBpp(pScrn, default_depth, default_depth,
- fPtr->info.depth,
- fPtr->info.depth >= 24 ? Support24bppFb|Support32bppFb : 0))
- return FALSE;
/* Check consistency */
if (pScrn->bitsPerPixel != fPtr->info.depth) {
@@ -557,6 +621,17 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags)
masks.blue = 0x1f;
}
break;
+ case WSDISPLAY_TYPE_PCIVGA:
+ if (pScrn->depth > 16) {
+ masks.red = 0xff0000;
+ masks.green = 0x00ff00;
+ masks.blue = 0x0000ff;
+ } else {
+ masks.red = 0x1f << 11;
+ masks.green = 0x3f << 5;
+ masks.blue = 0x1f;
+ }
+ break;
default:
masks.red = 0;
masks.green = 0;
@@ -645,6 +720,7 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags)
"Option \"Rotate\" ignored on depth < 8");
}
}
+
/* fake video mode struct */
mode = (DisplayModePtr)xalloc(sizeof(DisplayModeRec));
mode->prev = mode;
@@ -664,10 +740,7 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags)
mode->VTotal = 0;
mode->VScan = 0;
mode->Flags = 0;
- if (pScrn->modes != NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Ignoring mode specification from screen section\n");
- }
+
pScrn->currentMode = pScrn->modes = mode;
pScrn->virtualX = fPtr->info.width;
pScrn->virtualY = fPtr->info.height;
@@ -730,7 +803,7 @@ WsfbScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
TRACE_ENTER("WsfbScreenInit");
#if DEBUG
ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
- "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
+ "\tmask: %x,%x,%x, offset: %u,%u,%u\n",
pScrn->bitsPerPixel,
pScrn->depth,
xf86GetVisualName(pScrn->defaultVisual),
@@ -750,6 +823,13 @@ WsfbScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
len = fPtr->linebytes*fPtr->info.height;
}
break;
+ case 24:
+ if (fPtr->linebytes == fPtr->info.width) {
+ len = fPtr->info.width*fPtr->info.height*3;
+ } else {
+ len = fPtr->linebytes*fPtr->info.height;
+ }
+ break;
case 32:
if (fPtr->linebytes == fPtr->info.width) {
len = fPtr->info.width*fPtr->info.height*sizeof(int);
@@ -835,6 +915,7 @@ WsfbScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
break;
case 8:
case 16:
+ case 24:
case 32:
ret = fbScreenInit(pScreen,
fPtr->fbstart,
@@ -849,8 +930,11 @@ WsfbScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
} /* case */
- if (!ret)
+ if (!ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "fbScreenInit error");
return FALSE;
+ }
if (pScrn->bitsPerPixel > 8) {
/* Fixup RGB ordering */
@@ -1044,20 +1128,34 @@ static Bool
WsfbEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ WsfbPtr fPtr = WSFBPTR(pScrn);
+ int wsmode = WSDISPLAYIO_MODE_DUMBFB;
TRACE_ENTER("EnterVT");
+
+ /* Switch to graphics mode */
+ if (ioctl(fPtr->fd, WSDISPLAYIO_SMODE, &wsmode) == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl WSDISPLAYIO_SMODE: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
pScrn->vtSema = TRUE;
+ TRACE_EXIT("EnterVT");
return TRUE;
}
static void
WsfbLeaveVT(int scrnIndex, int flags)
{
-#if DEBUG
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-#endif
TRACE_ENTER("LeaveVT");
+
+ WsfbRestore(pScrn);
+
+ TRACE_EXIT("LeaveVT");
}
static Bool
@@ -1134,6 +1232,7 @@ WsfbLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
if (ioctl(fPtr->fd,WSDISPLAYIO_PUTCMAP, &cmap) == -1)
ErrorF("ioctl FBIOPUTCMAP: %s\n", strerror(errno));
}
+ TRACE_EXIT("LoadPalette");
}
static Bool