From ca1ce2b61d5bbe00f4789f0dc92adaa9b77c88db Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 17 Nov 2008 11:28:15 +0000 Subject: creating xora/xora-driver --- .gitignore | 27 ++ COPYING | 23 + ChangeLog | 66 +++ Makefile.am | 22 + config.h.in | 69 +++ configure.ac | 87 ++++ man/Makefile.am | 59 +++ man/fbdev.man | 63 +++ src/Makefile.am | 32 ++ src/fbdev.c | 1264 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1712 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100644 config.h.in create mode 100644 configure.ac create mode 100644 man/Makefile.am create mode 100644 man/fbdev.man create mode 100644 src/Makefile.am create mode 100644 src/fbdev.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8426b8b --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +Makefile +Makefile.in +.deps +.libs +.msg +*.lo +*.la +*.a +*.o +*~ +aclocal.m4 +autom4te.cache +compile +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +ltmain.sh +missing +xorg-server.pc +stamp-h? +do-not-use-config.h +do-not-use-config.h.in diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..c513618 --- /dev/null +++ b/COPYING @@ -0,0 +1,23 @@ +Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. + +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 fur- +nished 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, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- +NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the XFree86 Project shall not +be used in advertising or otherwise to promote the sale, use or other deal- +ings in this Software without prior written authorization from the XFree86 +Project. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..ead4bce --- /dev/null +++ b/ChangeLog @@ -0,0 +1,66 @@ +2006-05-19 Adam Jackson + + * configure.ac: + * src/fbdev.c: + Bump to 0.3.0 + +2006-05-18 Kevin E. Martin + + * src/fbdev.c: (FBDevShadowInit), (FBDevScreenInit), + (FBDevCloseScreen): + Fix ShadowFB support to work with recent miext/shadow changes from + bug #5460 (Kevin Martin), and apply fix for miext/shadow crasher + https://bugs.freedesktop.org/show_bug.cgi?id=6940 (Kristian + Hoegsberg). + +2006-04-06 Adam Jackson + + * configure.ac: + * src/fbdev.c: + Unlibcwrap. Bump server version requirement. Bump to 0.2.0. + +2006-01-09 David Nusinow + + * man/fbdev.man: + Convert manpage to utf-8 + Bugzilla #1925 + +2005-12-20 Kevin E. Martin + + * configure.ac: + Update package version for X11R7 release. + +2005-12-14 Kevin E. Martin + + * configure.ac: + Update package version number for final X11R7 release candidate. + +2005-12-06 Kevin E. Martin + + * man/Makefile.am: + Change *man_SOURCES ==> *man_PRE to fix autotools warnings. + +2005-12-03 Kevin E. Martin + + * configure.ac: + Update package version number for X11R7 RC3 release. + +2005-12-01 Kevin E. Martin + + * configure.ac: + Remove extraneous AC_MSG_RESULT. + +2005-11-29 Adam Jackson + + * configure.ac: + Only build dlloader modules by default. + +2005-11-09 Kevin E. Martin + + * configure.ac: + Update package version number for X11R7 RC2 release. + +2005-11-01 Kevin E. Martin + + * configure.ac: + Update pkgcheck dependencies to work with separate build roots. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..7052905 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,22 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 (including the next +# paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. + +AUTOMAKE_OPTIONS = foreign +SUBDIRS = src man diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..72ca535 --- /dev/null +++ b/config.h.in @@ -0,0 +1,69 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +#include "xorg-server.h" + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Major version of this package */ +#undef PACKAGE_VERSION_MAJOR + +/* Minor version of this package */ +#undef PACKAGE_VERSION_MINOR + +/* Patch version of this package */ +#undef PACKAGE_VERSION_PATCHLEVEL + +/* Use libpciaccess */ +#undef PCIACCESS + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..ec3d7aa --- /dev/null +++ b/configure.ac @@ -0,0 +1,87 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 (including the next +# paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. +# +# Process this file with autoconf to produce a configure script + +AC_PREREQ(2.57) +AC_INIT([xf86-video-fbdev], + 0.4.0, + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], + xf86-video-fbdev) + +AC_CONFIG_SRCDIR([Makefile.am]) +AM_CONFIG_HEADER([config.h]) +AC_CONFIG_AUX_DIR(.) + +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_MAINTAINER_MODE + +# Checks for programs. +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_CC + +AH_TOP([#include "xorg-server.h"]) + +AC_ARG_WITH(xorg-module-dir, + AC_HELP_STRING([--with-xorg-module-dir=DIR], + [Default xorg module directory [[default=$libdir/xorg/modules]]]), + [moduledir="$withval"], + [moduledir="$libdir/xorg/modules"]) +AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], + [Enable use of libpciaccess (default: disabled)]), + [PCIACCESS=$enableval], [PCIACCESS=no]) + +# Checks for extensions +XORG_DRIVER_CHECK_EXT(RANDR, randrproto) +XORG_DRIVER_CHECK_EXT(RENDER, renderproto) +XORG_DRIVER_CHECK_EXT(XV, videoproto) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_MODULES]) +sdkdir=$(pkg-config --variable=sdkdir xorg-server) + +AM_CONDITIONAL(PCIACCESS, [test "x$PCIACCESS" = xyes]) +if test "x$PCIACCESS" = xyes; then + AC_DEFINE(PCIACCESS, 1, [Use libpciaccess]) + PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) + XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" +fi + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC + +AC_SUBST([XORG_CFLAGS]) +AC_SUBST([moduledir]) + +DRIVER_NAME=fbdev +AC_SUBST([DRIVER_NAME]) + +XORG_MANPAGE_SECTIONS +XORG_RELEASE_VERSION + +AC_OUTPUT([ + Makefile + src/Makefile + man/Makefile +]) diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..bf7ec17 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,59 @@ +# $Id$ +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# +# 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. +# +# 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 OPEN GROUP 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. +# +# Except as contained in this notice, the name of the copyright holders shall +# not be used in advertising or otherwise to promote the sale, use or +# other dealings in this Software without prior written authorization +# from the copyright holders. +# + +drivermandir = $(DRIVER_MAN_DIR) + +driverman_PRE = @DRIVER_NAME@.man + +driverman_DATA = $(driverman_PRE:man=@DRIVER_MAN_SUFFIX@) + +EXTRA_DIST = @DRIVER_NAME@.man + +CLEANFILES = $(driverman_DATA) + +SED = sed + +# Strings to replace in man pages +XORGRELSTRING = @PACKAGE_STRING@ + XORGMANNAME = X Version 11 + +MAN_SUBSTS = \ + -e 's|__vendorversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xorgversion__|"$(XORGRELSTRING)" "$(XORGMANNAME)"|' \ + -e 's|__xservername__|Xorg|g' \ + -e 's|__xconfigfile__|xorg.conf|g' \ + -e 's|__projectroot__|$(prefix)|g' \ + -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \ + -e 's|__drivermansuffix__|$(DRIVER_MAN_SUFFIX)|g' \ + -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \ + -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \ + -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' + +SUFFIXES = .$(DRIVER_MAN_SUFFIX) .man + +.man.$(DRIVER_MAN_SUFFIX): + sed $(MAN_SUBSTS) < $< > $@ diff --git a/man/fbdev.man b/man/fbdev.man new file mode 100644 index 0000000..aed60ce --- /dev/null +++ b/man/fbdev.man @@ -0,0 +1,63 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.man,v 1.2 2001/01/27 18:20:47 dawes Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH FBDEV __drivermansuffix__ __vendorversion__ +.SH NAME +fbdev \- video driver for framebuffer device +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qfbdev\*q" +.BI " BusID \*qpci:" bus : dev : func \*q +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B fbdev +is an __xservername__ driver for framebuffer devices. This is a non-accelerated +driver, the following framebuffer depths are supported: 8, 15, 16, 24. +All visual types are supported for depth 8, and TrueColor visual is +supported for the other depths. Multi-head configurations are supported. +.SH SUPPORTED HARDWARE +The +.B fbdev +driver supports all hardware where a framebuffer driver is available. +fbdev uses the os-specific submodule fbdevhw(__drivermansuffix__) to talk +to the kernel +device driver. Currently a fbdevhw module is available for linux. +.SH CONFIGURATION DETAILS +Please refer to __xconfigfile__(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to +this driver. +.PP +For this driver it is not required to specify modes in the screen +section of the config file. The +.B fbdev +driver can pick up the currently used video mode from the framebuffer +driver and will use it if there are no video modes configured. +.PP +For PCI boards you might have to add a BusID line to the Device +section. See above for a sample line. You can use \*q\__xservername__ +-scanpci\*q +to figure out the correct values. +.PP +The following driver +.B Options +are supported: +.TP +.BI "Option \*qfbdev\*q \*q" string \*q +The framebuffer device to use. Default: /dev/fb0. +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Enable or disable use of the shadow framebuffer layer. Default: on. +.TP +.BI "Option \*qRotate\*q \*q" string \*q +Enable rotation of the display. The supported values are "CW" (clockwise, +90 degrees), "UD" (upside down, 180 degrees) and "CCW" (counter clockwise, +270 degrees). Implies use of the shadow framebuffer layer. Default: off. +.SH "SEE ALSO" +__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), +X(__miscmansuffix__), fbdevhw(__drivermansuffix__) +.SH AUTHORS +Authors include: Gerd Knorr, Michel D\(:anzer, Geert Uytterhoeven diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..1203177 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,32 @@ +# Copyright 2005 Adam Jackson. +# +# 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 +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, 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 (including the next +# paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON 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. + +# this is obnoxious: +# -module lets us name the module exactly how we want +# -avoid-version prevents gratuitous .0.0.0 version numbers on the end +# _ladir passes a dummy rpath to libtool so the thing will actually link +# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc. +AM_CFLAGS = @XORG_CFLAGS@ +fbdev_drv_la_LTLIBRARIES = fbdev_drv.la +fbdev_drv_la_LDFLAGS = -module -avoid-version +fbdev_drv_ladir = @moduledir@/drivers + +fbdev_drv_la_SOURCES = \ + fbdev.c diff --git a/src/fbdev.c b/src/fbdev.c new file mode 100644 index 0000000..df278f5 --- /dev/null +++ b/src/fbdev.c @@ -0,0 +1,1264 @@ +/* + * Authors: Alan Hourihane, + * Michel Dänzer, + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "mipointer.h" +#include "mibstore.h" +#include "micmap.h" +#include "colormapst.h" +#include "xf86cmap.h" +#include "shadow.h" +#include "dgaproc.h" + +/* for visuals */ +#include "fb.h" +#ifdef USE_AFB +#include "afb.h" +#endif + +#include "xf86Resources.h" +#include "xf86RAC.h" + +#include "fbdevhw.h" + +#include "xf86xv.h" + +#ifdef XSERVER_LIBPCIACCESS +#include +#endif + +static Bool debug = 0; + +#define TRACE_ENTER(str) \ + do { if (debug) ErrorF("fbdev: " str " %d\n",pScrn->scrnIndex); } while (0) +#define TRACE_EXIT(str) \ + do { if (debug) ErrorF("fbdev: " str " done\n"); } while (0) +#define TRACE(str) \ + do { if (debug) ErrorF("fbdev trace: " str "\n"); } while (0) + +/* -------------------------------------------------------------------- */ +/* prototypes */ + +static const OptionInfoRec * FBDevAvailableOptions(int chipid, int busid); +static void FBDevIdentify(int flags); +static Bool FBDevProbe(DriverPtr drv, int flags); +#ifdef XSERVER_LIBPCIACCESS +static Bool FBDevPciProbe(DriverPtr drv, int entity_num, + struct pci_device *dev, intptr_t match_data); +#endif +static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags); +static Bool FBDevScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen); +static void * FBDevWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 *size, void *closure); +static void FBDevPointerMoved(int index, int x, int y); +static Bool FBDevDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); +static Bool FBDevDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, + pointer ptr); + + +enum { FBDEV_ROTATE_NONE=0, FBDEV_ROTATE_CW=270, FBDEV_ROTATE_UD=180, FBDEV_ROTATE_CCW=90 }; + + +/* -------------------------------------------------------------------- */ + +/* + * This is intentionally screen-independent. It indicates the binding + * choice made in the first PreInit. + */ +static int pix24bpp = 0; + +#define FBDEV_VERSION 4000 +#define FBDEV_NAME "FBDEV" +#define FBDEV_DRIVER_NAME "fbdev" + +#ifdef XSERVER_LIBPCIACCESS +static const struct pci_id_match fbdev_device_match[] = { + { + PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, + 0x00030000, 0x00ffffff, 0 + }, + + { 0, 0, 0 }, +}; +#endif + +_X_EXPORT DriverRec FBDEV = { + FBDEV_VERSION, + FBDEV_DRIVER_NAME, +#if 0 + "driver for linux framebuffer devices", +#endif + FBDevIdentify, + FBDevProbe, + FBDevAvailableOptions, + NULL, + 0, + FBDevDriverFunc, + +#ifdef XSERVER_LIBPCIACCESS + fbdev_device_match, + FBDevPciProbe +#endif +}; + +/* Supported "chipsets" */ +static SymTabRec FBDevChipsets[] = { + { 0, "fbdev" }, +#ifdef USE_AFB + { 0, "afb" }, +#endif + {-1, NULL } +}; + +/* Supported options */ +typedef enum { + OPTION_SHADOW_FB, + OPTION_ROTATE, + OPTION_FBDEV, + OPTION_DEBUG +} FBDevOpts; + +static const OptionInfoRec FBDevOptions[] = { + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE }, + { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE }, + { OPTION_DEBUG, "debug", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +/* -------------------------------------------------------------------- */ + +static const char *afbSymbols[] = { + "afbScreenInit", + "afbCreateDefColormap", + NULL +}; + +static const char *fbSymbols[] = { + "fbScreenInit", + "fbPictureInit", + NULL +}; + +static const char *shadowSymbols[] = { + "shadowAdd", + "shadowInit", + "shadowSetup", + "shadowUpdatePacked", + "shadowUpdatePackedWeak", + "shadowUpdateRotatePacked", + "shadowUpdateRotatePackedWeak", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWInit", + "fbdevHWProbe", + "fbdevHWSetVideoModes", + "fbdevHWUseBuildinMode", + + "fbdevHWGetDepth", + "fbdevHWGetLineLength", + "fbdevHWGetName", + "fbdevHWGetType", + "fbdevHWGetVidmem", + "fbdevHWLinearOffset", + "fbdevHWLoadPalette", + "fbdevHWMapVidmem", + "fbdevHWUnmapVidmem", + + /* colormap */ + "fbdevHWLoadPalette", + "fbdevHWLoadPaletteWeak", + + /* ScrnInfo hooks */ + "fbdevHWAdjustFrameWeak", + "fbdevHWEnterVTWeak", + "fbdevHWLeaveVTWeak", + "fbdevHWModeInit", + "fbdevHWRestore", + "fbdevHWSave", + "fbdevHWSaveScreen", + "fbdevHWSaveScreenWeak", + "fbdevHWSwitchModeWeak", + "fbdevHWValidModeWeak", + + "fbdevHWDPMSSet", + "fbdevHWDPMSSetWeak", + + NULL +}; + +#ifdef XFree86LOADER + +MODULESETUPPROTO(FBDevSetup); + +static XF86ModuleVersionInfo FBDevVersRec = +{ + "fbdev", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + NULL, + {0,0,0,0} +}; + +_X_EXPORT XF86ModuleData fbdevModuleData = { &FBDevVersRec, FBDevSetup, NULL }; + +pointer +FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&FBDEV, module, HaveDriverFuncs); + LoaderRefSymLists(afbSymbols, fbSymbols, + shadowSymbols, fbdevHWSymbols, NULL); + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#endif /* XFree86LOADER */ + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +typedef struct { + unsigned char* fbstart; + unsigned char* fbmem; + int fboff; + int lineLength; + int rotate; + Bool shadowFB; + void *shadow; + CloseScreenProcPtr CloseScreen; + CreateScreenResourcesProcPtr CreateScreenResources; + void (*PointerMoved)(int index, int x, int y); + EntityInfoPtr pEnt; + /* DGA info */ + DGAModePtr pDGAMode; + int nDGAMode; + OptionInfoPtr Options; +} FBDevRec, *FBDevPtr; + +#define FBDEVPTR(p) ((FBDevPtr)((p)->driverPrivate)) + +static Bool +FBDevGetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(FBDevRec), 1); + return TRUE; +} + +static void +FBDevFreeRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; +} + +/* -------------------------------------------------------------------- */ + +static const OptionInfoRec * +FBDevAvailableOptions(int chipid, int busid) +{ + return FBDevOptions; +} + +static void +FBDevIdentify(int flags) +{ + xf86PrintChipsets(FBDEV_NAME, "driver for framebuffer", FBDevChipsets); +} + + +#ifdef XSERVER_LIBPCIACCESS +static Bool FBDevPciProbe(DriverPtr drv, int entity_num, + struct pci_device *dev, intptr_t match_data) +{ + ScrnInfoPtr pScrn = NULL; + + if (!xf86LoadDrvSubModule(drv, "fbdevhw")) + return FALSE; + + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + + pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, NULL, + NULL, NULL, NULL, NULL); + if (pScrn) { + char *device; + GDevPtr devSection = xf86GetDevFromEntity(pScrn->entityList[0], + pScrn->entityInstanceList[0]); + + device = xf86FindOptionValue(devSection->options, "fbdev"); + if (fbdevHWProbe(NULL, device, NULL)) { + pScrn->driverVersion = FBDEV_VERSION; + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + pScrn->Probe = FBDevProbe; + pScrn->PreInit = FBDevPreInit; + pScrn->ScreenInit = FBDevScreenInit; + pScrn->SwitchMode = fbdevHWSwitchModeWeak(); + pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); + pScrn->EnterVT = fbdevHWEnterVTWeak(); + pScrn->LeaveVT = fbdevHWLeaveVTWeak(); + pScrn->ValidMode = fbdevHWValidModeWeak(); + + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "claimed PCI slot %d@%d:%d:%d\n", + dev->bus, dev->domain, dev->dev, dev->func); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "using %s\n", device ? device : "default device"); + } + else { + pScrn = NULL; + } + } + + return (pScrn != NULL); +} +#endif + + +static Bool +FBDevProbe(DriverPtr drv, int flags) +{ + int i; + ScrnInfoPtr pScrn; + GDevPtr *devSections; + int numDevSections; + int bus,device,func; + char *dev; + Bool foundScreen = FALSE; + + TRACE("probe start"); + + /* For now, just bail out for PROBE_DETECT. */ + if (flags & PROBE_DETECT) + return FALSE; + + if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + if (!xf86LoadDrvSubModule(drv, "fbdevhw")) + return FALSE; + + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + + for (i = 0; i < numDevSections; i++) { + Bool isIsa = FALSE; +#ifndef XSERVER_LIBPCIACCESS + Bool isPci = FALSE; +#endif + + dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); + if (devSections[i]->busID) { +#ifndef XSERVER_LIBPCIACCESS + if (xf86ParsePciBusString(devSections[i]->busID,&bus,&device, + &func)) { + if (!xf86CheckPciSlot(bus,device,func)) + continue; + isPci = TRUE; + } else +#endif + if (xf86ParseIsaBusString(devSections[i]->busID)) + isIsa = TRUE; + + } + if (fbdevHWProbe(NULL,dev,NULL)) { + pScrn = NULL; +#ifndef XSERVER_LIBPCIACCESS + if (isPci) { + /* XXX what about when there's no busID set? */ + int entity; + + entity = xf86ClaimPciSlot(bus,device,func,drv, + 0,devSections[i], + TRUE); + pScrn = xf86ConfigPciEntity(pScrn,0,entity, + NULL,RES_SHARED_VGA, + NULL,NULL,NULL,NULL); + /* xf86DrvMsg() can't be called without setting these */ + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "claimed PCI slot %d:%d:%d\n",bus,device,func); + + } else +#endif + if (isIsa) { + int entity; + + entity = xf86ClaimIsaSlot(drv, 0, + devSections[i], TRUE); + pScrn = xf86ConfigIsaEntity(pScrn,0,entity, + NULL,RES_SHARED_VGA, + NULL,NULL,NULL,NULL); + } else { + int entity; + + entity = xf86ClaimFbSlot(drv, 0, + devSections[i], TRUE); + pScrn = xf86ConfigFbEntity(pScrn,0,entity, + NULL,NULL,NULL,NULL); + + } + if (pScrn) { + foundScreen = TRUE; + + pScrn->driverVersion = FBDEV_VERSION; + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + pScrn->Probe = FBDevProbe; + pScrn->PreInit = FBDevPreInit; + pScrn->ScreenInit = FBDevScreenInit; + pScrn->SwitchMode = fbdevHWSwitchModeWeak(); + pScrn->AdjustFrame = fbdevHWAdjustFrameWeak(); + pScrn->EnterVT = fbdevHWEnterVTWeak(); + pScrn->LeaveVT = fbdevHWLeaveVTWeak(); + pScrn->ValidMode = fbdevHWValidModeWeak(); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "using %s\n", dev ? dev : "default device"); + } + } + } + xfree(devSections); + TRACE("probe done"); + return foundScreen; +} + +static Bool +FBDevPreInit(ScrnInfoPtr pScrn, int flags) +{ + FBDevPtr fPtr; + int default_depth, fbbpp; + const char *mod = NULL, *s; + const char **syms = NULL; + int type; + + if (flags & PROBE_DETECT) return FALSE; + + TRACE_ENTER("PreInit"); + + /* Check the number of entities, and fail if it isn't one. */ + if (pScrn->numEntities != 1) + return FALSE; + + pScrn->monitor = pScrn->confScreen->monitor; + + FBDevGetRec(pScrn); + fPtr = FBDEVPTR(pScrn); + + fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + /* XXX Is this right? Can probably remove RAC_FB */ + pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; + + if (fPtr->pEnt->location.type == BUS_PCI && + xf86RegisterResources(fPtr->pEnt->index,NULL,ResExclusive)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "xf86RegisterResources() found resource conflicts\n"); + return FALSE; + } + + /* open device */ + if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(fPtr->pEnt->device->options,"fbdev"))) + return FALSE; + default_depth = fbdevHWGetDepth(pScrn,&fbbpp); + if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, fbbpp, + Support24bppFb | Support32bppFb | SupportConvert32to24 | SupportConvert24to32)) + return FALSE; + xf86PrintDepthBpp(pScrn); + + /* Get the depth24 pixmap format */ + if (pScrn->depth == 24 && pix24bpp == 0) + pix24bpp = xf86GetBppFromDepth(pScrn, 24); + + /* color weight */ + if (pScrn->depth > 8) { + rgb zeros = { 0, 0, 0 }; + if (!xf86SetWeight(pScrn, zeros, zeros)) + return FALSE; + } + + /* visual init */ + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + /* We don't currently support DirectColor at > 8bpp */ + if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "requested default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn,zeros)) { + return FALSE; + } + } + + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + pScrn->chipset = "fbdev"; + pScrn->videoRam = fbdevHWGetVidmem(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "hardware: %s (video memory:" + " %dkB)\n", fbdevHWGetName(pScrn), pScrn->videoRam/1024); + + /* handle options */ + xf86CollectOptions(pScrn, NULL); + if (!(fPtr->Options = xalloc(sizeof(FBDevOptions)))) + return FALSE; + memcpy(fPtr->Options, FBDevOptions, sizeof(FBDevOptions)); + xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, fPtr->Options); + + /* use shadow framebuffer by default */ + fPtr->shadowFB = xf86ReturnOptValBool(fPtr->Options, OPTION_SHADOW_FB, TRUE); + + debug = xf86ReturnOptValBool(fPtr->Options, OPTION_DEBUG, FALSE); + + /* rotation */ + fPtr->rotate = FBDEV_ROTATE_NONE; + if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) + { + if(!xf86NameCmp(s, "CW")) + { + fPtr->shadowFB = TRUE; + fPtr->rotate = FBDEV_ROTATE_CW; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "rotating screen clockwise\n"); + } + else if(!xf86NameCmp(s, "CCW")) + { + fPtr->shadowFB = TRUE; + fPtr->rotate = FBDEV_ROTATE_CCW; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "rotating screen counter-clockwise\n"); + } + else if(!xf86NameCmp(s, "UD")) + { + fPtr->shadowFB = TRUE; + fPtr->rotate = FBDEV_ROTATE_UD; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "rotating screen upside-down\n"); + } + else + { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for Option \"Rotate\"\n", s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "valid options are \"CW\", \"CCW\" and \"UD\"\n"); + } + } + + /* select video modes */ + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "checking modes against framebuffer device...\n"); + fbdevHWSetVideoModes(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "checking modes against monitor...\n"); + { + DisplayModePtr mode, first = mode = pScrn->modes; + + if (mode != NULL) do { + mode->status = xf86CheckModeForMonitor(mode, pScrn->monitor); + mode = mode->next; + } while (mode != NULL && mode != first); + + xf86PruneDriverModes(pScrn); + } + + if (NULL == pScrn->modes) + fbdevHWUseBuildinMode(pScrn); + pScrn->currentMode = pScrn->modes; + + /* First approximation, may be refined in ScreenInit */ + pScrn->displayWidth = pScrn->virtualX; + + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch ((type = fbdevHWGetType(pScrn))) + { + case FBDEVHW_PLANES: + mod = "afb"; + syms = afbSymbols; + break; + case FBDEVHW_PACKED_PIXELS: + switch (pScrn->bitsPerPixel) + { + case 8: + case 16: + case 24: + case 32: + mod = "fb"; + syms = fbSymbols; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "unsupported number of bits per pixel: %d", + pScrn->bitsPerPixel); + return FALSE; + } + break; + case FBDEVHW_INTERLEAVED_PLANES: + /* Not supported yet, don't know what to do with this */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "interleaved planes are not yet supported by the " + "fbdev driver\n"); + return FALSE; + case FBDEVHW_TEXT: + /* This should never happen ... + * we should check for this much much earlier ... */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "text mode is not supported by the fbdev driver\n"); + return FALSE; + case FBDEVHW_VGA_PLANES: + /* Not supported yet */ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "EGA/VGA planes are not yet supported by the fbdev " + "driver\n"); + return FALSE; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "unrecognised fbdev hardware type (%d)\n", type); + return FALSE; + } + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + FBDevFreeRec(pScrn); + return FALSE; + } + if (mod && syms) { + xf86LoaderReqSymLists(syms, NULL); + } + + /* Load shadow if needed */ + if (fPtr->shadowFB) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "using shadow" + " framebuffer\n"); + if (!xf86LoadSubModule(pScrn, "shadow")) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + TRACE_EXIT("PreInit"); + return TRUE; +} + + +static Bool +FBDevCreateScreenResources(ScreenPtr pScreen) +{ + PixmapPtr pPixmap; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + Bool ret; + + pScreen->CreateScreenResources = fPtr->CreateScreenResources; + ret = pScreen->CreateScreenResources(pScreen); + pScreen->CreateScreenResources = FBDevCreateScreenResources; + + if (!ret) + return FALSE; + + pPixmap = pScreen->GetScreenPixmap(pScreen); + + if (!shadowAdd(pScreen, pPixmap, fPtr->rotate ? + shadowUpdateRotatePackedWeak() : shadowUpdatePackedWeak(), + FBDevWindowLinear, fPtr->rotate, NULL)) { + return FALSE; + } + + return TRUE; +} + +static Bool +FBDevShadowInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + if (!shadowSetup(pScreen)) { + return FALSE; + } + + fPtr->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = FBDevCreateScreenResources; + + return TRUE; +} + + +static Bool +FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + VisualPtr visual; + int init_picture = 0; + int ret, flags; + int type; + + TRACE_ENTER("FBDevScreenInit"); + +#if DEBUG + ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n" + "\tmask: %x,%x,%x, offset: %d,%d,%d\n", + pScrn->bitsPerPixel, + pScrn->depth, + xf86GetVisualName(pScrn->defaultVisual), + pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue, + pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue); +#endif + + if (NULL == (fPtr->fbmem = fbdevHWMapVidmem(pScrn))) { + xf86DrvMsg(scrnIndex,X_ERROR,"mapping of video memory" + " failed\n"); + return FALSE; + } + fPtr->fboff = fbdevHWLinearOffset(pScrn); + + fbdevHWSave(pScrn); + + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) { + xf86DrvMsg(scrnIndex,X_ERROR,"mode initialization failed\n"); + return FALSE; + } + fbdevHWSaveScreen(pScreen, SCREEN_SAVER_ON); + fbdevHWAdjustFrame(scrnIndex,0,0,0); + + /* mi layer */ + miClearVisualTypes(); + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor)) { + xf86DrvMsg(scrnIndex,X_ERROR,"visual type setup failed" + " for %d bits per pixel [1]\n", + pScrn->bitsPerPixel); + return FALSE; + } + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) { + xf86DrvMsg(scrnIndex,X_ERROR,"visual type setup failed" + " for %d bits per pixel [2]\n", + pScrn->bitsPerPixel); + return FALSE; + } + } + if (!miSetPixmapDepths()) { + xf86DrvMsg(scrnIndex,X_ERROR,"pixmap depth setup failed\n"); + return FALSE; + } + + if(fPtr->rotate==FBDEV_ROTATE_CW || fPtr->rotate==FBDEV_ROTATE_CCW) + { + int tmp = pScrn->virtualX; + pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY; + pScrn->virtualY = tmp; + } else if (!fPtr->shadowFB) { + /* FIXME: this doesn't work for all cases, e.g. when each scanline + has a padding which is independent from the depth (controlfb) */ + pScrn->displayWidth = fbdevHWGetLineLength(pScrn) / + (pScrn->bitsPerPixel / 8); + + if (pScrn->displayWidth != pScrn->virtualX) { + xf86DrvMsg(scrnIndex, X_INFO, + "Pitch updated to %d after ModeInit\n", + pScrn->displayWidth); + } + } + + if(fPtr->rotate && !fPtr->PointerMoved) { + fPtr->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = FBDevPointerMoved; + } + + fPtr->fbstart = fPtr->fbmem + fPtr->fboff; + + if (fPtr->shadowFB) { + fPtr->shadow = xcalloc(1, pScrn->virtualX * pScrn->virtualY * + pScrn->bitsPerPixel); + + if (!fPtr->shadow) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate shadow framebuffer\n"); + return FALSE; + } + } + + switch ((type = fbdevHWGetType(pScrn))) + { +#ifdef USE_AFB + case FBDEVHW_PLANES: + if (fPtr->rotate) + { + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: rotate not supported for afb\n"); + ret = FALSE; + break; + } + if (fPtr->shadowFB) + { + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: shadow framebuffer not supported" + " for afb\n"); + ret = FALSE; + break; + } + ret = afbScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; +#endif + case FBDEVHW_PACKED_PIXELS: + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 24: + case 32: + ret = fbScreenInit(pScreen, fPtr->shadowFB ? fPtr->shadow + : fPtr->fbstart, pScrn->virtualX, + pScrn->virtualY, pScrn->xDpi, + pScrn->yDpi, pScrn->displayWidth, + pScrn->bitsPerPixel); + init_picture = 1; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: invalid number of bits per" + " pixel (%d) encountered in" + " FBDevScreenInit()\n", pScrn->bitsPerPixel); + ret = FALSE; + break; + } + break; + case FBDEVHW_INTERLEAVED_PLANES: + /* This should never happen ... + * we should check for this much much earlier ... */ + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: interleaved planes are not yet " + "supported by the fbdev driver\n"); + ret = FALSE; + break; + case FBDEVHW_TEXT: + /* This should never happen ... + * we should check for this much much earlier ... */ + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: text mode is not supported by the " + "fbdev driver\n"); + ret = FALSE; + break; + case FBDEVHW_VGA_PLANES: + /* Not supported yet */ + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: EGA/VGA Planes are not yet " + "supported by the fbdev driver\n"); + ret = FALSE; + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: unrecognised hardware type (%d) " + "encountered in FBDevScreenInit()\n", type); + ret = FALSE; + break; + } + if (!ret) + return FALSE; + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + /* must be after RGB ordering fixed */ + if (init_picture && !fbPictureInit(pScreen, NULL, 0)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Render extension initialisation failed\n"); + + if (fPtr->shadowFB && !FBDevShadowInit(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "shadow framebuffer initialization failed\n"); + return FALSE; + } + + if (!fPtr->rotate) + FBDevDGAInit(pScrn, pScreen); + else { + xf86DrvMsg(scrnIndex, X_INFO, "display rotated; disabling DGA\n"); + xf86DrvMsg(scrnIndex, X_INFO, "using driver rotation; disabling " + "XRandR\n"); + xf86DisableRandR(); + if (pScrn->bitsPerPixel == 24) + xf86DrvMsg(scrnIndex, X_WARNING, "rotation might be broken at 24 " + "bits per pixel\n"); + } + + xf86SetBlackWhitePixels(pScreen); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* colormap */ + switch ((type = fbdevHWGetType(pScrn))) + { + /* XXX It would be simpler to use miCreateDefColormap() in all cases. */ +#ifdef USE_AFB + case FBDEVHW_PLANES: + if (!afbCreateDefColormap(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: afbCreateDefColormap " + "failed in FBDevScreenInit()\n"); + return FALSE; + } + break; +#endif + case FBDEVHW_PACKED_PIXELS: + if (!miCreateDefColormap(pScreen)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: miCreateDefColormap failed " + "in FBDevScreenInit()\n"); + return FALSE; + } + break; + case FBDEVHW_INTERLEAVED_PLANES: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: interleaved planes are not yet " + "supported by the fbdev driver\n"); + return FALSE; + case FBDEVHW_TEXT: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: text mode is not supported by " + "the fbdev driver\n"); + return FALSE; + case FBDEVHW_VGA_PLANES: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: EGA/VGA planes are not yet " + "supported by the fbdev driver\n"); + return FALSE; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "internal error: unrecognised fbdev hardware type " + "(%d) encountered in FBDevScreenInit()\n", type); + return FALSE; + } + flags = CMAP_PALETTED_TRUECOLOR; + if(!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPaletteWeak(), + NULL, flags)) + return FALSE; + + xf86DPMSInit(pScreen, fbdevHWDPMSSetWeak(), 0); + + pScreen->SaveScreen = fbdevHWSaveScreenWeak(); + + /* Wrap the current CloseScreen function */ + fPtr->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = FBDevCloseScreen; + + { + XF86VideoAdaptorPtr *ptr; + + int n = xf86XVListGenericAdaptors(pScrn,&ptr); + if (n) { + xf86XVScreenInit(pScreen,ptr,n); + } + } + + TRACE_EXIT("FBDevScreenInit"); + + return TRUE; +} + +static Bool +FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + fbdevHWRestore(pScrn); + fbdevHWUnmapVidmem(pScrn); + if (fPtr->shadow) { + xfree(fPtr->shadow); + fPtr->shadow = NULL; + } + if (fPtr->pDGAMode) { + xfree(fPtr->pDGAMode); + fPtr->pDGAMode = NULL; + fPtr->nDGAMode = 0; + } + pScrn->vtSema = FALSE; + + pScreen->CreateScreenResources = fPtr->CreateScreenResources; + pScreen->CloseScreen = fPtr->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} + + + +/*********************************************************************** + * Shadow stuff + ***********************************************************************/ + +static void * +FBDevWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode, + CARD32 *size, void *closure) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + if (!pScrn->vtSema) + return NULL; + + if (fPtr->lineLength) + *size = fPtr->lineLength; + else + *size = fPtr->lineLength = fbdevHWGetLineLength(pScrn); + + return ((CARD8 *)fPtr->fbstart + row * fPtr->lineLength + offset); +} + +static void +FBDevPointerMoved(int index, int x, int y) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + int newX, newY; + + switch (fPtr->rotate) + { + case FBDEV_ROTATE_CW: + /* 90 degrees CW rotation. */ + newX = pScrn->pScreen->height - y - 1; + newY = x; + break; + + case FBDEV_ROTATE_CCW: + /* 90 degrees CCW rotation. */ + newX = y; + newY = pScrn->pScreen->width - x - 1; + break; + + case FBDEV_ROTATE_UD: + /* 180 degrees UD rotation. */ + newX = pScrn->pScreen->width - x - 1; + newY = pScrn->pScreen->height - y - 1; + break; + + default: + /* No rotation. */ + newX = x; + newY = y; + break; + } + + /* Pass adjusted pointer coordinates to wrapped PointerMoved function. */ + (*fPtr->PointerMoved)(index, newX, newY); +} + + +/*********************************************************************** + * DGA stuff + ***********************************************************************/ +static Bool FBDevDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, + unsigned char **ApertureBase, + int *ApertureSize, int *ApertureOffset, + int *flags); +static Bool FBDevDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode); +static void FBDevDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags); + +static Bool +FBDevDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName, + unsigned char **ApertureBase, int *ApertureSize, + int *ApertureOffset, int *flags) +{ + *DeviceName = NULL; /* No special device */ + *ApertureBase = (unsigned char *)(pScrn->memPhysBase); + *ApertureSize = pScrn->videoRam; + *ApertureOffset = pScrn->fbOffset; + *flags = 0; + + return TRUE; +} + +static Bool +FBDevDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode) +{ + DisplayModePtr pMode; + int scrnIdx = pScrn->pScreen->myNum; + int frameX0, frameY0; + + if (pDGAMode) { + pMode = pDGAMode->mode; + frameX0 = frameY0 = 0; + } + else { + if (!(pMode = pScrn->currentMode)) + return TRUE; + + frameX0 = pScrn->frameX0; + frameY0 = pScrn->frameY0; + } + + if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0)) + return FALSE; + (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0); + + return TRUE; +} + +static void +FBDevDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags) +{ + (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags); +} + +static int +FBDevDGAGetViewport(ScrnInfoPtr pScrn) +{ + return (0); +} + +static DGAFunctionRec FBDevDGAFunctions = +{ + FBDevDGAOpenFramebuffer, + NULL, /* CloseFramebuffer */ + FBDevDGASetMode, + FBDevDGASetViewport, + FBDevDGAGetViewport, + NULL, /* Sync */ + NULL, /* FillRect */ + NULL, /* BlitRect */ + NULL, /* BlitTransRect */ +}; + +static void +FBDevDGAAddModes(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + DisplayModePtr pMode = pScrn->modes; + DGAModePtr pDGAMode; + + do { + pDGAMode = xrealloc(fPtr->pDGAMode, + (fPtr->nDGAMode + 1) * sizeof(DGAModeRec)); + if (!pDGAMode) + break; + + fPtr->pDGAMode = pDGAMode; + pDGAMode += fPtr->nDGAMode; + (void)memset(pDGAMode, 0, sizeof(DGAModeRec)); + + ++fPtr->nDGAMode; + pDGAMode->mode = pMode; + pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE; + pDGAMode->byteOrder = pScrn->imageByteOrder; + pDGAMode->depth = pScrn->depth; + pDGAMode->bitsPerPixel = pScrn->bitsPerPixel; + pDGAMode->red_mask = pScrn->mask.red; + pDGAMode->green_mask = pScrn->mask.green; + pDGAMode->blue_mask = pScrn->mask.blue; + pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ? + TrueColor : PseudoColor; + pDGAMode->xViewportStep = 1; + pDGAMode->yViewportStep = 1; + pDGAMode->viewportWidth = pMode->HDisplay; + pDGAMode->viewportHeight = pMode->VDisplay; + + if (fPtr->lineLength) + pDGAMode->bytesPerScanline = fPtr->lineLength; + else + pDGAMode->bytesPerScanline = fPtr->lineLength = fbdevHWGetLineLength(pScrn); + + pDGAMode->imageWidth = pMode->HDisplay; + pDGAMode->imageHeight = pMode->VDisplay; + pDGAMode->pixmapWidth = pDGAMode->imageWidth; + pDGAMode->pixmapHeight = pDGAMode->imageHeight; + pDGAMode->maxViewportX = pScrn->virtualX - + pDGAMode->viewportWidth; + pDGAMode->maxViewportY = pScrn->virtualY - + pDGAMode->viewportHeight; + + pDGAMode->address = fPtr->fbstart; + + pMode = pMode->next; + } while (pMode != pScrn->modes); +} + +static Bool +FBDevDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + + if (pScrn->depth < 8) + return FALSE; + + if (!fPtr->nDGAMode) + FBDevDGAAddModes(pScrn); + + return (DGAInit(pScreen, &FBDevDGAFunctions, + fPtr->pDGAMode, fPtr->nDGAMode)); +} + +static Bool +FBDevDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr) +{ + xorgHWFlags *flag; + + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32*)ptr; + (*flag) = 0; + return TRUE; + default: + return FALSE; + } +} -- cgit v1.2.3