diff -urN -x compile-log -x xmakefile -x Makefile* 3.3.3/xc/config/cf/host.def xc/config/cf/host.def --- 3.3.3/xc/config/cf/host.def Thu Jan 1 01:00:00 1970 +++ xc/config/cf/host.def Mon Jan 11 21:46:09 1999 @@ -0,0 +1 @@ +#define BuildServersOnly YES diff -urN -x compile-log -x xmakefile -x Makefile* 3.3.3/xc/config/cf/xf86site.def xc/config/cf/xf86site.def --- 3.3.3/xc/config/cf/xf86site.def Sun Nov 8 12:19:11 1998 +++ xc/config/cf/xf86site.def Mon Jan 11 21:46:09 1999 @@ -163,13 +163,14 @@ * * The following servers are supported in Intel x86 platforms * -#define XF86SVGAServer NO -#define XF86VGA16Server NO + */ +#define XF86SVGAServer YES +#define XF86VGA16Server YES #define XF86VGA16DualServer NO #define XF86MonoServer NO #define XF86MonoDualServer NO #define XF86S3Server NO -#define XF86S3VServer NO +#define XF86S3VServer YES #define XF86I8514Server NO #define XF86Mach8Server NO #define XF86Mach32Server NO @@ -179,8 +180,7 @@ #define XF86W32Server NO #define XF86I128Server NO #define XF86GLINTServer NO -#define XF86FBDevServer NO - */ +#define XF86FBDevServer YES /* * Which servers do you wish to build, you can save a lot of disk space @@ -269,12 +269,12 @@ /* * SVGA server: * + */ #define XF86SvgaDrivers nv et4000 et3000 pvga1 gvga ati sis tvga8900 \ cirrus ncr77c22 compaq mga oak al2101 ali \ cl64xx video7 ark mx realtek apm \ s3v s3_svga neo chips cyrix rendition p9x00 \ - generic - */ + fbdev generic /* * VGA16 server: diff -urN -x compile-log -x xmakefile -x Makefile* 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/Imakefile xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/Imakefile --- 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/Imakefile Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/Imakefile Mon Jan 11 21:46:09 1999 @@ -0,0 +1,33 @@ +XCOMM $XConsortium: Imakefile /main/6 1996/09/28 17:29:26 rws $ + + + + + +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/et3000/Imakefile,v 3.6 1996/12/23 06:57:18 dawes Exp $ +#include + +SRCS = fbdev.c + +OBJS = fbdev.o + +#if XF86LinkKit +INCLUDES = -I. -I../../../include -I../../../include/X11 -I../.. +#else +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86HWSRC) -I$(XF86OSSRC) \ + -I../../vga -I$(SERVERSRC)/include -I$(XINCLUDESRC) +#endif + +#if MakeHasPosixVariableSubstitutions +SubdirLibraryRule($(OBJS)) +#endif +NormalLibraryObjectRule() +NormalAsmObjectRule() + +NormalRelocatableTarget(fbdev_drv,$(OBJS)) + +InstallLinkKitNonExecFile(fbdev.c,$(LINKKITDIR)/drivers/vga256/fbdev) +InstallLinkKitNonExecFile(Imakefile,$(LINKKITDIR)/drivers/vga256/fbdev) + +DependTarget() + diff -urN -x compile-log -x xmakefile -x Makefile* 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/README xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/README --- 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/README Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/README Mon Jan 11 21:46:09 1999 @@ -0,0 +1,42 @@ + +This is a "chipset" driver for linux framebuffer devices. + + +Configuration hints: +==================== + + * You don't have to specify any modelines. fbdev will use + the current video mode of the framebuffer device if there + is no (valid) modeline in the XF86Config file. This is + the easiest way to configure the X-Server for vesafb. + + * If the framebuffer device driver supports video mode + switching (like matroxfb does), fbdev will use this feature. + You can stick your own modelines into XF86Config, you can + switch resolutions on the fly (Ctrl+Alt+Keypad+/-) as usual. + + * fbdev is probed as very last driver (just before generic + vga). You might have to add fbdev as chipset to your device + section to overwrite the autoprobed chipset, like this: + +Section "Device" + Identifier "matrox" + VendorName "Matrox" + BoardName "Mystique" + chipset "fbdev" +EndSection + + +Acceleration: +============= + +Acceleration is currently only supported for matrox boards. +It works with matroxfb only. + + +Have fun, + + Gerd + +-- +Gerd Knorr diff -urN -x compile-log -x xmakefile -x Makefile* 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/fbdev.c xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/fbdev.c --- 3.3.3/xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/fbdev.c Thu Jan 1 01:00:00 1970 +++ xc/programs/Xserver/hw/xfree86/vga256/drivers/fbdev/fbdev.c Fri Jan 15 20:18:55 1999 @@ -0,0 +1,699 @@ +/* + * (c) 1998 Gerd Knorr + * + * based on: + * et3000 vga chipset driver by Thomas Roell, + * FBDev Server code (Martin Schaller and Geert Uytterhoeven) + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Thomas Roell not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Thomas Roell makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + */ + + +#include +#include "X.h" +#include "input.h" +#include "screenint.h" +#include "resource.h" +#include "dix.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86_HWlib.h" +#include "vga.h" + +#ifdef XFreeXDGA +#include "Xproto.h" +#include "scrnintstr.h" +#include "servermd.h" +#define _XF86DGA_SERVER_ +#include "extensions/xf86dgastr.h" +#endif + +#include "linux/fb.h" + +#define DEBUG 1 /* 0 == off, 1 == on */ + +static Bool FBDevProbe(); +static char * FBDevIdent(); +static Bool FBDevClockSelect(); +static void FBDevEnterLeave(); +static Bool FBDevInit(); +static int FBDevValidMode(); +static void * FBDevSave(); +static void FBDevRestore(); +static void FBDevAdjust(); +extern void FBDevSetRead(); +extern void FBDevSetWrite(); +extern void FBDevSetReadWrite(); +static int fbdevLinearOffset(); + +static int fb_fd; +static int LinearOffset; + +static struct fb_fix_screeninfo fix; +static struct fb_var_screeninfo var; +static ScreenPtr savepScreen = NULL; + +typedef struct { + struct fb_var_screeninfo var; +} vgaFBDevRec, *vgaFBDevPtr; + +extern Bool xf86Exiting, xf86Resetting, xf86ProbeFailed; + +DisplayModeRec startupMode; + +vgaVideoChipRec FBDEV = { + FBDevProbe, + FBDevIdent, + FBDevEnterLeave, + FBDevInit, + FBDevValidMode, + FBDevSave, + FBDevRestore, + FBDevAdjust, + (void (*)())NoopDDA /* XXX vgaHWSaveScreen */, + (void (*)())NoopDDA, /* GetMode(DisplayModePtr) */ + (void (*)())NoopDDA, /* FBInit() */ + (void (*)(int))NoopDDA, + (void (*)(int))NoopDDA, + (void (*)(int))NoopDDA, + + 0x10000, + 0x10000, + 16, + 0xFFFF, + 0x00000, 0x10000, + 0x00000, 0x10000, + TRUE, + + FALSE, + {0,}, + 16, + + TRUE, /* linear fb ? */ + 0, /* base */ + 0, /* size */ + + TRUE, /* has 16 bpp ? */ + TRUE, /* has 24 bpp ? */ + TRUE, /* has 32 bpp ? */ + NULL, /* build in mode list */ + 1, /* ClockMulFactor */ + 1 /* ClockDivFactor */ +}; + +/* ------------------------------------------------------------ */ + +static int +fb_open() +{ + struct fb_con2fbmap c2m; + char fbdev[16] = "/dev/fb0"; + int fd; + + /* allways respect $FRAMEBUFFER */ + if (NULL != getenv("FRAMEBUFFER")) + return open(getenv("FRAMEBUFFER"),O_RDWR); + + if (-1 == (fd = open(fbdev,O_RDWR))) + return -1; + + /* check console <=> framebuffer mapping */ + c2m.console = xf86Info.vtno; + if (-1 == ioctl(fd, FBIOGET_CON2FBMAP, &c2m)) { + perror("ioctl FBIOGET_CON2FBMAP"); + return fd; + } +#if DEBUG + ErrorF("fbdev: vt%02d => fb%d\n",c2m.console,c2m.framebuffer); +#endif + if (c2m.framebuffer != 0) { + /* it is another one ... */ + sprintf(fbdev,"/dev/fb%d\n",c2m.framebuffer); + close(fd); + fd = open(fbdev,O_RDWR); + } + return fd; +} + +/* + * Convert timings between the XFree style and the Frame Buffer Device style + */ + +static void xfree2fbdev(DisplayModePtr mode, struct fb_var_screeninfo *var) +{ + var->xres = mode->HDisplay; + var->yres = mode->VDisplay; + var->xres_virtual = vga256InfoRec.virtualX; + var->yres_virtual = vga256InfoRec.virtualY; + var->xoffset = var->yoffset = 0; + var->bits_per_pixel = (xf86bpp+7)&0xf8; /* XXX */ + var->red.length = xf86weight.red, + var->red.offset = xf86weight.green + xf86weight.blue, + var->green.length = xf86weight.green, + var->green.offset = xf86weight.blue, + var->blue.length = xf86weight.blue; + var->blue.offset = 0; + if (mode->Clock < MAXCLOCKS) { + var->pixclock = vga256InfoRec.clock[mode->Clock] ? + 1000000000/vga256InfoRec.clock[mode->Clock] : 0; + } else { + 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 (mode->Flags & V_BCAST) + var->sync |= FB_SYNC_BROADCAST; + 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(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 (var->sync & FB_SYNC_BROADCAST) + mode->Flags |= V_BCAST; + 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; +} + +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); +} + +/* ------------------------------------------------------------ */ +/* colormap handling */ + +static ColormapPtr InstalledMaps[MAXSCREENS]; + +static void fbdevUpdateColormap(int dex, int count, unsigned short *rmap, + unsigned short *gmap, unsigned short *bmap) +{ + struct fb_cmap cmap; + + if (!xf86VTSema) + /* Switched away from server vt, do nothing. */ + return; + + cmap.start = dex; + cmap.len = count; + cmap.red = rmap; + cmap.green = gmap; + cmap.blue = bmap; + cmap.transp = NULL; + + if (ioctl(fb_fd, FBIOPUTCMAP, &cmap) < 0) + FatalError("fbdevUpdateColormap: FBIOPUTCMAP failed (%s)\n", + strerror(errno)); +} + +static int fbdevListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) +{ + *pmaps = InstalledMaps[pScreen->myNum]->mid; + return 1; +} + +static void fbdevStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs) +{ + xColorItem *directDefs = NULL; + +#if DEBUG + ErrorF("fbdev: StoreColors pmap=%p, ndef=%d\n",pmap,ndef); +#endif + if (pmap != InstalledMaps[pmap->pScreen->myNum]) + return; + + if ((pmap->pVisual->class | DynamicClass) == DirectColor) { + directDefs = (xColorItem *) + ALLOCATE_LOCAL(256*sizeof(xColorItem)); + ndef = cfbExpandDirectColors (pmap, ndef, pdefs, directDefs); +#if DEBUG + ErrorF("fbdev: StoreColors: DirectColor ndef=%d\n",ndef); +#endif + pdefs = directDefs; + } + + while (ndef--) { +#if DEBUG + ErrorF("%d ",pdefs->pixel); +#endif + fbdevUpdateColormap(pdefs->pixel, 1, &pdefs->red, &pdefs->green, + &pdefs->blue); + pdefs++; + } +#if DEBUG + ErrorF("\n"); +#endif + + if (directDefs) + DEALLOCATE_LOCAL(directDefs); +} + +static void fbdevInstallColormap(ColormapPtr pmap) +{ + ColormapPtr oldmap = InstalledMaps[pmap->pScreen->myNum]; + int entries; + Pixel *ppix; + xrgb *prgb; + xColorItem *defs; + int i; + +#if DEBUG + ErrorF("fbdev: InstallColormap pmap=%p, oldmap=%p\n",pmap,oldmap); +#endif + if (pmap == oldmap) + return; + + if ((pmap->pVisual->class | DynamicClass) == DirectColor) + entries = (pmap->pVisual->redMask | + pmap->pVisual->greenMask | + pmap->pVisual->blueMask) + 1; + else + entries = pmap->pVisual->ColormapEntries; +#if DEBUG + ErrorF("fbdev: InstallColormap entries=%d\n",entries); +#endif + + ppix = (Pixel *)ALLOCATE_LOCAL(entries*sizeof(Pixel)); + prgb = (xrgb *)ALLOCATE_LOCAL(entries*sizeof(xrgb)); + defs = (xColorItem *)ALLOCATE_LOCAL(entries*sizeof(xColorItem)); + + if (oldmap != NULL) + WalkTree(pmap->pScreen, TellLostMap, &oldmap->mid); + + InstalledMaps[pmap->pScreen->myNum] = pmap; + + for (i = 0; i < entries; i++) + ppix[i] = i; + QueryColors(pmap, entries, ppix, prgb); + + for (i = 0 ; i < entries; i++) { + defs[i].pixel = ppix[i]; + defs[i].red = prgb[i].red; + defs[i].green = prgb[i].green; + defs[i].blue = prgb[i].blue; + defs[i].flags = DoRed|DoGreen|DoBlue; + } + + fbdevStoreColors(pmap, entries, defs); + + WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid); + + DEALLOCATE_LOCAL(ppix); + DEALLOCATE_LOCAL(prgb); + DEALLOCATE_LOCAL(defs); +} + +static void fbdevUninstallColormap(ColormapPtr pmap) +{ + ColormapPtr defColormap; + +#if DEBUG + ErrorF("fbdev: UninstallColormap pmap=%p\n",pmap); +#endif + if (pmap != InstalledMaps[pmap->pScreen->myNum]) + return; + defColormap = (ColormapPtr)LookupIDByType(pmap->pScreen->defColormap, + RT_COLORMAP); + if (defColormap == InstalledMaps[pmap->pScreen->myNum]) + return; + (*pmap->pScreen->InstallColormap)(defColormap); +} + +static void fbdevRestoreColors() +{ + ScreenPtr pScreen = savepScreen; + ColormapPtr pmap; + int entries; + + if (NULL == pScreen) + return; + pmap = InstalledMaps[pScreen->myNum]; + if (!pmap) + pmap = (ColormapPtr) LookupIDByType(pScreen->defColormap, RT_COLORMAP); + entries = pmap->pVisual->ColormapEntries; + if (entries) { + Pixel *ppix; + xrgb *prgb; + xColorItem *defs; + int i; + + ppix = (Pixel *)ALLOCATE_LOCAL(entries*sizeof(Pixel)); + prgb = (xrgb *)ALLOCATE_LOCAL(entries*sizeof(xrgb)); + defs = (xColorItem *)ALLOCATE_LOCAL(entries*sizeof(xColorItem)); + + for (i = 0 ; i < entries; i++) + ppix[i] = i; + QueryColors(pmap, entries, ppix, prgb); + + for (i = 0 ; i < entries; i++) { + defs[i].pixel = ppix[i]; + defs[i].red = prgb[i].red; + defs[i].green = prgb[i].green; + defs[i].blue = prgb[i].blue; + } + + fbdevStoreColors(pmap, entries, defs); + + DEALLOCATE_LOCAL(ppix); + DEALLOCATE_LOCAL(prgb); + DEALLOCATE_LOCAL(defs); + } +} + +static Bool fbdevScrInitFunc(pScreen,base,x,y,resx,resy,width) + ScreenPtr pScreen; + pointer base; + int x; + int y; + int resx; + int resy; + int width; +{ +#if DEBUG + ErrorF("fbdev: ScrInitFunc\n"); +#endif + if (vgaBitsPerPixel > 8) + return; + pScreen->InstallColormap = fbdevInstallColormap; + pScreen->UninstallColormap = fbdevUninstallColormap; + pScreen->ListInstalledColormaps = fbdevListInstalledColormaps; + pScreen->StoreColors = fbdevStoreColors; + savepScreen = pScreen; +} + +/* ------------------------------------------------------------ */ +/* handle acceleration */ + +#include "vgaPCI.h" +#include "../mga/mga.h" + +int +fbdev_mga_init(CARD32 pci) +{ + MGAchipset = pci; + MGAydstorg = LinearOffset; + MGAMMIOBase = xf86MapVidMem(vga256InfoRec.scrnIndex, MMIO_REGION, + (pointer)(fix.mmio_start), fix.mmio_len); + MGAStormAccelInit(); +} + +static struct accelentry { + CARD32 id; + CARD32 pci; + const char *name; + int (*init)(CARD32); +} acceltab[] = { + { FB_ACCEL_NONE, 0, "None", NULL }, + { FB_ACCEL_MATROX_MGA2064W, PCI_CHIP_MGA2064, "Matrox MGA2064W (Millennium)", fbdev_mga_init }, + { FB_ACCEL_MATROX_MGA1064SG, PCI_CHIP_MGA1064, "Matrox MGA1064SG (Mystique)", fbdev_mga_init }, + { FB_ACCEL_MATROX_MGA2164W, PCI_CHIP_MGA2164, "Matrox MGA2164W (Millennium II)", fbdev_mga_init }, + { FB_ACCEL_MATROX_MGA2164W_AGP, PCI_CHIP_MGA2164_AGP, "Matrox MGA2164W (Millennium II AGP)", fbdev_mga_init }, + { FB_ACCEL_MATROX_MGAG100, PCI_CHIP_MGAG100, "Matrox G100 (Productiva G100)", fbdev_mga_init }, + { FB_ACCEL_MATROX_MGAG200, PCI_CHIP_MGAG200, "Matrox G200 (Millennium, Mystique)", fbdev_mga_init }, +}; + +void +fbdev_accel() +{ + int i; + + for (i = 0; i < sizeof(acceltab)/sizeof(struct accelentry); i++) { + if (fix.accel == acceltab[i].id) + break; + } + if (i == sizeof(acceltab)/sizeof(struct accelentry)) + return; + if (acceltab[i].init == NULL) + return; + ErrorF( "fbdev: accelerator=%s, fb=%p+%dk, mmio=%p+%d\n", + acceltab[i].name, + fix.smem_start,fix.smem_len>>10, + fix.mmio_start,fix.mmio_len); + acceltab[i].init(acceltab[i].pci); +} + +/* ------------------------------------------------------------ */ + +static char * +FBDevIdent(n) + int n; +{ + static char *chipsets[] = {"fbdev"}; + + if (n + 1 > sizeof(chipsets) / sizeof(char *)) + return(NULL); + else + return(chipsets[n]); +} + +static Bool +FBDevProbe() +{ + /* handle chipset config option */ + if (vga256InfoRec.chipset != NULL) + if (0 != strcmp(FBDevIdent(0),vga256InfoRec.chipset)) + return FALSE; + + if (-1 == (fb_fd = fb_open())) + return FALSE; + if (-1 == ioctl(fb_fd,FBIOGET_FSCREENINFO,&fix) || + fix.type != FB_TYPE_PACKED_PIXELS) { + close(fb_fd); + return FALSE; + } + + /* set parameters */ +#define PAGE_SIZE 4096 /* FIXME */ + FBDEV.ChipLinearBase = (unsigned long)fix.smem_start & ~(PAGE_SIZE-1); + FBDEV.ChipLinearSize = fix.smem_len; + vga256InfoRec.videoRam = fix.smem_len>>10; + vga256InfoRec.chipset = "fbdev"; + OFLG_SET(CLOCK_OPTION_PROGRAMABLE, &vga256InfoRec.clockOptions); + + /* no vga hardware access allowed !!! */ + vgaSaveScreenFunc = (void (*)(Bool))NoopDDA; + vgaBlankScreenFunc = (Bool (*)(ScreenPtr,Bool))NoopDDA; + + /* use the current mode if there are no modelines */ + ioctl(fb_fd,FBIOGET_VSCREENINFO,&var); + if (NULL == vga256InfoRec.modes) { + fbdev2xfree(&var, &startupMode); +#if DEBUG + print_fbdev_mode("current",&var); + print_xfree_mode("current",&startupMode); +#endif + startupMode.name = "current"; + startupMode.next = &startupMode; + FBDEV.ChipBuiltinModes = &startupMode; + } + + /* hook for setting the colormap function pointers */ + vgaSetScreenInitHook(fbdevScrInitFunc); + vgaSetLinearOffsetHook(fbdevLinearOffset); + return TRUE; +} + +static void +FBDevEnterLeave(enter) + Bool enter; +{ +#if DEBUG + ErrorF("fbdev: EnterLeave %d\n",enter); +#endif + if (enter) { + if (!xf86Exiting) + fbdevRestoreColors(); + } else { + /* nothing (yet?) */ + } +} + +static void +FBDevRestore(restore) + vgaFBDevPtr restore; +{ +#if DEBUG + ErrorF("fbdev: Restore %p\n",restore); +#endif + if (NULL == restore) + return; + if (-1 == ioctl(fb_fd,FBIOPUT_VSCREENINFO,restore)) + perror("FBIOPUT_VSCREENINFO"); +} + + +static void* +FBDevSave(save) + vgaFBDevPtr save; +{ +#if DEBUG + ErrorF("fbdev: Save %p",save); +#endif + if (NULL == save) + save = (vgaFBDevPtr)xcalloc(1,sizeof(vgaFBDevRec)); +#if DEBUG + ErrorF("(%p)\n",save); +#endif + if (-1 == ioctl(fb_fd,FBIOGET_VSCREENINFO,save)) + perror("FBIOGET_VSCREENINFO"); + return save; +} + + +static Bool +FBDevInit(mode) + DisplayModePtr mode; +{ + static int first = TRUE; + + memset(&var,0,sizeof(var)); + xfree2fbdev(mode, &var); +#if DEBUG + print_xfree_mode("init",&startupMode); + print_fbdev_mode("init",&var); +#endif + if (0 != ioctl(fb_fd,FBIOPUT_VSCREENINFO,&var)) { + perror("FBIOPUT_VSCREENINFO"); + return FALSE; + } + + if (first) { + first = FALSE; + fbdev_accel(); + } + return TRUE; +} + + +static void +FBDevAdjust(x, y) + int x, y; +{ + var.xoffset = x; + var.yoffset = y; + ioctl(fb_fd,FBIOPAN_DISPLAY,&var); +} + +static int +FBDevValidMode(mode, verbose,flag) + DisplayModePtr mode; + Bool verbose; + int flag; +{ + struct fb_var_screeninfo var; + + memset(&var,0,sizeof(var)); + xfree2fbdev(mode, &var); +#if DEBUG + print_xfree_mode("valid?",mode); +#endif + var.activate = FB_ACTIVATE_TEST; + if (0 != ioctl(fb_fd,FBIOPUT_VSCREENINFO,&var)) { + return MODE_BAD; + } + return MODE_OK; +} + +static int +fbdevLinearOffset() +{ + /* "var" has the currently used video mode here. */ + /* fill in virtual screen size and colordepth... */ + var.xres_virtual = vga256InfoRec.virtualX; + var.yres_virtual = vga256InfoRec.virtualY; + var.xoffset = var.yoffset = 0; + var.bits_per_pixel = (xf86bpp+7)&0xf8; + var.red.length = xf86weight.red, + var.red.offset = xf86weight.green + xf86weight.blue, + var.green.length = xf86weight.green, + var.green.offset = xf86weight.blue, + var.blue.length = xf86weight.blue; + var.blue.offset = 0; + + /* ... mode switch .. */ + if (-1 == ioctl(fb_fd,FBIOPUT_VSCREENINFO,&var)) + return 0; + + /* ... and look for a offset */ + ioctl(fb_fd,FBIOGET_FSCREENINFO,&fix); + LinearOffset = (unsigned long)fix.smem_start-FBDEV.ChipLinearBase; +#if DEBUG + ErrorF("fbdev: Linear Offset %d\n",LinearOffset); +#endif + return LinearOffset; +}