diff -urN 3.9Pb/config/cf/host.def xc/config/cf/host.def --- 3.9Pb/config/cf/host.def Thu Jan 1 01:00:00 1970 +++ xc/config/cf/host.def Sun Feb 21 15:33:43 1999 @@ -0,0 +1 @@ + diff -urN 3.9Pb/config/cf/xf86site.def xc/config/cf/xf86site.def --- 3.9Pb/config/cf/xf86site.def Sun Feb 21 15:31:13 1999 +++ xc/config/cf/xf86site.def Wed Feb 24 22:29:35 1999 @@ -17,6 +17,8 @@ */ /******************************************************************************/ +#define XConfigFile XF86Config4 + /* * If you have build-specific modifications in your host.def file, but * want an empty host.def file installed when doing 'make install', @@ -168,8 +170,11 @@ * this to YES. This defaults to YES on most platforms. A static server * can be built by setting this to NO. * -#define DoLoadableServer NO */ +#define DoLoadableServer NO /* FIXME */ +#ifdef PpcArchitecture +# define DoLoadableServer NO +#endif /* * Build dlopen() style modules instead of the standard loader modules. diff -urN 3.9Pb/config/cf/xfree86.cf xc/config/cf/xfree86.cf --- 3.9Pb/config/cf/xfree86.cf Sun Feb 21 15:31:20 1999 +++ xc/config/cf/xfree86.cf Mon Feb 22 21:13:12 1999 @@ -74,6 +74,10 @@ #ifndef XF86VgaHw #define XF86VgaHw YES #endif +/* fbdevhw module */ +#ifndef XF86FBDevHw +#define XF86FBDevHw YES +#endif /* XAA module */ #ifndef XF86XAA #define XF86XAA YES @@ -98,7 +102,7 @@ /* Pure PCI drivers should go first */ #ifndef XF86CardDrivers #define XF86CardDrivers mga glint tga s3virge sis cirrus tseng \ - trident chips vga + trident chips fbdev vga #endif #endif @@ -126,6 +130,10 @@ #ifndef XF86VgaHw #define XF86VgaHw YES #endif +/* fbdevhw module */ +#ifndef XF86FBDevHw +#define XF86FBDevHw YES +#endif /* XAA module */ #ifndef XF86XAA #define XF86XAA YES @@ -206,6 +214,78 @@ #ifndef XF86VgaHw #define XF86VgaHw YES #endif +/* fbdevhw module */ +#ifndef XF86FBDevHw +#define XF86FBDevHw YES +#endif +/* XAA module */ +#ifndef XF86XAA +#define XF86XAA YES +#endif +/* ramdac module */ +#ifndef XF86Ramdac +#define XF86Ramdac YES +#endif +/* I2C module */ +#ifndef XF86I2C +#define XF86I2C YES +#endif +/* DDC module */ +#ifndef XF86DDC +#define XF86DDC YES +#endif +/* RAC (Resource Access Control) module */ +#ifndef XF86RAC +#define XF86RAC YES +#endif + +/* Pure PCI drivers should go first */ +#ifndef XF86CardDrivers +#define XF86CardDrivers mga glint s3virge sis cirrus tseng \ + trident chips fbdev vga +#endif +#endif + + +/* + * LinuxPPC + */ +#if defined(PpcArchitecture) && defined(LinuxArchitecture) +#ifndef XF86Server +#define XF86Server YES +#endif +/* 1bpp module */ +#ifndef XF1Bpp +#define XF1Bpp YES +#endif +/* 4bpp module */ +#ifndef XF4Bpp +#define XF4Bpp YES +#endif +/* 8/32bpp overlay module */ +#ifndef XF8_32Bpp +#define XF8_32Bpp YES +#endif +/* 8/16bpp dual fb module */ +#ifndef XF8_16Bpp +#define XF8_16Bpp YES +#endif +/* 24/32bpp conversion module */ +#ifndef XF24_32Bpp +#define XF24_32Bpp YES +#endif +/* shadow fb module */ +#ifndef XFShadowFB +#define XFShadowFB YES +#endif +/* vgahw module */ +#ifndef XF86VgaHw +#define XF86VgaHw YES +#endif +/* fbdevhw module */ +#ifndef XF86FBDevHw +#define XF86FBDevHw YES +#endif /* XAA module */ #ifndef XF86XAA #define XF86XAA YES @@ -268,6 +348,10 @@ /* vgahw module */ #ifndef XF86VgaHw #define XF86VgaHw YES +#endif +/* fbdevhw module */ +#ifndef XF86FBDevHw +#define XF86FBDevHw YES #endif /* XAA module */ #ifndef XF86XAA diff -urN 3.9Pb/programs/Xserver/hw/xfree86/common/xf86Bus.c xc/programs/Xserver/hw/xfree86/common/xf86Bus.c --- 3.9Pb/programs/Xserver/hw/xfree86/common/xf86Bus.c Sun Feb 21 15:31:20 1999 +++ xc/programs/Xserver/hw/xfree86/common/xf86Bus.c Sun Feb 21 15:34:01 1999 @@ -1324,6 +1324,7 @@ static void xf86DisableAccess(void) { + return; DisablePciAccess(); } diff -urN 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile --- 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile Tue Feb 23 23:17:50 1999 @@ -0,0 +1,41 @@ +XCOMM +XCOMM This is an Imakefile for the fbdev driver. +XCOMM + +#define IHaveModules +#include + +SRCS = fbdev.c +OBJS = fbdev.o + +#if XF86LinkKit +INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \ + -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \ + -I$(XF86SRC)/fbdevhw -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\ + -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/shadowfb +#endif + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif + +ModuleObjectRule() + +ObjectModuleTarget(fbdev,$(OBJS)) + +InstallLinkKitNonExecFile(fbdev.c,$(LINKKITDIR)/drivers/svga/fbdev) +InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/svga/fbdev) + +InstallObjectModule(fbdev,$(MODULEDIR),drivers) + +XCOMM old version... +ObjectModuleTarget(fbdev-v1,$(OBJS)) +InstallObjectModule(fbdev-v1,$(MODULEDIR),drivers) + +DependTarget() diff -urN 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev-v1.c xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev-v1.c --- 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev-v1.c Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev-v1.c Tue Feb 23 21:18:57 1999 @@ -0,0 +1,1019 @@ +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "mipointer.h" +#include "mibstore.h" +#include "micmap.h" +#include "colormapst.h" +#include "xf86cmap.h" +#include "shadowfb.h" + +/* for visuals */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" + +#include "linux/fb.h" + +#define DEBUG 1 + +/* -------------------------------------------------------------------- */ +/* prototypes */ + +/* Mandatory functions */ +static void FBDevIdentify(int flags); +static Bool FBDevProbe(DriverPtr drv, int flags); +static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags); +static Bool FBDevScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool FBDevEnterVT(int scrnIndex, int flags); +static void FBDevLeaveVT(int scrnIndex, int flags); +static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool FBDevSaveScreen(ScreenPtr pScreen, Bool unblank); + +/* panning */ +static void FBDevAdjustFrame(int scrnIndex, int x, int y, int flags); + +/* for modeswitching */ +static Bool FBDevSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static int FBDevValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); + +/* -------------------------------------------------------------------- */ + +#define VERSION 4000 +#define FBDEV_NAME "FBDev" +#define FBDEV_DRIVER_NAME "fbdev" +#define FBDEV_MAJOR_VERSION 0 +#define FBDEV_MINOR_VERSION 1 + +DriverRec FBDEV = { + VERSION, + "driver for linux framebuffer devices", + FBDevIdentify, + FBDevProbe, + NULL, + 0 +}; + +/* Supported "chipsets" */ +static SymTabRec FBDevChipsets[] = { + { 0, "fbdev" }, + {-1, NULL } +}; + +/* Supported options */ +typedef enum { + OPTION_NOACCEL, + OPTION_SHADOW_FB, + OPTION_FBDEV +} FBDevOpts; + +static OptionInfoRec FBDevOptions[] = { + { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + + +#ifdef XFree86LOADER + +MODULESETUPPROTO(FBDevSetup); + +static XF86ModuleVersionInfo FBDevVersRec = +{ + "fbdev", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + FBDEV_MAJOR_VERSION, FBDEV_MINOR_VERSION, 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + NULL, + {0,0,0,0} +}; + +XF86ModuleData fbdevModuleData = { &FBDevVersRec, FBDevSetup, NULL }; + +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +pointer +FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&FBDEV, module, 0); + LoaderRefSymLists(cfbSymbols, shadowSymbols, NULL); + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#else /* XFree86LOADER */ + +#include +#include + +#endif /* XFree86LOADER */ + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +typedef struct { + char* device; + int fd; + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + struct fb_var_screeninfo var_saved; + DisplayModeRec buildin; + unsigned char* fbmem; + unsigned char* shadowmem; + int shadowPitch; + unsigned char* fbstart; + void* mmio; + Bool need_mmio; + Bool noAccel; + Bool shadowFB; + CloseScreenProcPtr CloseScreen; +} 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; +} + +/* -------------------------------------------------------------------- */ +/* some helpers for printing debug informations */ + +static void print_fbdev_mode(char *txt, struct fb_var_screeninfo *var) +{ + ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n", + txt,var->pixclock, + var->xres, var->right_margin, var->hsync_len, var->left_margin, + var->yres, var->lower_margin, var->vsync_len, var->upper_margin, + var->bits_per_pixel, + var->red.length, var->green.length, var->blue.length); +} + +static void print_xfree_mode(char *txt, DisplayModePtr mode) +{ + ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n", + txt,mode->Clock, + mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); +} + +/* -------------------------------------------------------------------- */ +/* Convert timings between the XFree and the Frame Buffer Device */ + +static void xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var) +{ + var->xres_virtual = pScrn->virtualX; + var->yres_virtual = pScrn->virtualY; + var->bits_per_pixel = pScrn->bitsPerPixel; + var->red.length = 0; + var->red.offset = 0; + var->green.length = 0; + var->green.offset = 0; + var->blue.length = 0; + var->blue.offset = 0; +} + +static void xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var) +{ + var->xres = mode->HDisplay; + var->yres = mode->VDisplay; + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + var->xoffset = var->yoffset = 0; + var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0; + var->right_margin = mode->HSyncStart-mode->HDisplay; + var->hsync_len = mode->HSyncEnd-mode->HSyncStart; + var->left_margin = mode->HTotal-mode->HSyncEnd; + var->lower_margin = mode->VSyncStart-mode->VDisplay; + var->vsync_len = mode->VSyncEnd-mode->VSyncStart; + var->upper_margin = mode->VTotal-mode->VSyncEnd; + var->sync = 0; + if (mode->Flags & V_PHSYNC) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (mode->Flags & V_PVSYNC) + var->sync |= FB_SYNC_VERT_HIGH_ACT; + if (mode->Flags & V_PCSYNC) + var->sync |= FB_SYNC_COMP_HIGH_ACT; +#if 0 + if (mode->Flags & V_BCAST) + var->sync |= FB_SYNC_BROADCAST; +#endif + if (mode->Flags & V_INTERLACE) + var->vmode = FB_VMODE_INTERLACED; + else if (mode->Flags & V_DBLSCAN) + var->vmode = FB_VMODE_DOUBLE; + else + var->vmode = FB_VMODE_NONINTERLACED; +} + +static void fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode) +{ + mode->Clock = var->pixclock ? 1000000000/var->pixclock : 28000000; + mode->HDisplay = var->xres; + mode->HSyncStart = mode->HDisplay+var->right_margin; + mode->HSyncEnd = mode->HSyncStart+var->hsync_len; + mode->HTotal = mode->HSyncEnd+var->left_margin; + mode->VDisplay = var->yres; + mode->VSyncStart = mode->VDisplay+var->lower_margin; + mode->VSyncEnd = mode->VSyncStart+var->vsync_len; + mode->VTotal = mode->VSyncEnd+var->upper_margin; + mode->Flags = 0; + mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; + mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; + mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC; +#if 0 + if (var->sync & FB_SYNC_BROADCAST) + mode->Flags |= V_BCAST; +#endif + if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) + mode->Flags |= V_INTERLACE; + else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) + mode->Flags |= V_DBLSCAN; + mode->SynthClock = mode->Clock; + mode->CrtcHDisplay = mode->HDisplay; + mode->CrtcHSyncStart = mode->HSyncStart; + mode->CrtcHSyncEnd = mode->HSyncEnd; + mode->CrtcHTotal = mode->HTotal; + mode->CrtcVDisplay = mode->VDisplay; + mode->CrtcVSyncStart = mode->VSyncStart; + mode->CrtcVSyncEnd = mode->VSyncEnd; + mode->CrtcVTotal = mode->VTotal; + mode->CrtcHAdjusted = FALSE; + mode->CrtcVAdjusted = FALSE; +} + +/* + * open correct framebuffer device. + */ + +static int +fbdev_open(char *dev) +{ + struct fb_con2fbmap c2m; + char fbdev[16]; + int fd; +#if DEBUG + ErrorF("fbdev_open: %s\n",dev); +#endif + + /* try argument (from XF86Config) first */ + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* second: environment variable */ + dev = getenv("FRAMEBUFFER"); + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* open the first one */ + if (-1 == (fd = open("/dev/fb0",O_RDWR,0))) + return -1; + +#if 1 + /* FIXME: xf86Info is'nt available for drivers :-( */ + return fd; +#else + /* check which fb device the vt is mapped to */ + c2m.console = xf86Info.vtno; + if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) { + perror("ioctl FBIOGET_CON2FBMAP"); + return fd; + } +#if DEBUG + ErrorF("fbdev_open: vt%02d => fb%d\n",c2m.console,c2m.framebuffer); +#endif + if (c2m.framebuffer != 0) { + /* it is'nt the first, open the correct one */ + sprintf(fbdev,"/dev/fb%d\n",c2m.framebuffer); + close(fd); + fd = open(fbdev,O_RDWR,0); + } + return fd; +#endif +} + +/* -------------------------------------------------------------------- */ + +static void +FBDevIdentify(int flags) +{ + xf86PrintChipsets(FBDEV_NAME, "driver for linux framebuffer", FBDevChipsets); +} + +static Bool +FBDevProbe(DriverPtr drv, int flags) +{ + int i,fd; + ScrnInfoPtr pScrn; + GDevPtr *devSections; + int numDevSections; + char *dev; + Bool foundScreen = FALSE; + +#ifdef DEBUG + ErrorF("FBDevProbe\n"); +#endif + + if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + for (i = 0; i < numDevSections; i++) { + dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); + if (-1 != (fd = fbdev_open(dev))) { + close(fd); + pScrn = xf86AllocateScreen(drv, 0); + + pScrn->driverVersion = VERSION; + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + pScrn->Probe = FBDevProbe; + pScrn->PreInit = FBDevPreInit; + pScrn->ScreenInit = FBDevScreenInit; + pScrn->SwitchMode = FBDevSwitchMode; + pScrn->AdjustFrame = FBDevAdjustFrame; + pScrn->EnterVT = FBDevEnterVT; + pScrn->LeaveVT = FBDevLeaveVT; + pScrn->ValidMode = FBDevValidMode; + pScrn->device = devSections[i]; + + foundScreen = TRUE; + } + } + xfree(devSections); + return foundScreen; +} + +static Bool +FBDevPreInit(ScrnInfoPtr pScrn, int flags) +{ + FBDevPtr fPtr; + struct fb_var_screeninfo var; + char *mod = NULL; + const char *reqSym = NULL; + int depth; + Gamma zeros = {0.0, 0.0, 0.0}; + +#ifdef DEBUG + ErrorF("FBDevPreInit %d\n",pScrn->scrnIndex); +#endif + pScrn->monitor = pScrn->confScreen->monitor; + + FBDevGetRec(pScrn); + fPtr = FBDEVPTR(pScrn); + + /* opem device */ + fPtr->device = xf86FindOptionValue(pScrn->device->options,"fbdev"); + if (-1 == (fPtr->fd = fbdev_open(fPtr->device))) + return FALSE; + + /* get current fb device settings */ + if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_FSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_VSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + + /* copy current fb mode, using this for testing parameters */ + memcpy(&var,&fPtr->var,sizeof(var)); + + /* color depth */ + depth = var.bits_per_pixel; /* use current fbdev setting as default */ + if (!xf86SetDepthBpp(pScrn, depth, depth, depth, Support24bppFb | Support32bppFb)) + return FALSE; + var.activate = FB_ACTIVATE_TEST; + var.bits_per_pixel = pScrn->depth; + var.yres_virtual = var.yres; + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by framebuffer device\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + /* 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, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + + xf86SetGamma(pScrn,zeros); + + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + pScrn->chipset = "fbdev"; + pScrn->videoRam = fPtr->fix.smem_len; + + /* handle options */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->device->options, FBDevOptions); + if (xf86IsOptionSet(FBDevOptions, OPTION_NOACCEL)) { + fPtr->noAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } + if (xf86IsOptionSet(FBDevOptions, OPTION_SHADOW_FB)) { + fPtr->shadowFB = TRUE; + fPtr->noAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB enabled\n"); + } + + if (NULL != pScrn->display->modes) { + /* verify display modes */ + int virtX = pScrn->display->virtualX; + int virtY = pScrn->display->virtualY; + char **modename; + DisplayModePtr mode,this,last = NULL; + +#ifdef DEBUG + ErrorF("FBDevPreInit: check mode list\n"); +#endif + for (modename = pScrn->display->modes; *modename != NULL; modename++) { + ErrorF("\t%s... ",*modename); + for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next) + if (0 == strcmp(mode->name,*modename)) + break; + if (NULL == mode) { + ErrorF("not found\n"); + continue; + } + memset(&var,0,sizeof(var)); + xfree2fbdev_timing(mode,&var); + var.xres_virtual = virtX; + var.yres_virtual = virtY; + var.bits_per_pixel = pScrn->depth; + var.activate = FB_ACTIVATE_TEST; + if (var.xres_virtual < var.xres) var.xres_virtual = var.xres; + if (var.yres_virtual < var.yres) var.yres_virtual = var.yres; + if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) { + ErrorF("failed\n"); + continue; + } + ErrorF("passed\n"); + if (virtX < var.xres) virtX = var.xres; + if (virtY < var.yres) virtY = var.yres; + if (NULL == pScrn->modes) { + pScrn->modes = xnfalloc(sizeof(DisplayModeRec)); + this = pScrn->modes; + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = this; + this->prev = this; + } else { + this = xnfalloc(sizeof(DisplayModeRec)); + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = pScrn->modes; + this->prev = last; + last->next = this; + pScrn->modes->prev = this; + } + last = this; + } + pScrn->virtualX = virtX; + pScrn->virtualY = virtY; + } + if (pScrn->modes == NULL) { + /* no valid mode? use the current fb settings as buildin mode */ + fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); +#if DEBUG + print_fbdev_mode("current",&fPtr->var); + print_xfree_mode("current",&fPtr->buildin); +#endif + fPtr->buildin.name = "current"; + fPtr->buildin.next = &fPtr->buildin; + fPtr->buildin.prev = &fPtr->buildin; + fPtr->buildin.type |= M_T_BUILTIN; + pScrn->modes = &fPtr->buildin; + pScrn->virtualX = pScrn->display->virtualX; + pScrn->virtualY = pScrn->display->virtualY; + if (pScrn->virtualX < fPtr->var.xres) + pScrn->virtualX = fPtr->var.xres; + if (pScrn->virtualY < fPtr->var.yres) + pScrn->virtualY = fPtr->var.yres; + } + pScrn->currentMode = pScrn->modes; + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) + { + case 8: + mod = "cfb"; + reqSym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSym = "cfb16ScreenInit"; + break; + case 24: + mod = "cfb24"; + reqSym = "cfb24ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSym = "cfb32ScreenInit"; + break; + } + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols(reqSym, NULL); + + /* Load shadowFB if needed */ + if (fPtr->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("ShadowFBInit", NULL); + } + + /* TODO: acceleration */ + +#ifdef DEBUG + ErrorF("FBDevPreInit done\n"); +#endif + return TRUE; +} + +static Bool +FBDevMap(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevMap %d\n",pScrn->scrnIndex); +#endif +#if 0 /* FIXME: there is no wrapper for mmap() */ + if (NULL == fPtr->fbmem) { + fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, 0); + if (-1 == (int)fPtr->fbmem) { + perror("mmap fbmem"); + fPtr->fbmem = NULL; + return FALSE; + } + } + if (NULL == fPtr->mmio && fPtr->need_mmio) { + fPtr->mmio = mmap(NULL, fPtr->fix.mmio_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, fPtr->fix.smem_len); + if (-1 == (int)fPtr->fbmem) { + perror("mmap mmio"); + fPtr->mmio = NULL; + return FALSE; + } + } +#else + if (NULL == fPtr->fbmem) { + fPtr->fbmem = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + (pointer)(fPtr->fix.smem_start), fPtr->fix.smem_len); + } +#endif + return TRUE; +} + +static Bool +FBDevUnmap(ScrnInfoPtr pScrn) +{ +#if 0 + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevUnmap %d\n",pScrn->scrnIndex); +#endif + if (NULL != fPtr->fbmem) { + munmap(fPtr->fbmem, fPtr->fix.smem_len); + fPtr->fbmem = NULL; + } + if (NULL != fPtr->mmio) { + munmap(fPtr->mmio, fPtr->fix.mmio_len); + fPtr->mmio = NULL; + } +#endif + return TRUE; +} + +static Bool +FBDevModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + + xfree2fbdev_fblayout(pScrn, &fPtr->var); + xfree2fbdev_timing(mode, &fPtr->var); +#if DEBUG + print_xfree_mode("init",mode); + print_fbdev_mode("init",&fPtr->var); +#endif + pScrn->vtSema = TRUE; + + /* set */ + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + /* read back */ + if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + perror("FBIOGET_FSCREENINFO"); + return FALSE; + } + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOGET_VSCREENINFO"); + return FALSE; + } + return TRUE; +} + +static void +FBDevLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, short visualClass) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + struct fb_cmap cmap; + unsigned short red,green,blue; + int i; + +#ifdef DEBUG + ErrorF("FBDevLoadPalette\n"); +#endif + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + for (i = 0; i < numColors; i++) { + cmap.start = indices[i]; + red = colors[indices[i]].red << 8; + green = colors[indices[i]].green << 8; + blue = colors[indices[i]].blue << 8; + if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap)) + perror("ioctl FBIOPUTCMAP"); + } +} + +/* for ShadowFB */ +static void +FBDevRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = pScrn->displayWidth * Bpp; + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = fPtr->shadowmem + (pbox->y1 * fPtr->shadowPitch) + + (pbox->x1 * Bpp); + dst = fPtr->fbmem + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += fPtr->shadowPitch; + } + pbox++; + } +} + +static Bool +FBDevSaveScreen(ScreenPtr pScreen, Bool unblank) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSaveScreen unblank=%s vtSema=%d\n", + unblank ? "true" : "false", + pScrn->vtSema); +#endif + /* not implemented yet */ + return TRUE; +} + +static void FBDevSave(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSave %d\n",pScrn->scrnIndex); +#endif + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var_saved))) + perror("FBIOGET_VSCREENINFO"); +} + +static void FBDevRestore(ScrnInfoPtr pScrn) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevRestore %d\n",pScrn->scrnIndex); +#endif + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var_saved))) + perror("FBIOPUT_VSCREENINFO"); +} + +static Bool +FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + VisualPtr visual; + int ret,flags; + +#ifdef DEBUG + ErrorF("FBDevScreenInit %d\n",pScrn->scrnIndex); + 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 (!FBDevMap(pScrn)) + return FALSE; + + FBDevSave(pScrn); + + if (!FBDevModeInit(pScrn, pScrn->currentMode)) + return FALSE; + FBDevAdjustFrame(scrnIndex,0,0,0); + + /* mi layer */ + miClearVisualTypes(); + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + /* shadowfb */ + if (fPtr->shadowFB) { + fPtr->shadowPitch = + ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L; + fPtr->shadowmem = xalloc(fPtr->shadowPitch * pScrn->virtualY); + fPtr->fbstart = fPtr->shadowmem; + } else { + fPtr->shadowmem = NULL; + fPtr->fbstart = fPtr->fbmem; + } + + switch (pScrn->bitsPerPixel) { + case 8: + ret = cfbScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 16: + ret = cfb16ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 24: + ret = cfb24ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 32: + ret = cfb32ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in FBDevScreenInit\n", + pScrn->bitsPerPixel); + 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; + } + } + } + + xf86SetBlackWhitePixels(pScreen); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if(fPtr->shadowFB) + ShadowFBInit(pScreen, FBDevRefreshArea); + + /* colormap */ + switch (pScrn->depth) { +#if 0 + case 1: + if (!xf1bppCreateDefColormap(pScreen)) + return FALSE; + break; + case 4: + if (!xf4bppCreateDefColormap(pScreen)) + return FALSE; + break; +#endif + default: + if (!cfbCreateDefColormap(pScreen)) + return FALSE; + break; + } + + flags = 0; /* CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) */ + if (fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR) + flags = CMAP_PALETTED_TRUECOLOR; + if(!xf86HandleColormaps(pScreen, 256, 8, FBDevLoadPalette, NULL, flags)) + return FALSE; + + pScreen->SaveScreen = FBDevSaveScreen; + + /* Wrap the current CloseScreen function */ + fPtr->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = FBDevCloseScreen; +#ifdef DEBUG + ErrorF("FBDevScreenInit done\n",pScrn->scrnIndex); +#endif + return TRUE; +} + +static void +FBDevAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevAdjustFrame +%d+%d\n",x,y); +#endif + fPtr->var.xoffset = x; + fPtr->var.yoffset = y; + if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var)) + perror("ioctl FBIOPAN_DISPLAY"); +} + +static int +FBDevValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + struct fb_var_screeninfo var; + +#ifdef DEBUG + ErrorF("FBDevValidMode %d %s\n",pScrn->scrnIndex,mode->name); +#endif + memcpy(&var,&fPtr->var,sizeof(var)); + xfree2fbdev_timing(mode, &var); + var.activate = FB_ACTIVATE_TEST; + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return MODE_BAD; + } + return MODE_OK; +} + +static Bool +FBDevSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + +#ifdef DEBUG + ErrorF("FBDevSwitchMode %d %s\n",pScrn->scrnIndex,mode->name); +#endif + xfree2fbdev_timing(mode, &fPtr->var); + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + return TRUE; +} + +static Bool +FBDevEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + +#ifdef DEBUG + ErrorF("FBDevEnterVT %d flags=%d\n",scrnIndex,flags); +#endif + if (!FBDevModeInit(pScrn, pScrn->currentMode)) + return FALSE; + FBDevAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +static void +FBDevLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + +#ifdef DEBUG + ErrorF("FBDevLeaveVT %d flags=%d\n",scrnIndex,flags); +#endif + FBDevRestore(pScrn); +} + +static Bool +FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + FBDevRestore(pScrn); + FBDevUnmap(pScrn); + close(fPtr->fd); + if (fPtr->shadowmem) + xfree(fPtr->shadowmem); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = fPtr->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} diff -urN 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c --- 3.9Pb/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c Fri Feb 26 00:05:32 1999 @@ -0,0 +1,557 @@ +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +#include "mipointer.h" +#include "mibstore.h" +#include "micmap.h" +#include "colormapst.h" +#include "xf86cmap.h" +#include "shadowfb.h" + +/* for visuals */ +#define PSZ 8 +#include "cfb.h" +#undef PSZ +#include "cfb16.h" +#include "cfb24.h" +#include "cfb32.h" + +#include "fbdevhw.h" +#include "linux/fb.h" + +#define DEBUG 1 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("fbdev: " str " %d\n",pScrn->scrnIndex) +# define TRACE_EXIT(str) ErrorF("fbdev: " str " done\n") +# define TRACE(str) ErrorF("fbdev trace: " str "\n") +#else +# define TRACE_ENTER(str) +# define TRACE_EXIT(str) +#endif + +/* -------------------------------------------------------------------- */ +/* prototypes */ + +/* Mandatory functions */ +static void FBDevIdentify(int flags); +static Bool FBDevProbe(DriverPtr drv, int flags); +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 Bool FBDevSaveScreen(ScreenPtr pScreen, Bool unblank); + +/* -------------------------------------------------------------------- */ + +#define VERSION 4000 +#define FBDEV_NAME "FBDev" +#define FBDEV_DRIVER_NAME "fbdev" +#define FBDEV_MAJOR_VERSION 0 +#define FBDEV_MINOR_VERSION 1 + +DriverRec FBDEV = { + VERSION, + "driver for linux framebuffer devices", + FBDevIdentify, + FBDevProbe, + NULL, + 0 +}; + +/* Supported "chipsets" */ +static SymTabRec FBDevChipsets[] = { + { 0, "cfb8" }, + { 0, "cfb16" }, + { 0, "cfb24" }, + { 0, "cfb32" }, + {-1, NULL } +}; + +/* Supported options */ +typedef enum { + OPTION_SHADOW_FB, + OPTION_FBDEV +} FBDevOpts; + +static OptionInfoRec FBDevOptions[] = { + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +/* -------------------------------------------------------------------- */ + +static const char *cfbSymbols[] = { + "cfbScreenInit", + "cfb16ScreenInit", + "cfb24ScreenInit", + "cfb32ScreenInit", + NULL +}; + +static const char *shadowSymbols[] = { + "ShadowFBInit", + NULL +}; + +static const char *fbdevHWSymbols[] = { + "fbdevHWProbe", + "fbdevHWInit", + "fbdevHWUseBuildinMode", + + /* colormap */ + "fbdevHWLoadpalette", + + /* ScrnInfo hooks */ + "fbdevHWSwitchMode", + "fbdevHWAdjustFrame", + "fbdevHWEnterVT", + "fbdevHWLeaveVT", + "fbdevHWValidMode", + NULL +}; + +#ifdef XFree86LOADER + +MODULESETUPPROTO(FBDevSetup); + +static XF86ModuleVersionInfo FBDevVersRec = +{ + "fbdev", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + FBDEV_MAJOR_VERSION, FBDEV_MINOR_VERSION, 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + NULL, + {0,0,0,0} +}; + +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, 0); + LoaderRefSymLists(cfbSymbols, shadowSymbols, NULL); + return (pointer)1; + } else { + if (errmaj) *errmaj = LDR_ONCEONLY; + return NULL; + } +} + +#else /* XFree86LOADER */ + +#include +#include + +#endif /* XFree86LOADER */ + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +typedef struct { + unsigned char* fbstart; + unsigned char* fbmem; + unsigned char* shadowmem; + int shadowPitch; + Bool shadowFB; + CloseScreenProcPtr CloseScreen; +} 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 void +FBDevIdentify(int flags) +{ + xf86PrintChipsets(FBDEV_NAME, "driver for linux framebuffer", FBDevChipsets); +} + +static Bool +FBDevProbe(DriverPtr drv, int flags) +{ + static char *baseModules[] = { "fbdevhw", NULL }; + int i,fd; + ScrnInfoPtr pScrn; + GDevPtr *devSections; + int numDevSections; + char *dev; + Bool foundScreen = FALSE; + +#ifdef DEBUG + ErrorF("FBDevProbe\n"); +#endif + +#if 0 + xf86LoadModules(baseModules, NULL); + TRACE("loaded #1"); +#endif + xf86LoaderReqSymLists(fbdevHWSymbols, NULL); + TRACE("loaded #2"); + + if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) + return FALSE; + + for (i = 0; i < numDevSections; i++) { + dev = xf86FindOptionValue(devSections[i]->options,"fbdev"); + if (-1 != (fd = fbdevHWProbe(NULL,dev))) { + pScrn = xf86AllocateScreen(drv, 0); + + pScrn->driverVersion = VERSION; + pScrn->driverName = FBDEV_DRIVER_NAME; + pScrn->name = FBDEV_NAME; + pScrn->Probe = FBDevProbe; + pScrn->PreInit = FBDevPreInit; + pScrn->ScreenInit = FBDevScreenInit; + pScrn->SwitchMode = fbdevHWSwitchMode; + pScrn->AdjustFrame = fbdevHWAdjustFrame; + pScrn->EnterVT = fbdevHWEnterVT; + pScrn->LeaveVT = fbdevHWLeaveVT; + pScrn->ValidMode = fbdevHWValidMode; + pScrn->device = devSections[i]; + + foundScreen = TRUE; + } + } + xfree(devSections); + return foundScreen; +} + +static Bool +FBDevPreInit(ScrnInfoPtr pScrn, int flags) +{ + FBDevPtr fPtr; + char *mod = NULL; + const char *reqSym = NULL; + Gamma zeros = {0.0, 0.0, 0.0}; + + TRACE_ENTER("PreInit"); + + pScrn->monitor = pScrn->confScreen->monitor; + + FBDevGetRec(pScrn); + fPtr = FBDEVPTR(pScrn); + + /* open device */ + if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(pScrn->device->options,"fbdev"))) + return FALSE; + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb)) + return FALSE; + xf86PrintDepthBpp(pScrn); + + /* 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, "Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); + return FALSE; + } + + xf86SetGamma(pScrn,zeros); + + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + pScrn->chipset = "fbdev"; + pScrn->videoRam = 4096*1024 /* FIXME */; + + /* handle options */ + xf86CollectOptions(pScrn, NULL); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->device->options, FBDevOptions); + if (xf86IsOptionSet(FBDevOptions, OPTION_SHADOW_FB)) { + fPtr->shadowFB = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB enabled\n"); + } + + fbdevHWUseBuildinMode(pScrn); +#if 0 + pScrn->currentMode = pScrn->modes; + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ +#endif + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load bpp-specific modules */ + switch (pScrn->bitsPerPixel) + { + case 8: + mod = "cfb"; + reqSym = "cfbScreenInit"; + break; + case 16: + mod = "cfb16"; + reqSym = "cfb16ScreenInit"; + break; + case 24: + mod = "cfb24"; + reqSym = "cfb24ScreenInit"; + break; + case 32: + mod = "cfb32"; + reqSym = "cfb32ScreenInit"; + break; + } + if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols(reqSym, NULL); + + /* Load shadowFB if needed */ + if (fPtr->shadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + FBDevFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymbols("ShadowFBInit", NULL); + } + + TRACE_EXIT("PreInit"); + return TRUE; +} + +/* for ShadowFB */ +static void +FBDevRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + FBDevPtr fPtr = FBDEVPTR(pScrn); + int width, height, Bpp, FBPitch; + unsigned char *src, *dst; + + Bpp = pScrn->bitsPerPixel >> 3; + FBPitch = pScrn->displayWidth * Bpp; + + while(num--) { + width = (pbox->x2 - pbox->x1) * Bpp; + height = pbox->y2 - pbox->y1; + src = fPtr->shadowmem + (pbox->y1 * fPtr->shadowPitch) + + (pbox->x1 * Bpp); + dst = fPtr->fbmem + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp); + + while(height--) { + memcpy(dst, src, width); + dst += FBPitch; + src += fPtr->shadowPitch; + } + pbox++; + } +} + +static Bool +FBDevSaveScreen(ScreenPtr pScreen, Bool unblank) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + +#ifdef DEBUG + ErrorF("FBDevSaveScreen unblank=%s vtSema=%d\n", + unblank ? "true" : "false", + pScrn->vtSema); +#endif + /* not implemented yet */ + 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 ret,flags; + + TRACE_ENTER("FBDevScreenInit"); +#ifdef 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))) + return FALSE; + + fbdevHWSave(pScrn); + + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) + return FALSE; + fbdevHWAdjustFrame(scrnIndex,0,0,0); + + /* mi layer */ + miClearVisualTypes(); + if (pScrn->bitsPerPixel > 8) { + if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor)) + return FALSE; + } else { + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + } + + /* shadowfb */ + if (fPtr->shadowFB) { + fPtr->shadowPitch = + ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L; + fPtr->shadowmem = xalloc(fPtr->shadowPitch * pScrn->virtualY); + fPtr->fbstart = fPtr->shadowmem; + } else { + fPtr->shadowmem = NULL; + fPtr->fbstart = fPtr->fbmem; + } + + switch (pScrn->bitsPerPixel) { + case 8: + ret = cfbScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 16: + ret = cfb16ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 24: + ret = cfb24ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + case 32: + ret = cfb32ScreenInit + (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in FBDevScreenInit\n", + pScrn->bitsPerPixel); + 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; + } + } + } + + xf86SetBlackWhitePixels(pScreen); + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + + /* software cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + if(fPtr->shadowFB) + ShadowFBInit(pScreen, FBDevRefreshArea); + + /* colormap */ + switch (pScrn->depth) { +#if 0 + case 1: + if (!xf1bppCreateDefColormap(pScreen)) + return FALSE; + break; + case 4: + if (!xf4bppCreateDefColormap(pScreen)) + return FALSE; + break; +#endif + default: + if (!cfbCreateDefColormap(pScreen)) + return FALSE; + break; + } + +#if 0 /* FIXME */ + flags = 0; /* CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) */ + if (fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR) + flags = CMAP_PALETTED_TRUECOLOR; +#else + flags = CMAP_PALETTED_TRUECOLOR; +#endif + if(!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPalette, NULL, flags)) + return FALSE; + + pScreen->SaveScreen = FBDevSaveScreen; + + /* Wrap the current CloseScreen function */ + fPtr->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = FBDevCloseScreen; +#ifdef DEBUG + ErrorF("FBDevScreenInit done\n",pScrn->scrnIndex); +#endif + return TRUE; +} + +static Bool +FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + FBDevPtr fPtr = FBDEVPTR(pScrn); + + fbdevHWRestore(pScrn); + fbdevHWUnmapVidmem(pScrn); + if (fPtr->shadowmem) + xfree(fPtr->shadowmem); + pScrn->vtSema = FALSE; + + pScreen->CloseScreen = fPtr->CloseScreen; + return (*pScreen->CloseScreen)(scrnIndex, pScreen); +} diff -urN 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/Imakefile xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile --- 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/Imakefile Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile Sun Feb 21 20:19:33 1999 @@ -0,0 +1,26 @@ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/Imakefile,v 1.7 1999/01/03 03:58:49 dawes Exp $ + +#define IHaveModules +#include + +SRCS = fbdevhw.c +OBJS = fbdevhw.o + + INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/include -I$(XINCLUDESRC) \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c + + LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/llib-los.ln \ + ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln + +ModuleObjectRule() +LibraryModuleTarget(fbdevhw,$(OBJS)) +NormalLintTarget($(SRCS)) +InstallLinkKitNonExecFile(fbdevhw.c,$(LINKKITDIR)/VGADriverDoc) +InstallLibraryModule(fbdevhw,$(MODULEDIR),.) + +#ifndef OS2Architecture +DependTarget() +#endif + diff -urN 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c --- 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c Thu Feb 25 23:54:35 1999 @@ -0,0 +1,672 @@ + +/* all driver need this */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +/* pci stuff */ +#include "xf86PciInfo.h" +#include "xf86Pci.h" + +#include "xf86cmap.h" + +#include "fbdevhw.h" +#include "linux/fb.h" + +#define DEBUG 1 + +#if DEBUG +# define TRACE_ENTER(str) ErrorF("fbdevHW: " str " %d\n",pScrn->scrnIndex) +#else +# define TRACE_ENTER(str) +#endif + +/* -------------------------------------------------------------------- */ + +#ifdef XFree86LOADER + +static XF86ModuleVersionInfo fbdevHWVersRec = +{ + "fbdevhw", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + 0, 0, 1, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + {0,0,0,0} +}; + +XF86ModuleData fbdevModuleData = { &fbdevHWVersRec, NULL, NULL }; + +#else /* XFree86LOADER */ + +#include +#include + +#endif /* XFree86LOADER */ + +/* -------------------------------------------------------------------- */ +/* our private data, and two functions to allocate/free this */ + +#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr +#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p))) + +static int fbdevHWPrivateIndex = -1; + +typedef struct { + /* framebuffer device: filename (/dev/fb*), handle, more */ + char* device; + int fd; + void* fbmem; + void* mmio; + + /* current hardware state */ + struct fb_fix_screeninfo fix; + struct fb_var_screeninfo var; + + /* saved video mode */ + struct fb_var_screeninfo saved_var; + struct fb_cmap saved_cmap; + unsigned short *saved_red; + unsigned short *saved_green; + unsigned short *saved_blue; + + /* buildin video mode */ + DisplayModeRec buildin; + +} fbdevHWRec, *fbdevHWPtr; + +Bool +fbdevHWGetRec(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr; + + if (fbdevHWPrivateIndex < 0) + fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex(); + + if (FBDEVHWPTR(pScrn) != NULL) + return TRUE; + + fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1); + return TRUE; +} + +void +fbdevHWFreeRec(ScrnInfoPtr pScrn) +{ + if (fbdevHWPrivateIndex < 0) + return; + if (FBDEVHWPTR(pScrn) == NULL) + return; + xfree(FBDEVHWPTR(pScrn)); + FBDEVHWPTRLVAL(pScrn) = NULL; +} + +/* -------------------------------------------------------------------- */ +/* some helpers for printing debug informations */ + +static void print_fbdev_mode(char *txt, struct fb_var_screeninfo *var) +{ + ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n", + txt,var->pixclock, + var->xres, var->right_margin, var->hsync_len, var->left_margin, + var->yres, var->lower_margin, var->vsync_len, var->upper_margin, + var->bits_per_pixel, + var->red.length, var->green.length, var->blue.length); +} + +static void print_xfree_mode(char *txt, DisplayModePtr mode) +{ + ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n", + txt,mode->Clock, + mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal, + mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal); +} + +/* -------------------------------------------------------------------- */ +/* Convert timings between the XFree and the Frame Buffer Device */ + +static void xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var) +{ + var->xres_virtual = pScrn->virtualX; + var->yres_virtual = pScrn->virtualY; + var->bits_per_pixel = pScrn->bitsPerPixel; + var->red.length = 0; + var->red.offset = 0; + var->green.length = 0; + var->green.offset = 0; + var->blue.length = 0; + var->blue.offset = 0; +} + +static void xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var) +{ + var->xres = mode->HDisplay; + var->yres = mode->VDisplay; + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + var->xoffset = var->yoffset = 0; + var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0; + var->right_margin = mode->HSyncStart-mode->HDisplay; + var->hsync_len = mode->HSyncEnd-mode->HSyncStart; + var->left_margin = mode->HTotal-mode->HSyncEnd; + var->lower_margin = mode->VSyncStart-mode->VDisplay; + var->vsync_len = mode->VSyncEnd-mode->VSyncStart; + var->upper_margin = mode->VTotal-mode->VSyncEnd; + var->sync = 0; + if (mode->Flags & V_PHSYNC) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (mode->Flags & V_PVSYNC) + var->sync |= FB_SYNC_VERT_HIGH_ACT; + if (mode->Flags & V_PCSYNC) + var->sync |= FB_SYNC_COMP_HIGH_ACT; +#if 0 + if (mode->Flags & V_BCAST) + var->sync |= FB_SYNC_BROADCAST; +#endif + if (mode->Flags & V_INTERLACE) + var->vmode = FB_VMODE_INTERLACED; + else if (mode->Flags & V_DBLSCAN) + var->vmode = FB_VMODE_DOUBLE; + else + var->vmode = FB_VMODE_NONINTERLACED; +} + +static void fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode) +{ + mode->Clock = var->pixclock ? 1000000000/var->pixclock : 28000000; + mode->HDisplay = var->xres; + mode->HSyncStart = mode->HDisplay+var->right_margin; + mode->HSyncEnd = mode->HSyncStart+var->hsync_len; + mode->HTotal = mode->HSyncEnd+var->left_margin; + mode->VDisplay = var->yres; + mode->VSyncStart = mode->VDisplay+var->lower_margin; + mode->VSyncEnd = mode->VSyncStart+var->vsync_len; + mode->VTotal = mode->VSyncEnd+var->upper_margin; + mode->Flags = 0; + mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC; + mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC; + mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC; +#if 0 + if (var->sync & FB_SYNC_BROADCAST) + mode->Flags |= V_BCAST; +#endif + if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) + mode->Flags |= V_INTERLACE; + else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) + mode->Flags |= V_DBLSCAN; + mode->SynthClock = mode->Clock; + mode->CrtcHDisplay = mode->HDisplay; + mode->CrtcHSyncStart = mode->HSyncStart; + mode->CrtcHSyncEnd = mode->HSyncEnd; + mode->CrtcHTotal = mode->HTotal; + mode->CrtcVDisplay = mode->VDisplay; + mode->CrtcVSyncStart = mode->VSyncStart; + mode->CrtcVSyncEnd = mode->VSyncEnd; + mode->CrtcVTotal = mode->VTotal; + mode->CrtcHAdjusted = FALSE; + mode->CrtcVAdjusted = FALSE; +} + + +/* -------------------------------------------------------------------- */ +/* open correct framebuffer device */ + +static struct fb2pci_entry { + CARD32 id; + CARD32 vendor; + CARD32 chip; +} fb2pci_map[] = { + { FB_ACCEL_MATROX_MGA2064W, PCI_VENDOR_MATROX, PCI_CHIP_MGA2064 }, + { FB_ACCEL_MATROX_MGA1064SG, PCI_VENDOR_MATROX, PCI_CHIP_MGA1064 }, + { FB_ACCEL_MATROX_MGA2164W, PCI_VENDOR_MATROX, PCI_CHIP_MGA2164 }, + { FB_ACCEL_MATROX_MGA2164W_AGP, PCI_VENDOR_MATROX, PCI_CHIP_MGA2164_AGP }, + { FB_ACCEL_MATROX_MGAG100, PCI_VENDOR_MATROX, PCI_CHIP_MGAG100 }, + { FB_ACCEL_MATROX_MGAG200, PCI_VENDOR_MATROX, PCI_CHIP_MGAG200 }, +}; +#define FB2PCICOUNT (sizeof(fb2pci_map)/sizeof(struct fb2pci_entry)) + +/* try to find the framebuffer device for a given PCI device */ +static int +fbdev_open_pci(pciVideoPtr pPci) +{ + struct fb_fix_screeninfo fix; + char filename[16]; + int fd,i,j; + + for (i = 0; i < 4; i++) { + sprintf(filename,"/dev/fb%d",i); + if (-1 == (fd = open(filename,O_RDWR,0))) + continue; + if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) { + close(fd); + continue; + } + /* FIXME: better ask the fbdev driver for bus/device/func */ + for (j = 0; j < FB2PCICOUNT; j++) { + if (pPci->vendor == fb2pci_map[j].vendor && + pPci->chipType == fb2pci_map[j].chip) + break; + } + if (j == FB2PCICOUNT) { + close(fd); + continue; + } + return fd; + } + return -1; +} + +static int +fbdev_open(char *dev) +{ + struct fb_con2fbmap c2m; + char fbdev[16]; + int fd; + + /* try argument (from XF86Config) first */ + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* second: environment variable */ + dev = getenv("FRAMEBUFFER"); + if (NULL != dev) + return open(dev,O_RDWR,0); + + /* open the first one */ + if (-1 == (fd = open("/dev/fb0",O_RDWR,0))) + return -1; + +#if 1 + /* FIXME: xf86Info is'nt available for drivers :-( */ + return fd; +#else + /* check which fb device the vt is mapped to */ + c2m.console = xf86Info.vtno; + if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) { + perror("ioctl FBIOGET_CON2FBMAP"); + return fd; + } +#if DEBUG + ErrorF("fbdev_open: vt%02d => fb%d\n",c2m.console,c2m.framebuffer); +#endif + if (c2m.framebuffer != 0) { + /* it is'nt the first, open the correct one */ + sprintf(fbdev,"/dev/fb%d\n",c2m.framebuffer); + close(fd); + fd = open(fbdev,O_RDWR,0); + } + return fd; +#endif +} + +/* -------------------------------------------------------------------- */ + +Bool +fbdevHWProbe(pciVideoPtr pPci, char *device) +{ + int fd; + + if (pPci) + fd = fbdev_open_pci(pPci); + else + fd = fbdev_open(NULL); + + if (-1 == fd) + return FALSE; + close(fd); + return TRUE; +} + +Bool +fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device) +{ + fbdevHWPtr fPtr; + + TRACE_ENTER("Init"); + + fbdevHWGetRec(pScrn); + fPtr = FBDEVHWPTR(pScrn); + + /* open device */ + if (pPci) + fPtr->fd = fbdev_open_pci(pPci); + else + fPtr->fd = fbdev_open(device); + if (-1 == fPtr->fd) + return FALSE; + + /* get current fb device settings */ + if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_FSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "ioctl FBIOGET_VSCREENINFO: %s\n", + strerror(errno)); + return FALSE; + } + return TRUE; +} + + +#if 0 +fbdevHW_verify_all_display_modes() +{ + if (NULL != pScrn->display->modes) { + /* verify display modes */ + int virtX = pScrn->display->virtualX; + int virtY = pScrn->display->virtualY; + char **modename; + DisplayModePtr mode,this,last = NULL; + +#ifdef DEBUG + ErrorF("FBDevPreInit: check mode list\n"); +#endif + for (modename = pScrn->display->modes; *modename != NULL; modename++) { + ErrorF("\t%s... ",*modename); + for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next) + if (0 == strcmp(mode->name,*modename)) + break; + if (NULL == mode) { + ErrorF("not found\n"); + continue; + } + memset(&var,0,sizeof(var)); + xfree2fbdev_timing(mode,&var); + var.xres_virtual = virtX; + var.yres_virtual = virtY; + var.bits_per_pixel = pScrn->depth; + var.activate = FB_ACTIVATE_TEST; + if (var.xres_virtual < var.xres) var.xres_virtual = var.xres; + if (var.yres_virtual < var.yres) var.yres_virtual = var.yres; + if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) { + ErrorF("failed\n"); + continue; + } + ErrorF("passed\n"); + if (virtX < var.xres) virtX = var.xres; + if (virtY < var.yres) virtY = var.yres; + if (NULL == pScrn->modes) { + pScrn->modes = xnfalloc(sizeof(DisplayModeRec)); + this = pScrn->modes; + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = this; + this->prev = this; + } else { + this = xnfalloc(sizeof(DisplayModeRec)); + memcpy(this,mode,sizeof(DisplayModeRec)); + this->next = pScrn->modes; + this->prev = last; + last->next = this; + pScrn->modes->prev = this; + } + last = this; + } + pScrn->virtualX = virtX; + pScrn->virtualY = virtY; + } +} +#endif + +void +fbdevHWUseBuildinMode(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("UseBuildinMode"); + fbdev2xfree_timing(&fPtr->var, &fPtr->buildin); +#if DEBUG + print_fbdev_mode("current",&fPtr->var); + print_xfree_mode("current",&fPtr->buildin); +#endif + fPtr->buildin.name = "current"; + fPtr->buildin.next = &fPtr->buildin; + fPtr->buildin.prev = &fPtr->buildin; + fPtr->buildin.type |= M_T_BUILTIN; + pScrn->modes = &fPtr->buildin; + pScrn->virtualX = pScrn->display->virtualX; + pScrn->virtualY = pScrn->display->virtualY; + if (pScrn->virtualX < fPtr->var.xres) + pScrn->virtualX = fPtr->var.xres; + if (pScrn->virtualY < fPtr->var.yres) + pScrn->virtualY = fPtr->var.yres; + pScrn->currentMode = pScrn->modes; + pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */ +} + +/* -------------------------------------------------------------------- */ + +void* +fbdevHWMapVidmem(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("MapVidmem"); +#if 0 /* FIXME: there is no wrapper for mmap() */ + if (NULL == fPtr->fbmem) { + fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, 0); + if (-1 == (int)fPtr->fbmem) { + perror("mmap fbmem"); + fPtr->fbmem = NULL; + } + } +#else + if (NULL == fPtr->fbmem) { + fPtr->fbmem = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, + (pointer)(fPtr->fix.smem_start), fPtr->fix.smem_len); + } +#endif + return fPtr->fbmem; +} + +Bool +fbdevHWUnmapVidmem(ScrnInfoPtr pScrn) +{ +#if 0 + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("UnmapVidmem"); + if (NULL != fPtr->fbmem) { + munmap(fPtr->fbmem, fPtr->fix.smem_len); + fPtr->fbmem = NULL; + } +#endif + return TRUE; +} + +void* +fbdevHWMapMMIO(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("MapMMIO"); +#if 0 /* FIXME: there is no wrapper for mmap() */ + if (NULL == fPtr->mmio) { + fPtr->mmio = mmap(NULL, fPtr->fix.mmio_len, PROT_READ | PROT_WRITE, + MAP_SHARED, fPtr->fd, fPtr->fix.smem_len); + if (-1 == (int)fPtr->fbmem) { + perror("mmap mmio"); + fPtr->mmio = NULL; + } + } +#endif + return fPtr->mmio; +} + +Bool +fbdevHWUnmapMMIO(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("UnmapMMIO"); +#if 0 + if (NULL != fPtr->mmio) { + munmap(fPtr->mmio, fPtr->fix.mmio_len); + fPtr->mmio = NULL; + } +#endif + return TRUE; +} + +/* -------------------------------------------------------------------- */ + +Bool +fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("ModeInit"); + xfree2fbdev_fblayout(pScrn, &fPtr->var); + xfree2fbdev_timing(mode, &fPtr->var); +#if DEBUG + print_xfree_mode("init",mode); + print_fbdev_mode("init",&fPtr->var); +#endif + pScrn->vtSema = TRUE; + + /* set */ + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + /* read back */ + if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) { + perror("FBIOGET_FSCREENINFO"); + return FALSE; + } + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOGET_VSCREENINFO"); + return FALSE; + } + return TRUE; +} + +/* -------------------------------------------------------------------- */ +/* video mode save/restore */ + +/* TODO: colormap */ +void fbdevHWSave(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("Save"); + if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var))) + perror("FBIOGET_VSCREENINFO"); +} + +void fbdevHWRestore(ScrnInfoPtr pScrn) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("Restore"); + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var))) + perror("FBIOPUT_VSCREENINFO"); +} + +/* -------------------------------------------------------------------- */ +/* callback for xf86HandleColormaps */ + +void +fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, short visualClass) +{ + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + struct fb_cmap cmap; + unsigned short red,green,blue; + int i; + + TRACE_ENTER("ModeInit"); + cmap.len = 1; + cmap.red = &red; + cmap.green = &green; + cmap.blue = &blue; + for (i = 0; i < numColors; i++) { + cmap.start = indices[i]; + red = colors[indices[i]].red << 8; + green = colors[indices[i]].green << 8; + blue = colors[indices[i]].blue << 8; + if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap)) + perror("ioctl FBIOPUTCMAP"); + } +} + +/* -------------------------------------------------------------------- */ +/* these can be hooked directly into ScrnInfoRec */ + +int +fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + struct fb_var_screeninfo var; + + TRACE_ENTER("ValidMode"); + memcpy(&var,&fPtr->var,sizeof(var)); + xfree2fbdev_timing(mode, &var); + var.activate = FB_ACTIVATE_TEST; + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return MODE_BAD; + } + return MODE_OK; +} + +Bool +fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("SwitchMode"); + xfree2fbdev_timing(mode, &fPtr->var); + if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + return TRUE; +} + +void +fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + fbdevHWPtr fPtr = FBDEVHWPTR(pScrn); + + TRACE_ENTER("AdjustFrame"); + fPtr->var.xoffset = x; + fPtr->var.yoffset = y; + if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var)) + perror("ioctl FBIOPAN_DISPLAY"); +} + +Bool +fbdevHWEnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + TRACE_ENTER("EnterVT"); + if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) + return FALSE; + fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + return TRUE; +} + +void +fbdevHWLeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + TRACE_ENTER("LeaveVT"); + fbdevHWRestore(pScrn); +} + diff -urN 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h --- 3.9Pb/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h Wed Feb 24 21:28:40 1999 @@ -0,0 +1,24 @@ +Bool fbdevHWGetRec(ScrnInfoPtr pScrn); +void fbdevHWFreeRec(ScrnInfoPtr pScrn); + +Bool fbdevHWProbe(pciVideoPtr pPci, char *device); +Bool fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device); + +void* fbdevHWMapVidmem(ScrnInfoPtr pScrn); +Bool fbdevHWUnmapVidmem(ScrnInfoPtr pScrn); +void* fbdevHWMapMMIO(ScrnInfoPtr pScrn); +Bool fbdevHWUnmapMMIO(ScrnInfoPtr pScrn); + +void fbdevHWUseBuildinMode(ScrnInfoPtr pScrn); +Bool fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +void fbdevHWSave(ScrnInfoPtr pScrn); +void fbdevHWRestore(ScrnInfoPtr pScrn); + +void fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO *colors, short visualClass); + +int fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); +Bool fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +void fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags); +Bool fbdevHWEnterVT(int scrnIndex, int flags); +void fbdevHWLeaveVT(int scrnIndex, int flags);