summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:55 +0000
commitc5aeaa75075f2bace017bd6a55384f5bb8766eab (patch)
tree58573775edfc5a21277f3e37e9d4f0600271db92
-rw-r--r--man/glide.man298
-rw-r--r--src/glide_driver.c1116
2 files changed, 1414 insertions, 0 deletions
diff --git a/man/glide.man b/man/glide.man
new file mode 100644
index 0000000..bf3e78f
--- /dev/null
+++ b/man/glide.man
@@ -0,0 +1,298 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glide/glide.man,v 1.3 2001/02/07 22:51:56 tsi Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH GLIDE __drivermansuffix__ __vendorversion__
+.SH NAME
+glide \- Glide video driver
+.SH SYNOPSIS
+.nf
+.B "Section \*qDevice\*q"
+.BI " Identifier \*q" devname \*q
+.B " Driver \*qglide\*q"
+\ \ ...
+.B EndSection
+.fi
+.SH READ THIS IF NOTHING ELSE
+This driver has a special requirement that needs to be fulfilled
+before it will work: You need Glide installed and you need to make a link for the libglide2x.so
+file. Read the second paragraph in the description below to find out how.
+.SH DESCRIPTION
+.B glide
+is an XFree86 driver for Glide capable video boards (such as 3Dfx
+Voodoo boards). This driver is mainly for Voodoo 1 and Voodoo 2 boards, later
+boards from 3Dfx have 2D built-in and you should preferably use a driver separate for
+those boards or the fbdev(__drivermansuffix__) driver.
+This driver is a bit special because Voodoo 1 and 2 boards are
+very much NOT made for running 2D graphics. Therefore, this driver
+uses no hardware acceleration (since there is no acceleration for 2D,
+only 3D). Instead it is implemented with the help of a "shadow"
+framebuffer that resides entirely in RAM. Selected portions of this
+shadow framebuffer are then copied out to the Voodoo board at the right
+time. Because of this, the speed of the driver is very dependent on
+the CPU. But since the CPU is nowadays actually rather fast at moving
+data, we get very good speed anyway, especially since the whole shadow
+framebuffer is in cached RAM.
+.PP
+This driver requires that you have installed Glide. (Which can, at the
+time of this writing, be found at
+http://glide.xxedgexx.com/3DfxRPMS.html). Also, you need to tell
+XFree86 where the libglide2x.so file is placed by making a soft link
+in the /usr/X11R6/lib/modules directory that points to the libglide2x.so
+file. For example (if your libglide2x.so file is in /usr/lib):
+.PP
+\& # ln -s /usr/lib/libglide2x.so /usr/X11R6/lib/modules
+.PP
+If you have installed /dev/3dfx, the driver will be able to turn on
+the MTRR registers (through the glide library) if you have a CPU with
+such registers (see http://glide.xxedgexx.com/MTRR.html). This will
+speed up copying data to the Voodoo board by as much as 2.7 times and
+is very noticeable since this driver copies a lot of
+data... Highly recommended.
+.PP
+This driver supports 16 and 24 bit color modes. The 24 bit color mode
+uses a 32 bit framebuffer (it has no support for 24 bit packed-pixel
+framebuffers). Notice that the Voodoo boards can only display 16 bit
+color, but the shadow framebuffer can be run in 24 bit color. The
+point of supporting 24 bit mode is that this enables you to run in a
+multihead configuration with Xinerama together with another board that
+runs in real 24 bit color mode. (All boards must run the same color
+depth when you use Xinerama).
+.PP
+Resolutions supported are: 640x480, 800x600, 960x720, 1024x768,
+1280x1024 and 1600x1200. Note that not all modes will work on all
+Voodoo boards. It seems that Voodoo 2 boards support no higher than
+1024x768 and Voodoo 1 boards can go to 800x600. If you see a message like this in the output from the server:
+.PP
+ (EE) GLIDE(0): grSstWinOpen returned ...
+.PP
+Then you are probably trying to use a resolution that is supported by
+the driver but not supported by the hardware.
+.PP
+Refresh rates supported are: 60Hz, 75Hz and 85Hz. The refresh rate
+used is derived from the normal mode line according
+to the following table:
+.TP 28
+Mode-line refresh rate
+Used refresh rate
+.TP 28
+ 0-74 Hz
+ 60 Hz
+.TP 28
+ 74-84 Hz
+ 75 Hz
+.TP 28
+ 84- Hz
+ 85 Hz
+.PP
+Thus, if you use a modeline that for example has a 70Hz refresh rate
+you will only get a 60Hz refresh rate in actuality.
+.PP
+Selecting which Voodoo board to use with the driver is done by using
+an option called "GlideDevice" in the "Device" section. (If you don't
+have this option present then the first board found will be selected for that Device section). For
+example: To use the first Voodoo board, use a "Device" section like
+this, for example:
+.PP
+Section "Device"
+.br
+ Identifier "Voodoo"
+.br
+ Driver "glide"
+.br
+ Option "dpms" "on"
+.br
+ Option "GlideDevice" "0"
+.br
+EndSection
+.PP
+And if you have more than one Voodoo board, add another "Device"
+section with a GlideDevice option with value 1, and so on. (You can use more than one
+Voodoo board, but SLI configured boards will be treated as a single board.)
+.PP
+Multihead and Xinerama configurations are supported.
+.PP
+Limited support for DPMS screen saving is available. The "standby" and
+"suspend" modes are just painting the screen black. The "off" mode turns
+the Voodoo board off and thus works correctly.
+.PP
+This driver does not support a virtual screen size different from the display size.
+.SH SUPPORTED HARDWARE
+The
+.B glide
+driver supports any board that can be used with Glide (such as 3Dfx Voodoo boards)
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option \*qOnAtExit\*q \*q" boolean \*q
+If true, will leave the Voodoo board on when the server exits. Useful in a multihead setup when
+only the Voodoo board is connected to a second monitor and you don't want that monitor to lose
+signal when you quit the server. Put this option in the Device section.
+Default: off.
+.TP
+.BI "Option \*qGlideDevice\*q \*q" integer \*q
+Selects which Voodoo board to use. (Or boards, in an SLI configuration).
+The value should be 0 for the first board, 1 for the second and so on.
+If it is not present, the first Voodoo board found will be selected.
+Put this option in the Device section.
+.SH "EXAMPLE"
+Here is an example of a part of an XF86Config file that uses a multihead
+configuration with two monitors. The first monitor is driven by the
+fbdev video driver and the second monitor is driven by the glide
+driver.
+.PP
+.br
+Section "Monitor"
+.br
+ Identifier "Monitor 1"
+.br
+ VendorName "Unknown"
+.br
+ ModelName "Unknown"
+.br
+ HorizSync 30-70
+.br
+ VertRefresh 50-80
+.br
+
+.br
+\& # 1024x768 @ 76 Hz, 62.5 kHz hsync
+.br
+ Modeline "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+.br
+EndSection
+.br
+
+.br
+Section "Monitor"
+.br
+ Identifier "Monitor 2"
+.br
+ VendorName "Unknown"
+.br
+ ModelName "Unknown"
+.br
+ HorizSync 30-70
+.br
+ VertRefresh 50-80
+.br
+
+.br
+\& # 1024x768 @ 76 Hz, 62.5 kHz hsync
+.br
+ Modeline "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+.br
+EndSection
+.br
+
+.br
+Section "Device"
+.br
+ Identifier "fb"
+.br
+ Driver "fbdev"
+.br
+ Option "shadowfb"
+.br
+ Option "dpms" "on"
+.br
+\& # My video card is on the AGP bus which is usually
+.br
+\& # located as PCI bus 1, device 0, function 0.
+.br
+ BusID "PCI:1:0:0"
+.br
+EndSection
+.br
+
+.br
+Section "Device"
+.br
+\& # I have a Voodoo 2 board
+.br
+ Identifier "Voodoo"
+.br
+ Driver "glide"
+.br
+ Option "dpms" "on"
+.br
+\& # The next line says I want to use the first board.
+.br
+ Option "GlideDevice" "0"
+.br
+EndSection
+.br
+
+.br
+Section "Screen"
+.br
+ Identifier "Screen 1"
+.br
+ Device "fb"
+.br
+ Monitor "Monitor 1"
+.br
+ DefaultDepth 16
+.br
+ Subsection "Display"
+.br
+ Depth 16
+.br
+ Modes "1024x768"
+.br
+ EndSubSection
+.br
+EndSection
+.br
+
+.br
+Section "Screen"
+.br
+ Identifier "Screen 2"
+.br
+ Device "Voodoo"
+.br
+ Monitor "Monitor 2"
+.br
+ DefaultDepth 16
+.br
+ Subsection "Display"
+.br
+ Depth 16
+.br
+ Modes "1024x768"
+.br
+ EndSubSection
+.br
+EndSection
+.br
+
+.br
+Section "ServerLayout"
+.br
+ Identifier "Main Layout"
+.br
+\& # Screen 1 is to the right and screen 2 is to the left
+.br
+ Screen "Screen 2"
+.br
+ Screen "Screen 1" "" "" "Screen 2" ""
+.br
+EndSection
+.PP
+If you use this configuration file and start the server with the
++xinerama command line option, the two monitors will be showing a
+single large area where windows can be moved between monitors and
+overlap from one monitor to the other. Starting the X server with the
+Xinerama extension can be done for example like this:
+.PP
+$ xinit -- +xinerama
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__)
+.SH AUTHORS
+Author: Henrik Harmsen.
diff --git a/src/glide_driver.c b/src/glide_driver.c
new file mode 100644
index 0000000..230c34c
--- /dev/null
+++ b/src/glide_driver.c
@@ -0,0 +1,1116 @@
+
+/*
+ XFree86 driver for Glide(tm). (Mainly for Voodoo 1 and 2 cards)
+
+ Since Voodoo 1 and Voodoo 2 cards are very, very NOT made for
+ running a 2D windowing system, this driver is a little
+ special. Basically, we have a virtual framebuffer in RAM (the
+ Shadow Framebuffer) and we copy selected regions of this to the
+ voodoo card at appropriate times. We get no hardware acceleration
+ help (there isn't any for 2D on these cards), but since the
+ framebuffer is in cached RAM, we get a useable display
+ anyway. Also, we don't have any interaction with any hardware since
+ Glide is the layer beneath the driver.
+
+ Author:
+ Henrik Harmsen (hch@cd.chalmers.se or Henrik.Harmsen@erv.ericsson.se)
+
+ HISTORY
+ 1999-04-05
+ - First release for 3.9Pi
+
+ 1999-04-17
+ - Soft link to libglide2x.so instead of addition to ModulePath
+ - Changed "EXTERN_MODULE" to EXTERN_MODULE
+ - Uses the "GlideDevice" option instead of the "BusID" line to select
+ which voodoo board to use.
+ - Manpage updates
+
+ 1999-06-25
+ - Modify glideSetup to not register the driver when libglide2x.so cannot
+ be loaded, and to return appropriate error codes when it fails.
+ - Prevent GLIDEFreeScreen() from crashing if called early.
+
+ 1999-08-22
+ - Minor fixes.
+
+ 1999-11-22
+ - Minor change in GLIDE_FIND_FUNC by Loïc Grenié, grenie@math.jussieu.fr.
+
+ TODO
+ * Support for adjusting gamma correction.
+ * Support for setting gamma individually for R,G,B when Glide 3 arrives
+ for Linux. This will allow me to get rid of that sick green tint my
+ voodoo2 board produces...
+ * Support static loading.
+*/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c,v 1.28 2002/01/04 21:22:30 tsi Exp $ */
+
+#include "xaa.h"
+#include "xf86Cursor.h"
+#include "colormapst.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "mipointer.h"
+#include "mibstore.h"
+#include "micmap.h"
+#include "xf86DDC.h"
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#include "fb.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+
+#include <glide.h>
+
+#define TRUE 1
+#define FALSE 0
+#ifdef NULL
+#undef NULL
+#endif
+#define NULL 0
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+typedef signed char s8;
+typedef unsigned char u8;
+typedef signed short int s16;
+typedef unsigned short int u16;
+typedef signed long int s32;
+typedef unsigned long int u32;
+typedef u8 bool;
+
+/* Card-specific driver information */
+
+#define GLIDEPTR(p) ((GLIDEPtr)((p)->driverPrivate))
+
+
+typedef FxBool (*pgrSstQueryBoards_t)(GrHwConfiguration*);
+typedef void (*pgrGlideInit_t)(void);
+typedef void (*pgrSstSelect_t)(int which_sst);
+typedef FxBool (*pgrSstWinOpen_t)(FxU32, GrScreenResolution_t, GrScreenRefresh_t,
+ GrColorFormat_t, GrOriginLocation_t, int, int);
+typedef void (*pgrRenderBuffer_t)(GrBuffer_t);
+typedef void (*pgrClipWindow_t)(FxU32, FxU32, FxU32, FxU32);
+typedef void (*pgrBufferClear_t)(GrColor_t, GrAlpha_t, FxU16);
+typedef FxBool (*pgrLfbLock_t)(GrLock_t, GrBuffer_t, GrLfbWriteMode_t, GrOriginLocation_t,
+ FxBool, GrLfbInfo_t*);
+typedef FxBool (*pgrLfbUnlock_t)(GrLock_t, GrBuffer_t);
+typedef void (*pgrGlideShutdown_t)(void);
+
+
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+typedef FxBool (*pgrLfbWriteRegion_t)(GrBuffer_t, FxU32, FxU32, GrLfbSrcFmt_t,
+ FxU32, FxU32, FxBool, FxI32, void*);
+#else
+typedef FxBool (*pgrLfbWriteRegion_t)(GrBuffer_t, FxU32, FxU32, GrLfbSrcFmt_t,
+ FxU32, FxU32, FxI32, void*);
+#endif
+
+
+typedef struct {
+ u8* ShadowPtr;
+ u32 ShadowPitch;
+ u32 SST_Index;
+ CloseScreenProcPtr CloseScreen;
+ Bool Blanked;
+ u32 grRefreshRate;
+ u32 grResolution;
+ Bool OnAtExit;
+ Bool GlideInitiated;
+ EntityInfoPtr pEnt;
+ OptionInfoPtr Options;
+} GLIDERec, *GLIDEPtr;
+
+static pgrSstQueryBoards_t pgrSstQueryBoards;
+static pgrGlideInit_t pgrGlideInit;
+static pgrSstSelect_t pgrSstSelect;
+static pgrSstWinOpen_t pgrSstWinOpen;
+static pgrRenderBuffer_t pgrRenderBuffer;
+static pgrClipWindow_t pgrClipWindow;
+static pgrBufferClear_t pgrBufferClear;
+static pgrLfbLock_t pgrLfbLock;
+static pgrLfbUnlock_t pgrLfbUnlock;
+static pgrGlideShutdown_t pgrGlideShutdown;
+static pgrLfbWriteRegion_t pgrLfbWriteRegion;
+
+static const OptionInfoRec * GLIDEAvailableOptions(int chipid, int busid);
+static void GLIDEIdentify(int flags);
+static Bool GLIDEProbe(DriverPtr drv, int flags);
+static Bool GLIDEPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool GLIDEScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+static Bool GLIDEEnterVT(int scrnIndex, int flags);
+static void GLIDELeaveVT(int scrnIndex, int flags);
+static Bool GLIDECloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool GLIDESaveScreen(ScreenPtr pScreen, int mode);
+static void GLIDEFreeScreen(int scrnIndex, int flags);
+static void GLIDERefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static Bool GLIDEModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void GLIDERestore(ScrnInfoPtr pScrn, Bool Closing);
+static void GLIDERefreshAll(ScrnInfoPtr pScrn);
+
+static void GLIDEDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+
+
+static int LoadGlide(void);
+
+#define VERSION 4000
+#define GLIDE_NAME "GLIDE"
+#define GLIDE_DRIVER_NAME "glide"
+#define GLIDE_MAJOR_VERSION 1
+#define GLIDE_MINOR_VERSION 0
+#define GLIDE_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec GLIDE = {
+ VERSION,
+ GLIDE_DRIVER_NAME,
+ GLIDEIdentify,
+ GLIDEProbe,
+ GLIDEAvailableOptions,
+ NULL,
+ 0
+};
+
+typedef enum {
+ OPTION_ON_AT_EXIT,
+ OPTION_GLIDEDEVICE
+} GLIDEOpts;
+
+static const OptionInfoRec GLIDEOptions[] = {
+ { OPTION_ON_AT_EXIT, "OnAtExit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_GLIDEDEVICE, "GlideDevice", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/* Supported chipsets */
+static SymTabRec GLIDEChipsets[] = {
+ { 0, "Voodoo" },
+ {-1, NULL }
+};
+
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *fbSymbols[] = {
+ "fbScreenInit",
+ "fbPictureInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(glideSetup);
+
+static XF86ModuleVersionInfo glideVersRec =
+{
+ "glide",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ GLIDE_MAJOR_VERSION, GLIDE_MINOR_VERSION, GLIDE_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData glideModuleData = { &glideVersRec, glideSetup, NULL };
+
+static pointer
+glideSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+ pointer ret;
+ int errmaj2 = 0, errmin2 = 0;
+
+ if (!setupDone)
+ {
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ ret = LoadSubModule(module, "glide2x", NULL, NULL, EXTERN_MODULE, NULL,
+ &errmaj2, &errmin2);
+ if (!ret)
+ {
+ xf86Msg(X_ERROR, "Glide driver:\n"
+"\n"
+"Could not load the shared library file for Glide: \"libglide2x.so\"! \n"
+"\n"
+"You need to have Glide installed to run the glide driver for XFree86.\n"
+"Also, you need to tell XFree86 where the libglide2x.so file is placed\n"
+"by making a soft link in the /usr/X11R6/lib/modules directory that points\n"
+"to the libglide2x.so file. For example (if your libglide2x.so file is in\n"
+"/usr/lib):\n"
+"\n"
+" # ln -s /usr/lib/libglide2x.so /usr/X11R6/lib/modules\n"
+"\n"
+"\n");
+ if (errmaj)
+ *errmaj = LDR_NOSUBENT;
+ if (errmin)
+ *errmin = errmaj2;
+ return NULL;
+ }
+
+ if (!LoadGlide()) {
+ if (errmaj)
+ *errmaj = LDR_MODSPECIFIC;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ }
+
+ setupDone = TRUE;
+ /* This module should be loaded only once */
+ *errmaj = LDR_ONCEONLY;
+ xf86AddDriver(&GLIDE, module, 0);
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(fbSymbols, shadowSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ }
+ else
+ {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+#endif /* XFree86LOADER */
+
+static Bool
+GLIDEGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an GLIDERec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(GLIDERec), 1);
+
+ /* Initialize it */
+ /* No init here yet */
+ return TRUE;
+}
+
+static void
+GLIDEFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+static const OptionInfoRec *
+GLIDEAvailableOptions(int chipid, int busid)
+{
+ return GLIDEOptions;
+}
+
+/* Mandatory */
+static void
+GLIDEIdentify(int flags)
+{
+ xf86PrintChipsets(GLIDE_NAME, "driver for Glide devices (Voodoo cards)", GLIDEChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+GLIDEProbe(DriverPtr drv, int flags)
+{
+ GrHwConfiguration hw;
+ int i, sst, r;
+ GDevPtr *devList;
+ GDevPtr dev = NULL;
+ int numdevList;
+ Bool foundScreen = FALSE;
+ ScrnInfoPtr pScrn;
+ int GlideDevice;
+
+ if ((numdevList = xf86MatchDevice(GLIDE_DRIVER_NAME, &devList)) <= 0)
+ return FALSE;
+
+ r = pgrSstQueryBoards(&hw);
+ if (!r)
+ {
+ xf86Msg(X_ERROR, "GLIDEProbe(): Error calling pgrSstQueryBoards!\n");
+ goto cleanup;
+ }
+
+
+ /* hw.num_sst : number of Glide boards available */
+ if (hw.num_sst > 0 && (flags & PROBE_DETECT)) {
+ /* XXX Need to call xf886AddDeviceToConfigure() here */
+ return TRUE;
+ }
+
+ for (sst = 0; sst < hw.num_sst; sst++)
+ {
+ for (i = 0; i < numdevList; i++)
+ {
+ dev = devList[i];
+ GlideDevice = xf86SetIntOption(dev->options, "GlideDevice", 0);
+ if (GlideDevice == sst)
+ {
+ int entity;
+ /* Match */
+ entity = xf86ClaimIsaSlot(drv, 0, dev, TRUE);
+ pScrn = NULL;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ if ((pScrn = xf86ConfigIsaEntity(pScrn, 0, entity, NULL, NULL,
+ NULL, NULL, NULL, NULL))) {
+
+ /* I'm not going to "claim" the glide device since no other driver than this can drive it */
+ /* (A glide device is not a PCI device) */
+ /* XXX Need to see how this fits in with the new RAC */
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = GLIDE_DRIVER_NAME;
+ pScrn->name = GLIDE_NAME;
+ pScrn->Probe = GLIDEProbe;
+ pScrn->PreInit = GLIDEPreInit;
+ pScrn->ScreenInit = GLIDEScreenInit;
+ pScrn->EnterVT = GLIDEEnterVT;
+ pScrn->LeaveVT = GLIDELeaveVT;
+ pScrn->FreeScreen = GLIDEFreeScreen;
+ pScrn->driverPrivate = (void*)sst;
+ /*
+ * XXX This is a hack because don't have the PCI info. Set it as
+ * an ISA entity with no resources.
+ */
+ foundScreen = TRUE;
+ }
+ break;
+ }
+ }
+ }
+
+ cleanup:
+ xfree(devList);
+ return foundScreen;
+}
+
+
+
+
+/* Mandatory */
+static Bool
+GLIDEPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ GLIDEPtr pGlide;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ int sst;
+
+ if (flags & PROBE_DETECT) return FALSE;
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ sst = (int)(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (!xf86SetDepthBpp(pScrn, 16, 0, 0, Support32bppFb)) {
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ }
+ /* We don't 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;
+ }
+
+ /* Set default gamma */
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the GLIDERec driverPrivate */
+ if (!GLIDEGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pGlide = GLIDEPTR(pScrn);
+
+ /* Get the entity */
+ pGlide->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ if (!(pGlide->Options = xalloc(sizeof(GLIDEOptions))))
+ return FALSE;
+ memcpy(pGlide->Options, GLIDEOptions, sizeof(GLIDEOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pGlide->Options);
+
+ pGlide->OnAtExit = FALSE;
+ from = X_DEFAULT;
+ if (xf86GetOptValBool(pGlide->Options, OPTION_ON_AT_EXIT, &(pGlide->OnAtExit)))
+ from = X_CONFIG;
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Voodoo card will be %s when exiting server.\n",
+ pGlide->OnAtExit ? "ON" : "OFF");
+
+ pGlide->SST_Index = sst;
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pGlide->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pGlide->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ pScrn->videoRam = 8192; /* It's just virtual framebuffer anyway so let's say we have an 8MB sized framebuffer */
+ from = X_PROBED;
+ }
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, from, "Virtual video RAM: %d kB\n",
+ pScrn->videoRam);
+#endif
+
+ /* Set up clock ranges so that the xf86ValidateModes() function will not fail a mode because of the clock
+ requirement (because we don't use the clock value anyway) */
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = 10000;
+ clockRanges->maxClock = 300000;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* Select valid modes from those available */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ /* If no valid modes, return */
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Do some checking, we will not support a virtual framebuffer larger than
+ the visible screen. */
+ if (pScrn->currentMode->HDisplay != pScrn->virtualX ||
+ pScrn->currentMode->VDisplay != pScrn->virtualY ||
+ pScrn->displayWidth != pScrn->virtualX)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Virtual size doesn't equal display size. Forcing virtual size to equal display size.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "(Virtual size: %dx%d, Display size: %dx%d)\n", pScrn->virtualX, pScrn->virtualY,
+ pScrn->currentMode->HDisplay, pScrn->currentMode->VDisplay);
+ /* I'm not entirely sure this is "legal" but I hope so. */
+ pScrn->virtualX = pScrn->currentMode->HDisplay;
+ pScrn->virtualY = pScrn->currentMode->VDisplay;
+ pScrn->displayWidth = pScrn->virtualX;
+ }
+
+ /* TODO: Note: If I return FALSE right here, the server will not restore the console correctly,
+ forcing a reboot. Must find that. (valid for 3.9Pi) */
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load fb */
+ if (xf86LoadSubModule(pScrn, "fb") == NULL) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load the shadow framebuffer */
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+
+ return TRUE;
+}
+
+
+/* Mandatory */
+/* This gets called at the start of each server generation */
+static Bool
+GLIDEScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ GLIDEPtr pGlide;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (!GLIDEModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that fb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. Only TrueColor. */
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+
+ miSetPixmapDepths ();
+
+ pGlide->ShadowPitch = ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ pGlide->ShadowPtr = xnfalloc(pGlide->ShadowPitch * pScrn->virtualY);
+
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ ret = fbScreenInit(pScreen, pGlide->ShadowPtr,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth,
+ pScrn->bitsPerPixel);
+
+ if (!ret)
+ return FALSE;
+
+ /* 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 */
+ fbPictureInit (pScreen, 0, 0);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBlackWhitePixels(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ ShadowFBInit(pScreen, GLIDERefreshArea);
+
+ xf86DPMSInit(pScreen, GLIDEDisplayPowerManagementSet, 0);
+
+ pScreen->SaveScreen = GLIDESaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pGlide->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = GLIDECloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+#if 0
+ LoaderCheckUnresolved(LD_RESOLV_NOW);
+ return FALSE;
+#endif
+
+ /* Done */
+ return TRUE;
+}
+
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+GLIDEEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ return GLIDEModeInit(pScrn, pScrn->currentMode);
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+GLIDELeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDERestore(pScrn, FALSE);
+}
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+GLIDECloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+
+ if (pScrn->vtSema)
+ GLIDERestore(pScrn, TRUE);
+ xfree(pGlide->ShadowPtr);
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pGlide->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+GLIDEFreeScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ if (pGlide && pGlide->ShadowPtr)
+ xfree(pGlide->ShadowPtr);
+ GLIDEFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Do screen blanking */
+/* Mandatory */
+static Bool
+GLIDESaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn;
+ GLIDEPtr pGlide;
+ Bool unblank;
+
+ unblank = xf86IsUnblank(mode);
+ pScrn = xf86Screens[pScreen->myNum];
+ pGlide = GLIDEPTR(pScrn);
+ pGlide->Blanked = !unblank;
+ if (unblank)
+ GLIDERefreshAll(pScrn);
+ else
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+
+ return TRUE;
+}
+
+static Bool
+GLIDEModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLIDEPtr pGlide;
+ int r;
+ int width, height;
+ double refresh;
+ Bool match = FALSE;
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (mode->Flags & V_INTERLACE)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Interlaced modes not supported\n");
+ return FALSE;
+ }
+
+ width = mode->HDisplay;
+ height = mode->VDisplay;
+
+#if 0
+ ErrorF("mode->HDisplay = %d, pScrn->displayWidth = %d\n", mode->HDisplay, pScrn->displayWidth);
+ ErrorF("mode->VDisplay = %d, mode->HTotal = %d, mode->VTotal = %d\n",
+ mode->VDisplay, mode->HTotal, mode->VTotal);
+ ErrorF("mode->Clock = %d\n", mode->Clock);
+#endif
+
+ if (width == 640 && height == 480)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_640x480;
+ }
+ if (width == 800 && height == 600)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_800x600;
+ }
+ if (width == 960 && height == 720)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_960x720;
+ }
+ if (width == 1024 && height == 768)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1024x768;
+ }
+ if (width == 1280 && height == 1024)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1280x1024;
+ }
+ if (width == 1600 && height == 1200)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1600x1200;
+ }
+
+ if (!match)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Selected width = %d and height = %d is not supported by glide\n", width, height);
+ return FALSE;
+ }
+
+ refresh = (mode->Clock * 1.0e3)/((double)(mode->HTotal) *
+ (double)(mode->VTotal));
+#if 0
+ ErrorF("Calculated refresh rate for mode is %.2fHz\n",refresh);
+#endif
+
+ /* The Glide header files indicate there are a rather large number of
+ refresh rates available. In practice, though, only 60, 75 and 85Hz
+ seem to be available. If we try using another refresh rate, glide
+ will default to 60Hz. */
+ pGlide->grRefreshRate = GR_REFRESH_60Hz;
+ if (refresh > 74.0) pGlide->grRefreshRate = GR_REFRESH_75Hz;
+ if (refresh > 84.0) pGlide->grRefreshRate = GR_REFRESH_85Hz;
+
+
+ /* Initialize the video card */
+ pgrGlideInit();
+ pgrSstSelect(pGlide->SST_Index);
+
+ r = pgrSstWinOpen(0,
+ pGlide->grResolution,
+ pGlide->grRefreshRate,
+ GR_COLORFORMAT_ARGB,
+ GR_ORIGIN_UPPER_LEFT,
+ 2, 0);
+ if (!r)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "grSstWinOpen returned %d. "
+ "You are probably trying to use a resolution that is not supported by your hardware.", r);
+ return FALSE;
+ }
+
+ pgrRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ pgrClipWindow(0, 0, 1024, 768);
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+
+ if (!r)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not lock glide frame buffer\n");
+ return FALSE;
+ }
+
+ pGlide->Blanked = FALSE;
+ pGlide->GlideInitiated = TRUE;
+ return TRUE;
+}
+
+static void
+GLIDERestore(ScrnInfoPtr pScrn, Bool Closing)
+{
+ GLIDEPtr pGlide;
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (!(pGlide->GlideInitiated))
+ return;
+ pGlide->GlideInitiated = FALSE;
+ pGlide->Blanked = TRUE;
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+ if (!Closing || !(pGlide->OnAtExit))
+ pgrGlideShutdown();
+}
+
+
+#define GLIDE_FIND_FUNC(x) \
+ p##x = (p##x##_t)LoaderSymbol(#x); \
+ if (!p##x) \
+ { \
+ xf86Msg(X_ERROR, "Could not find " #x "() in libglide2x.so.\n"); \
+ return FALSE; \
+ }
+
+static int
+LoadGlide(void)
+{
+ GLIDE_FIND_FUNC(grSstQueryBoards);
+ GLIDE_FIND_FUNC(grGlideInit);
+ GLIDE_FIND_FUNC(grSstSelect);
+ GLIDE_FIND_FUNC(grSstWinOpen);
+ GLIDE_FIND_FUNC(grRenderBuffer);
+ GLIDE_FIND_FUNC(grClipWindow);
+ GLIDE_FIND_FUNC(grBufferClear);
+ GLIDE_FIND_FUNC(grLfbLock);
+ GLIDE_FIND_FUNC(grLfbUnlock);
+ GLIDE_FIND_FUNC(grGlideShutdown);
+ GLIDE_FIND_FUNC(grLfbWriteRegion);
+ return TRUE;
+}
+
+static void
+GLIDERefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ int Bpp;
+ unsigned char *src;
+ s32 x1, x2;
+
+ if (pGlide->Blanked) return;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ if (pScrn->bitsPerPixel == 16)
+ {
+ while(num--) {
+ /* We align to an even number of pixels so we won't have to copy
+ half-words over the PCI bus */
+ x1 = (pbox->x1) & ~1;
+ x2 = (pbox->x2 + 1) & ~1;
+ src = pGlide->ShadowPtr + (pbox->y1 * pGlide->ShadowPitch) +
+ (x1 * Bpp);
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_565, x2-x1, pbox->y2-pbox->y1, FALSE,
+ pGlide->ShadowPitch, src);
+#else
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_565, x2-x1, pbox->y2-pbox->y1,
+ pGlide->ShadowPitch, src);
+#endif
+ pbox++;
+ }
+ }
+ else
+ {
+ while(num--) {
+ x1 = pbox->x1;
+ x2 = pbox->x2;
+ src = pGlide->ShadowPtr + (pbox->y1 * pGlide->ShadowPitch) +
+ (pbox->x1 * Bpp);
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_888, x2-x1, pbox->y2-pbox->y1, FALSE,
+ pGlide->ShadowPitch, src);
+#else
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_888, x2-x1, pbox->y2-pbox->y1,
+ pGlide->ShadowPitch, src);
+#endif
+ pbox++;
+ }
+ }
+}
+
+
+/*
+ * GLIDEDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+static void
+GLIDEDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ static int oldmode = -1;
+
+#if 0
+ ErrorF("GLIDEDisplayPowerManagementSet: %d\n", PowerManagementMode);
+#endif
+
+ if (oldmode == DPMSModeOff && PowerManagementMode != DPMSModeOff)
+ {
+ GLIDEModeInit(pScrn, pScrn->currentMode);
+ }
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ pGlide->Blanked = FALSE;
+ GLIDERefreshAll(pScrn);
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ pGlide->Blanked = TRUE;
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+ break;
+ case DPMSModeOff:
+ GLIDERestore(pScrn, FALSE);
+ break;
+ }
+ oldmode = PowerManagementMode;
+}
+
+
+static void
+GLIDERefreshAll(ScrnInfoPtr pScrn)
+{
+ BoxRec box;
+ box.x1 = 0;
+ box.x2 = pScrn->virtualX;
+ box.y1 = 0;
+ box.y2 = pScrn->virtualY;
+ GLIDERefreshArea(pScrn, 1, &box);
+}
+