aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xfree86/common
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/xfree86/common')
-rw-r--r--xorg-server/hw/xfree86/common/xf86.h708
-rw-r--r--xorg-server/hw/xfree86/common/xf86AutoConfig.c1276
-rw-r--r--xorg-server/hw/xfree86/common/xf86Bus.c1366
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c5172
-rw-r--r--xorg-server/hw/xfree86/common/xf86Configure.c1784
-rw-r--r--xorg-server/hw/xfree86/common/xf86Cursor.c1724
-rw-r--r--xorg-server/hw/xfree86/common/xf86DGA.c2454
-rw-r--r--xorg-server/hw/xfree86/common/xf86DPMS.c400
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c4
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c5176
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c3644
-rw-r--r--xorg-server/hw/xfree86/common/xf86Mode.c4134
-rw-r--r--xorg-server/hw/xfree86/common/xf86Option.c1724
-rw-r--r--xorg-server/hw/xfree86/common/xf86Privstr.h343
-rw-r--r--xorg-server/hw/xfree86/common/xf86RandR.c918
-rw-r--r--xorg-server/hw/xfree86/common/xf86ShowOpts.c256
-rw-r--r--xorg-server/hw/xfree86/common/xf86VGAarbiter.c2202
-rw-r--r--xorg-server/hw/xfree86/common/xf86VidMode.c1334
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c2568
-rw-r--r--xorg-server/hw/xfree86/common/xf86cmap.c2332
-rw-r--r--xorg-server/hw/xfree86/common/xf86fbman.c2876
-rw-r--r--xorg-server/hw/xfree86/common/xf86pciBus.c846
-rw-r--r--xorg-server/hw/xfree86/common/xf86sbusBus.c1376
-rw-r--r--xorg-server/hw/xfree86/common/xf86xv.c4203
-rw-r--r--xorg-server/hw/xfree86/common/xf86xvmc.c458
-rw-r--r--xorg-server/hw/xfree86/common/xisb.c348
26 files changed, 24812 insertions, 24814 deletions
diff --git a/xorg-server/hw/xfree86/common/xf86.h b/xorg-server/hw/xfree86/common/xf86.h
index e9266abd4..cddca37a3 100644
--- a/xorg-server/hw/xfree86/common/xf86.h
+++ b/xorg-server/hw/xfree86/common/xf86.h
@@ -1,354 +1,354 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains declarations for public XFree86 functions and variables,
- * and definitions of public macros.
- *
- * "public" means available to video drivers.
- */
-
-#ifndef _XF86_H
-#define _XF86_H
-
-#if HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#elif HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <pciaccess.h>
-
-#include "xf86str.h"
-#include "xf86Opt.h"
-#include <X11/Xfuncproto.h>
-#include <stdarg.h>
-#ifdef RANDR
-#include <X11/extensions/randr.h>
-#endif
-
-#include "propertyst.h"
-
-/* General parameters */
-extern _X_EXPORT int xf86DoConfigure;
-extern _X_EXPORT int xf86DoShowOptions;
-extern _X_EXPORT Bool xf86DoConfigurePass1;
-extern _X_EXPORT DevPrivateKey xf86ScreenKey;
-extern _X_EXPORT DevPrivateKey xf86CreateRootWindowKey;
-extern _X_EXPORT DevPrivateKey xf86PixmapKey;
-extern _X_EXPORT ScrnInfoPtr *xf86Screens; /* List of pointers to ScrnInfoRecs */
-extern _X_EXPORT const unsigned char byte_reversed[256];
-extern _X_EXPORT Bool pciSlotClaimed;
-extern _X_EXPORT Bool fbSlotClaimed;
-#if defined(__sparc__) || defined(__sparc)
-extern _X_EXPORT Bool sbusSlotClaimed;
-#endif
-extern _X_EXPORT confDRIRec xf86ConfigDRI;
-extern _X_EXPORT Bool xf86inSuspend;
-extern _X_EXPORT Bool xf86DRI2Enabled(void);
-
-extern _X_EXPORT Bool VTSwitchEnabled; /* kbd driver */
-
-#define XF86SCRNINFO(p) ((ScrnInfoPtr)dixLookupPrivate(&(p)->devPrivates, \
- xf86ScreenKey))
-#define XF86FLIP_PIXELS() \
- do { \
- if (xf86GetFlipPixels()) { \
- pScreen->whitePixel = (pScreen->whitePixel) ? 0 : 1; \
- pScreen->blackPixel = (pScreen->blackPixel) ? 0 : 1; \
- } \
- while (0)
-
-#define BOOLTOSTRING(b) ((b) ? "TRUE" : "FALSE")
-
-#define PIX24TOBPP(p) (((p) == Pix24Use24) ? 24 : \
- (((p) == Pix24Use32) ? 32 : 0))
-
-/* Function Prototypes */
-#ifndef _NO_XF86_PROTOTYPES
-
-/* xf86Bus.c */
-
-extern _X_EXPORT Bool xf86CheckPciSlot( const struct pci_device * );
-extern _X_EXPORT int xf86ClaimPciSlot( struct pci_device *, DriverPtr drvp,
- int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *);
-extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device,
- int *func);
-extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func);
-extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer);
-extern _X_EXPORT int xf86GetFbInfoForScreen(int scrnIndex);
-extern _X_EXPORT int xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT int xf86ClaimNoSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT void xf86EnableAccess(ScrnInfoPtr pScrn);
-extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci);
-/* new RAC */
-extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp);
-extern _X_EXPORT void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
-extern _X_EXPORT void xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex,
- int instance);
-extern _X_EXPORT int xf86GetNumEntityInstances(int entityIndex);
-extern _X_EXPORT GDevPtr xf86GetDevFromEntity(int entityIndex, int instance);
-extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
-extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex);
-extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex);
-extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
- EntityProc enter, EntityProc leave, pointer);
-extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base);
-extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex);
-extern _X_EXPORT void xf86EnterServerState(xf86State state);
-extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex);
-
-extern _X_EXPORT int xf86GetLastScrnFlag(int entityIndex);
-extern _X_EXPORT void xf86SetLastScrnFlag(int entityIndex, int scrnIndex);
-extern _X_EXPORT Bool xf86IsEntityShared(int entityIndex);
-extern _X_EXPORT void xf86SetEntityShared(int entityIndex);
-extern _X_EXPORT Bool xf86IsEntitySharable(int entityIndex);
-extern _X_EXPORT void xf86SetEntitySharable(int entityIndex);
-extern _X_EXPORT Bool xf86IsPrimInitDone(int entityIndex);
-extern _X_EXPORT void xf86SetPrimInitDone(int entityIndex);
-extern _X_EXPORT void xf86ClearPrimInitDone(int entityIndex);
-extern _X_EXPORT int xf86AllocateEntityPrivateIndex(void);
-extern _X_EXPORT DevUnion *xf86GetEntityPrivate(int entityIndex, int privIndex);
-
-/* xf86Configure.c */
-extern _X_EXPORT GDevPtr xf86AddBusDeviceToConfigure(const char *driver, BusType bus,
- void *busData, int chipset);
-
-/* xf86Cursor.c */
-
-extern _X_EXPORT void xf86LockZoom(ScreenPtr pScreen, int lock);
-extern _X_EXPORT void xf86InitViewport(ScrnInfoPtr pScr);
-extern _X_EXPORT void xf86SetViewport(ScreenPtr pScreen, int x, int y);
-extern _X_EXPORT void xf86ZoomViewport(ScreenPtr pScreen, int zoom);
-extern _X_EXPORT Bool xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern _X_EXPORT void *xf86GetPointerScreenFuncs(void);
-extern _X_EXPORT void xf86InitOrigins(void);
-extern _X_EXPORT void xf86ReconfigureLayout(void);
-
-/* xf86cvt.c */
-extern _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
- Bool Reduced, Bool Interlaced);
-
-/* xf86DPMS.c */
-
-extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
-
-#ifdef DPMSExtension
-extern _X_EXPORT int DPMSSet(ClientPtr client, int level);
-extern _X_EXPORT Bool DPMSSupported(void);
-#endif
-
-
-/* xf86DGA.c */
-
-#ifdef XFreeXDGA
-extern _X_EXPORT Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes,
- int num);
-extern _X_EXPORT Bool DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num);
-extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
-#endif
-
-/* xf86Events.c */
-
-extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
-extern _X_EXPORT pointer xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data);
-extern _X_EXPORT int xf86RemoveInputHandler(pointer handler);
-extern _X_EXPORT void xf86DisableInputHandler(pointer handler);
-extern _X_EXPORT void xf86EnableInputHandler(pointer handler);
-extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data);
-extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86InterceptSignals(int *signo);
-extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void));
-extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
-extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
-extern _X_EXPORT void xf86PrintBacktrace(void);
-
-/* xf86Helper.c */
-
-extern _X_EXPORT void xf86AddDriver(DriverPtr driver, pointer module, int flags);
-extern _X_EXPORT void xf86DeleteDriver(int drvIndex);
-extern _X_EXPORT ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags);
-extern _X_EXPORT void xf86DeleteScreen(int scrnIndex, int flags);
-extern _X_EXPORT int xf86AllocateScrnInfoPrivateIndex(void);
-extern _X_EXPORT Bool xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad);
-extern _X_EXPORT Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, int fbbpp,
- int depth24flags);
-extern _X_EXPORT void xf86PrintDepthBpp(ScrnInfoPtr scrp);
-extern _X_EXPORT Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
-extern _X_EXPORT Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
-extern _X_EXPORT Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma newGamma);
-extern _X_EXPORT void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
-extern _X_EXPORT void xf86SetBlackWhitePixels(ScreenPtr pScreen);
-extern _X_EXPORT void xf86EnableDisableFBAccess(int scrnIndex, Bool enable);
-extern _X_EXPORT void xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb,
- const char *format, va_list args);
-extern _X_EXPORT void xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
- const char *format, ...) _printf_attribute(4,5);
-extern _X_EXPORT void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
- _printf_attribute(3,4);
-extern _X_EXPORT void xf86MsgVerb(MessageType type, int verb, const char *format, ...)
- _printf_attribute(3,4);
-extern _X_EXPORT void xf86Msg(MessageType type, const char *format, ...) _printf_attribute(2,3);
-extern _X_EXPORT void xf86ErrorFVerb(int verb, const char *format, ...) _printf_attribute(2,3);
-extern _X_EXPORT void xf86ErrorF(const char *format, ...) _printf_attribute(1,2);
-extern _X_EXPORT const char *xf86TokenToString(SymTabPtr table, int token);
-extern _X_EXPORT int xf86StringToToken(SymTabPtr table, const char *string);
-extern _X_EXPORT void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
-extern _X_EXPORT void xf86PrintChipsets(const char *drvname, const char *drvmsg,
- SymTabPtr chips);
-extern _X_EXPORT int xf86MatchDevice(const char *drivername, GDevPtr **driversectlist);
-extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, int vendorID,
- SymTabPtr chipsets, PciChipsets *PCIchipsets,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities);
-extern _X_EXPORT void xf86GetClocks(ScrnInfoPtr pScrn, int num,
- Bool (*ClockFunc)(ScrnInfoPtr, int),
- void (*ProtectRegs)(ScrnInfoPtr, Bool),
- void (*BlankScreen)(ScrnInfoPtr, Bool),
- IOADDRESS vertsyncreg, int maskval,
- int knownclkindex, int knownclkvalue);
-extern _X_EXPORT const char *xf86GetVisualName(int visual);
-extern _X_EXPORT int xf86GetVerbosity(void);
-extern _X_EXPORT Pix24Flags xf86GetPix24(void);
-extern _X_EXPORT int xf86GetDepth(void);
-extern _X_EXPORT rgb xf86GetWeight(void);
-extern _X_EXPORT Gamma xf86GetGamma(void);
-extern _X_EXPORT Bool xf86GetFlipPixels(void);
-extern _X_EXPORT const char *xf86GetServerName(void);
-extern _X_EXPORT Bool xf86ServerIsExiting(void);
-extern _X_EXPORT Bool xf86ServerIsResetting(void);
-extern _X_EXPORT Bool xf86ServerIsInitialising(void);
-extern _X_EXPORT Bool xf86ServerIsOnlyDetecting(void);
-extern _X_EXPORT Bool xf86CaughtSignal(void);
-extern _X_EXPORT Bool xf86GetVidModeAllowNonLocal(void);
-extern _X_EXPORT Bool xf86GetVidModeEnabled(void);
-extern _X_EXPORT Bool xf86GetModInDevAllowNonLocal(void);
-extern _X_EXPORT Bool xf86GetModInDevEnabled(void);
-extern _X_EXPORT Bool xf86GetAllowMouseOpenFail(void);
-extern _X_EXPORT Bool xf86IsPc98(void);
-extern _X_EXPORT void xf86DisableRandR(void);
-extern _X_EXPORT CARD32 xorgGetVersion(void);
-extern _X_EXPORT CARD32 xf86GetModuleVersion(pointer module);
-extern _X_EXPORT pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
-extern _X_EXPORT pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
-extern _X_EXPORT pointer xf86LoadOneModule(char *name, pointer optlist);
-extern _X_EXPORT void xf86UnloadSubModule(pointer mod);
-extern _X_EXPORT Bool xf86LoaderCheckSymbol(const char *name);
-extern _X_EXPORT void xf86SetBackingStore(ScreenPtr pScreen);
-extern _X_EXPORT void xf86SetSilkenMouse(ScreenPtr pScreen);
-extern _X_EXPORT pointer xf86FindXvOptions(int scrnIndex, int adapt_index, char *port_name,
- char **adaptor_name, pointer *adaptor_options);
-extern _X_EXPORT void xf86GetOS(const char **name, int *major, int *minor, int *teeny);
-extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag,
- int entityIndex,PciChipsets *p_chip,
- void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-extern _X_EXPORT ScrnInfoPtr xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
- int entityIndex, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-
-/* Obsolete! don't use */
-extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
- int entityIndex,PciChipsets *p_chip,
- void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-
-extern _X_EXPORT Bool xf86IsScreenPrimary(int scrnIndex);
-extern _X_EXPORT int xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
- int format, unsigned long len,
- pointer value);
-extern _X_EXPORT Bool xf86IsUnblank(int mode);
-
-/* xf86Init.c */
-
-extern _X_EXPORT PixmapFormatPtr xf86GetPixFormat(ScrnInfoPtr pScrn, int depth);
-extern _X_EXPORT int xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth);
-
-/* xf86Mode.c */
-
-extern _X_EXPORT int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- int DivFactor, int MulFactor, int *divider);
-extern _X_EXPORT const char *xf86ModeStatusToString(ModeStatus status);
-extern _X_EXPORT ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- ClockRangePtr clockRanges, LookupModeFlags strategy);
-extern _X_EXPORT ModeStatus xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor);
-extern _X_EXPORT ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- ClockRangePtr clockRanges,
- LookupModeFlags strategy,
- int maxPitch, int virtualX,
- int virtualY);
-extern _X_EXPORT ModeStatus xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- int flags);
-extern _X_EXPORT int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch,
- int minHeight, int maxHeight, int pitchInc,
- int virtualX, int virtualY, int apertureSize,
- LookupModeFlags strategy);
-extern _X_EXPORT void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
-extern _X_EXPORT void xf86PruneDriverModes(ScrnInfoPtr scrp);
-extern _X_EXPORT void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
-extern _X_EXPORT void xf86PrintModes(ScrnInfoPtr scrp);
-extern _X_EXPORT void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges);
-extern _X_EXPORT double xf86ModeHSync(const DisplayModeRec *mode);
-extern _X_EXPORT double xf86ModeVRefresh(const DisplayModeRec *mode);
-extern _X_EXPORT void xf86SetModeDefaultName(DisplayModePtr mode);
-extern _X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-extern _X_EXPORT DisplayModePtr xf86DuplicateMode(const DisplayModeRec *pMode);
-extern _X_EXPORT DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
-extern _X_EXPORT Bool xf86ModesEqual(const DisplayModeRec *pMode1,
- const DisplayModeRec *pMode2);
-extern _X_EXPORT void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-extern _X_EXPORT DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
-
-/* xf86Option.c */
-
-extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts);
-
-
-/* xf86RandR.c */
-#ifdef RANDR
-extern _X_EXPORT Bool xf86RandRInit (ScreenPtr pScreen);
-extern _X_EXPORT Rotation xf86GetRotation(ScreenPtr pScreen);
-extern _X_EXPORT Bool xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
- int newvirtX, int newvirtY,
- int newmmWidth, int newmmHeight, Bool resetMode);
-#endif
-
-/* xf86VidModeExtentionInit.c */
-
-extern _X_EXPORT Bool VidModeExtensionInit(ScreenPtr pScreen);
-
-#endif /* _NO_XF86_PROTOTYPES */
-
-#endif /* _XF86_H */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains declarations for public XFree86 functions and variables,
+ * and definitions of public macros.
+ *
+ * "public" means available to video drivers.
+ */
+
+#ifndef _XF86_H
+#define _XF86_H
+
+#if HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#elif HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <pciaccess.h>
+
+#include "xf86str.h"
+#include "xf86Opt.h"
+#include <X11/Xfuncproto.h>
+#include <stdarg.h>
+#ifdef RANDR
+#include <X11/extensions/randr.h>
+#endif
+
+#include "propertyst.h"
+
+/* General parameters */
+extern _X_EXPORT int xf86DoConfigure;
+extern _X_EXPORT int xf86DoShowOptions;
+extern _X_EXPORT Bool xf86DoConfigurePass1;
+extern _X_EXPORT DevPrivateKey xf86ScreenKey;
+extern _X_EXPORT DevPrivateKey xf86CreateRootWindowKey;
+extern _X_EXPORT DevPrivateKey xf86PixmapKey;
+extern _X_EXPORT ScrnInfoPtr *xf86Screens; /* List of pointers to ScrnInfoRecs */
+extern _X_EXPORT const unsigned char byte_reversed[256];
+extern _X_EXPORT Bool pciSlotClaimed;
+extern _X_EXPORT Bool fbSlotClaimed;
+#if defined(__sparc__) || defined(__sparc)
+extern _X_EXPORT Bool sbusSlotClaimed;
+#endif
+extern _X_EXPORT confDRIRec xf86ConfigDRI;
+extern _X_EXPORT Bool xf86inSuspend;
+extern _X_EXPORT Bool xf86DRI2Enabled(void);
+
+extern _X_EXPORT Bool VTSwitchEnabled; /* kbd driver */
+
+#define XF86SCRNINFO(p) ((ScrnInfoPtr)dixLookupPrivate(&(p)->devPrivates, \
+ xf86ScreenKey))
+#define XF86FLIP_PIXELS() \
+ do { \
+ if (xf86GetFlipPixels()) { \
+ pScreen->whitePixel = (pScreen->whitePixel) ? 0 : 1; \
+ pScreen->blackPixel = (pScreen->blackPixel) ? 0 : 1; \
+ } \
+ while (0)
+
+#define BOOLTOSTRING(b) ((b) ? "TRUE" : "FALSE")
+
+#define PIX24TOBPP(p) (((p) == Pix24Use24) ? 24 : \
+ (((p) == Pix24Use32) ? 32 : 0))
+
+/* Function Prototypes */
+#ifndef _NO_XF86_PROTOTYPES
+
+/* xf86Bus.c */
+
+extern _X_EXPORT Bool xf86CheckPciSlot( const struct pci_device * );
+extern _X_EXPORT int xf86ClaimPciSlot( struct pci_device *, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *);
+extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device,
+ int *func);
+extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func);
+extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer);
+extern _X_EXPORT int xf86GetFbInfoForScreen(int scrnIndex);
+extern _X_EXPORT int xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT int xf86ClaimNoSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT void xf86EnableAccess(ScrnInfoPtr pScrn);
+extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci);
+/* new RAC */
+extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp);
+extern _X_EXPORT void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
+extern _X_EXPORT void xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex,
+ int instance);
+extern _X_EXPORT int xf86GetNumEntityInstances(int entityIndex);
+extern _X_EXPORT GDevPtr xf86GetDevFromEntity(int entityIndex, int instance);
+extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
+extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex);
+extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex);
+extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer);
+extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base);
+extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex);
+extern _X_EXPORT void xf86EnterServerState(xf86State state);
+extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex);
+
+extern _X_EXPORT int xf86GetLastScrnFlag(int entityIndex);
+extern _X_EXPORT void xf86SetLastScrnFlag(int entityIndex, int scrnIndex);
+extern _X_EXPORT Bool xf86IsEntityShared(int entityIndex);
+extern _X_EXPORT void xf86SetEntityShared(int entityIndex);
+extern _X_EXPORT Bool xf86IsEntitySharable(int entityIndex);
+extern _X_EXPORT void xf86SetEntitySharable(int entityIndex);
+extern _X_EXPORT Bool xf86IsPrimInitDone(int entityIndex);
+extern _X_EXPORT void xf86SetPrimInitDone(int entityIndex);
+extern _X_EXPORT void xf86ClearPrimInitDone(int entityIndex);
+extern _X_EXPORT int xf86AllocateEntityPrivateIndex(void);
+extern _X_EXPORT DevUnion *xf86GetEntityPrivate(int entityIndex, int privIndex);
+
+/* xf86Configure.c */
+extern _X_EXPORT GDevPtr xf86AddBusDeviceToConfigure(const char *driver, BusType bus,
+ void *busData, int chipset);
+
+/* xf86Cursor.c */
+
+extern _X_EXPORT void xf86LockZoom(ScreenPtr pScreen, int lock);
+extern _X_EXPORT void xf86InitViewport(ScrnInfoPtr pScr);
+extern _X_EXPORT void xf86SetViewport(ScreenPtr pScreen, int x, int y);
+extern _X_EXPORT void xf86ZoomViewport(ScreenPtr pScreen, int zoom);
+extern _X_EXPORT Bool xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
+extern _X_EXPORT void *xf86GetPointerScreenFuncs(void);
+extern _X_EXPORT void xf86InitOrigins(void);
+extern _X_EXPORT void xf86ReconfigureLayout(void);
+
+/* xf86cvt.c */
+extern _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+ Bool Reduced, Bool Interlaced);
+
+/* xf86DPMS.c */
+
+extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
+
+#ifdef DPMSExtension
+extern _X_EXPORT int DPMSSet(ClientPtr client, int level);
+extern _X_EXPORT Bool DPMSSupported(void);
+#endif
+
+
+/* xf86DGA.c */
+
+#ifdef XFreeXDGA
+extern _X_EXPORT Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes,
+ int num);
+extern _X_EXPORT Bool DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num);
+extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
+#endif
+
+/* xf86Events.c */
+
+extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
+extern _X_EXPORT pointer xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data);
+extern _X_EXPORT int xf86RemoveInputHandler(pointer handler);
+extern _X_EXPORT void xf86DisableInputHandler(pointer handler);
+extern _X_EXPORT void xf86EnableInputHandler(pointer handler);
+extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data);
+extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86InterceptSignals(int *signo);
+extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void));
+extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
+extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
+extern _X_EXPORT void xf86PrintBacktrace(void);
+
+/* xf86Helper.c */
+
+extern _X_EXPORT void xf86AddDriver(DriverPtr driver, pointer module, int flags);
+extern _X_EXPORT void xf86DeleteDriver(int drvIndex);
+extern _X_EXPORT ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags);
+extern _X_EXPORT void xf86DeleteScreen(int scrnIndex, int flags);
+extern _X_EXPORT int xf86AllocateScrnInfoPrivateIndex(void);
+extern _X_EXPORT Bool xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad);
+extern _X_EXPORT Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, int fbbpp,
+ int depth24flags);
+extern _X_EXPORT void xf86PrintDepthBpp(ScrnInfoPtr scrp);
+extern _X_EXPORT Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
+extern _X_EXPORT Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
+extern _X_EXPORT Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma newGamma);
+extern _X_EXPORT void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
+extern _X_EXPORT void xf86SetBlackWhitePixels(ScreenPtr pScreen);
+extern _X_EXPORT void xf86EnableDisableFBAccess(int scrnIndex, Bool enable);
+extern _X_EXPORT void xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ const char *format, va_list args);
+extern _X_EXPORT void xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5);
+extern _X_EXPORT void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+ _X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT void xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+ _X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT void xf86Msg(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
+extern _X_EXPORT void xf86ErrorFVerb(int verb, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
+extern _X_EXPORT void xf86ErrorF(const char *format, ...) _X_ATTRIBUTE_PRINTF(1,2);
+extern _X_EXPORT const char *xf86TokenToString(SymTabPtr table, int token);
+extern _X_EXPORT int xf86StringToToken(SymTabPtr table, const char *string);
+extern _X_EXPORT void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
+extern _X_EXPORT void xf86PrintChipsets(const char *drvname, const char *drvmsg,
+ SymTabPtr chips);
+extern _X_EXPORT int xf86MatchDevice(const char *drivername, GDevPtr **driversectlist);
+extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, int vendorID,
+ SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities);
+extern _X_EXPORT void xf86GetClocks(ScrnInfoPtr pScrn, int num,
+ Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool),
+ IOADDRESS vertsyncreg, int maskval,
+ int knownclkindex, int knownclkvalue);
+extern _X_EXPORT const char *xf86GetVisualName(int visual);
+extern _X_EXPORT int xf86GetVerbosity(void);
+extern _X_EXPORT Pix24Flags xf86GetPix24(void);
+extern _X_EXPORT int xf86GetDepth(void);
+extern _X_EXPORT rgb xf86GetWeight(void);
+extern _X_EXPORT Gamma xf86GetGamma(void);
+extern _X_EXPORT Bool xf86GetFlipPixels(void);
+extern _X_EXPORT const char *xf86GetServerName(void);
+extern _X_EXPORT Bool xf86ServerIsExiting(void);
+extern _X_EXPORT Bool xf86ServerIsResetting(void);
+extern _X_EXPORT Bool xf86ServerIsInitialising(void);
+extern _X_EXPORT Bool xf86ServerIsOnlyDetecting(void);
+extern _X_EXPORT Bool xf86CaughtSignal(void);
+extern _X_EXPORT Bool xf86GetVidModeAllowNonLocal(void);
+extern _X_EXPORT Bool xf86GetVidModeEnabled(void);
+extern _X_EXPORT Bool xf86GetModInDevAllowNonLocal(void);
+extern _X_EXPORT Bool xf86GetModInDevEnabled(void);
+extern _X_EXPORT Bool xf86GetAllowMouseOpenFail(void);
+extern _X_EXPORT Bool xf86IsPc98(void);
+extern _X_EXPORT void xf86DisableRandR(void);
+extern _X_EXPORT CARD32 xorgGetVersion(void);
+extern _X_EXPORT CARD32 xf86GetModuleVersion(pointer module);
+extern _X_EXPORT pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
+extern _X_EXPORT pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
+extern _X_EXPORT pointer xf86LoadOneModule(char *name, pointer optlist);
+extern _X_EXPORT void xf86UnloadSubModule(pointer mod);
+extern _X_EXPORT Bool xf86LoaderCheckSymbol(const char *name);
+extern _X_EXPORT void xf86SetBackingStore(ScreenPtr pScreen);
+extern _X_EXPORT void xf86SetSilkenMouse(ScreenPtr pScreen);
+extern _X_EXPORT pointer xf86FindXvOptions(int scrnIndex, int adapt_index, char *port_name,
+ char **adaptor_name, pointer *adaptor_options);
+extern _X_EXPORT void xf86GetOS(const char **name, int *major, int *minor, int *teeny);
+extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag,
+ int entityIndex,PciChipsets *p_chip,
+ void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+extern _X_EXPORT ScrnInfoPtr xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
+ int entityIndex, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+
+/* Obsolete! don't use */
+extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
+ int entityIndex,PciChipsets *p_chip,
+ void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+
+extern _X_EXPORT Bool xf86IsScreenPrimary(int scrnIndex);
+extern _X_EXPORT int xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
+ int format, unsigned long len,
+ pointer value);
+extern _X_EXPORT Bool xf86IsUnblank(int mode);
+
+/* xf86Init.c */
+
+extern _X_EXPORT PixmapFormatPtr xf86GetPixFormat(ScrnInfoPtr pScrn, int depth);
+extern _X_EXPORT int xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth);
+
+/* xf86Mode.c */
+
+extern _X_EXPORT int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ int DivFactor, int MulFactor, int *divider);
+extern _X_EXPORT const char *xf86ModeStatusToString(ModeStatus status);
+extern _X_EXPORT ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ ClockRangePtr clockRanges, LookupModeFlags strategy);
+extern _X_EXPORT ModeStatus xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor);
+extern _X_EXPORT ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ ClockRangePtr clockRanges,
+ LookupModeFlags strategy,
+ int maxPitch, int virtualX,
+ int virtualY);
+extern _X_EXPORT ModeStatus xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ int flags);
+extern _X_EXPORT int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch,
+ int minHeight, int maxHeight, int pitchInc,
+ int virtualX, int virtualY, int apertureSize,
+ LookupModeFlags strategy);
+extern _X_EXPORT void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
+extern _X_EXPORT void xf86PruneDriverModes(ScrnInfoPtr scrp);
+extern _X_EXPORT void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
+extern _X_EXPORT void xf86PrintModes(ScrnInfoPtr scrp);
+extern _X_EXPORT void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges);
+extern _X_EXPORT double xf86ModeHSync(const DisplayModeRec *mode);
+extern _X_EXPORT double xf86ModeVRefresh(const DisplayModeRec *mode);
+extern _X_EXPORT void xf86SetModeDefaultName(DisplayModePtr mode);
+extern _X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+extern _X_EXPORT DisplayModePtr xf86DuplicateMode(const DisplayModeRec *pMode);
+extern _X_EXPORT DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+extern _X_EXPORT Bool xf86ModesEqual(const DisplayModeRec *pMode1,
+ const DisplayModeRec *pMode2);
+extern _X_EXPORT void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+extern _X_EXPORT DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+
+/* xf86Option.c */
+
+extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts);
+
+
+/* xf86RandR.c */
+#ifdef RANDR
+extern _X_EXPORT Bool xf86RandRInit (ScreenPtr pScreen);
+extern _X_EXPORT Rotation xf86GetRotation(ScreenPtr pScreen);
+extern _X_EXPORT Bool xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
+ int newvirtX, int newvirtY,
+ int newmmWidth, int newmmHeight, Bool resetMode);
+#endif
+
+/* xf86VidModeExtentionInit.c */
+
+extern _X_EXPORT Bool VidModeExtensionInit(ScreenPtr pScreen);
+
+#endif /* _NO_XF86_PROTOTYPES */
+
+#endif /* _XF86_H */
diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
index 7b836b00d..88891e5a7 100644
--- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c
+++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
@@ -1,638 +1,638 @@
-/*
- * Copyright 2003 by David H. Dawes.
- * Copyright 2003 by X-Oz Technologies.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- *
- * Author: David Dawes <dawes@XFree86.Org>.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "xf86Config.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#ifdef __sparc__
-# include "xf86sbusBus.h"
-#endif
-#include "dirent.h"
-
-#ifdef sun
-# include <sys/visual_io.h>
-# include <ctype.h>
-#endif
-
-/* Sections for the default built-in configuration. */
-
-#define BUILTIN_DEVICE_NAME \
- "\"Builtin Default %s Device %d\""
-
-#define BUILTIN_DEVICE_SECTION_PRE \
- "Section \"Device\"\n" \
- "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
- "\tDriver\t\"%s\"\n"
-
-#define BUILTIN_DEVICE_SECTION_POST \
- "EndSection\n\n"
-
-#define BUILTIN_DEVICE_SECTION \
- BUILTIN_DEVICE_SECTION_PRE \
- BUILTIN_DEVICE_SECTION_POST
-
-#define BUILTIN_SCREEN_NAME \
- "\"Builtin Default %s Screen %d\""
-
-#define BUILTIN_SCREEN_SECTION \
- "Section \"Screen\"\n" \
- "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
- "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
- "EndSection\n\n"
-
-#define BUILTIN_LAYOUT_SECTION_PRE \
- "Section \"ServerLayout\"\n" \
- "\tIdentifier\t\"Builtin Default Layout\"\n"
-
-#define BUILTIN_LAYOUT_SCREEN_LINE \
- "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
-
-#define BUILTIN_LAYOUT_SECTION_POST \
- "EndSection\n\n"
-
-static const char **builtinConfig = NULL;
-static int builtinLines = 0;
-
-static void listPossibleVideoDrivers(char *matches[], int nmatches);
-
-/*
- * A built-in config file is stored as an array of strings, with each string
- * representing a single line. AppendToConfig() breaks up the string "s"
- * into lines, and appends those lines it to builtinConfig.
- */
-
-static void
-AppendToList(const char *s, const char ***list, int *lines)
-{
- char *str, *newstr, *p;
-
- str = xnfstrdup(s);
- for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
- (*lines)++;
- *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
- newstr = xnfalloc(strlen(p) + 2);
- strcpy(newstr, p);
- strcat(newstr, "\n");
- (*list)[*lines - 1] = newstr;
- (*list)[*lines] = NULL;
- }
- xfree(str);
-}
-
-static void
-FreeList(const char ***list, int *lines)
-{
- int i;
-
- for (i = 0; i < *lines; i++) {
- if ((*list)[i])
- xfree((*list)[i]);
- }
- xfree(*list);
- *list = NULL;
- *lines = 0;
-}
-
-static void
-FreeConfig(void)
-{
- FreeList(&builtinConfig, &builtinLines);
-}
-
-static void
-AppendToConfig(const char *s)
-{
- AppendToList(s, &builtinConfig, &builtinLines);
-}
-
-static int
-videoPtrToDriverList(struct pci_device *dev,
- char *returnList[], int returnListMax)
-{
- int i;
- /* Add more entries here if we ever return more than 4 drivers for
- any device */
- char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
-
- switch (dev->vendor_id)
- {
- /* AMD Geode LX */
- case 0x1022:
- if (dev->device_id == 0x2081)
- driverList[0] = "geode";
- break;
- /* older Geode products acquired by AMD still carry an NSC vendor_id */
- case 0x100b:
- if (dev->device_id == 0x0030) {
- /* NSC Geode GX2 specifically */
- driverList[0] = "geode";
- /* GX2 support started its life in the NSC tree and was later
- forked by AMD for GEODE so we keep it as a backup */
- driverList[1] = "nsc";
- } else
- /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
- driverList[0] = "nsc";
- break;
- /* Cyrix Geode GX1 */
- case 0x1078:
- if (dev->device_id == 0x0104)
- driverList[0] = "cyrix";
- break;
- case 0x1142: driverList[0] = "apm"; break;
- case 0xedd8: driverList[0] = "ark"; break;
- case 0x1a03: driverList[0] = "ast"; break;
- case 0x1002: driverList[0] = "ati"; break;
- case 0x102c: driverList[0] = "chips"; break;
- case 0x1013: driverList[0] = "cirrus"; break;
- case 0x3d3d: driverList[0] = "glint"; break;
- case 0x105d: driverList[0] = "i128"; break;
- case 0x8086:
- if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
- driverList[0] = "i740";
- } else if (dev->device_id == 0x8108) {
- break; /* "hooray" for poulsbo */
- } else {
- driverList[0] = "intel";
- }
- break;
- case 0x102b: driverList[0] = "mga"; break;
- case 0x10c8: driverList[0] = "neomagic"; break;
- case 0x10de: case 0x12d2: driverList[0] = "nv"; break;
- case 0x1106: driverList[0] = "openchrome"; break;
- case 0x1b36: driverList[0] = "qxl"; break;
- case 0x1163: driverList[0] = "rendition"; break;
- case 0x5333:
- switch (dev->device_id)
- {
- case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
- case 0x8812: case 0x8814: case 0x8901:
- driverList[0] = "s3"; break;
- case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
- case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
- driverList[0] = "s3virge"; break;
- default:
- driverList[0] = "savage"; break;
- }
- break;
- case 0x1039: driverList[0] = "sis"; break;
- case 0x126f: driverList[0] = "siliconmotion"; break;
- case 0x121a:
- if (dev->device_id < 0x0003)
- driverList[0] = "voodoo";
- else
- driverList[0] = "tdfx";
- break;
- case 0x1011: driverList[0] = "tga"; break;
- case 0x1023: driverList[0] = "trident"; break;
- case 0x100c: driverList[0] = "tseng"; break;
- case 0x80ee: driverList[0] = "vboxvideo"; break;
- case 0x15ad: driverList[0] = "vmware"; break;
- case 0x18ca:
- if (dev->device_id == 0x47)
- driverList[0] = "xgixp";
- else
- driverList[0] = "xgi";
- break;
- default: break;
- }
- for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) {
- returnList[i] = xnfstrdup(driverList[i]);
- }
- return i; /* Number of entries added */
-}
-
-Bool
-xf86AutoConfig(void)
-{
- char *deviceList[20];
- char **p;
- const char **cp;
- char buf[1024];
- ConfigStatus ret;
-
- listPossibleVideoDrivers(deviceList, 20);
-
- for (p = deviceList; *p; p++) {
- snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
- AppendToConfig(buf);
- snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
- AppendToConfig(buf);
- }
-
- AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
- for (p = deviceList; *p; p++) {
- snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
- AppendToConfig(buf);
- }
- AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
-
- for (p = deviceList; *p; p++) {
- xfree(*p);
- }
-
- xf86MsgVerb(X_DEFAULT, 0,
- "Using default built-in configuration (%d lines)\n",
- builtinLines);
-
- xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
- for (cp = builtinConfig; *cp; cp++)
- xf86ErrorFVerb(3, "\t%s", *cp);
- xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
-
- xf86initConfigFiles();
- xf86setBuiltinConfig(builtinConfig);
- ret = xf86HandleConfigFile(TRUE);
- FreeConfig();
-
- if (ret != CONFIG_OK)
- xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
-
- return (ret == CONFIG_OK);
-}
-
-static int
-xchomp(char *line)
-{
- size_t len = 0;
-
- if (!line) {
- return 1;
- }
-
- len = strlen(line);
- if (line[len - 1] == '\n' && len > 0) {
- line[len - 1] = '\0';
- }
- return 0;
-}
-
-#ifdef __linux__
-/* This function is used to provide a workaround for binary drivers that
- * don't export their PCI ID's properly. If distros don't end up using this
- * feature it can and should be removed because the symbol-based resolution
- * scheme should be the primary one */
-static void
-matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
-{
- DIR *idsdir;
- FILE *fp;
- struct dirent *direntry;
- char *line = NULL;
- size_t len;
- ssize_t read;
- char path_name[256], vendor_str[5], chip_str[5];
- uint16_t vendor, chip;
- int i, j;
-
- idsdir = opendir(PCI_TXT_IDS_PATH);
- if (!idsdir)
- return;
-
- xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH);
- direntry = readdir(idsdir);
- /* Read the directory */
- while (direntry) {
- if (direntry->d_name[0] == '.') {
- direntry = readdir(idsdir);
- continue;
- }
- len = strlen(direntry->d_name);
- /* A tiny bit of sanity checking. We should probably do better */
- if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
- /* We need the full path name to open the file */
- strncpy(path_name, PCI_TXT_IDS_PATH, 256);
- strncat(path_name, "/", 1);
- strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1));
- fp = fopen(path_name, "r");
- if (fp == NULL) {
- xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
- goto end;
- }
- /* Read the file */
-#ifdef __GLIBC__
- while ((read = getline(&line, &len, fp)) != -1) {
-#else
- while ((line = fgetln(fp, &len)) != (char *)NULL) {
-#endif /* __GLIBC __ */
- xchomp(line);
- if (isdigit(line[0])) {
- strncpy(vendor_str, line, 4);
- vendor_str[4] = '\0';
- vendor = (int)strtol(vendor_str, NULL, 16);
- if ((strlen(&line[4])) == 0) {
- chip_str[0] = '\0';
- chip = -1;
- } else {
- /* Handle trailing whitespace */
- if (isspace(line[4])) {
- chip_str[0] = '\0';
- chip = -1;
- } else {
- /* Ok, it's a real ID */
- strncpy(chip_str, &line[4], 4);
- chip_str[4] = '\0';
- chip = (int)strtol(chip_str, NULL, 16);
- }
- }
- if (vendor == match_vendor && chip == match_chip ) {
- i = 0;
- while (matches[i]) {
- i++;
- }
- matches[i] = (char*)xalloc(sizeof(char) * strlen(direntry->d_name) - 3);
- if (!matches[i]) {
- xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
- goto end;
- }
- /* hack off the .ids suffix. This should guard
- * against other problems, but it will end up
- * taking off anything after the first '.' */
- for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
- if (direntry->d_name[j] == '.') {
- matches[i][j] = '\0';
- break;
- } else {
- matches[i][j] = direntry->d_name[j];
- }
- }
- xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name);
- }
- } else {
- /* TODO Handle driver overrides here */
- }
- }
- fclose(fp);
- }
- direntry = readdir(idsdir);
- }
- end:
- xfree(line);
- closedir(idsdir);
-}
-#endif /* __linux__ */
-
-static void
-listPossibleVideoDrivers(char *matches[], int nmatches)
-{
- struct pci_device * info = NULL;
- struct pci_device_iterator *iter;
- int i;
-
- for (i = 0 ; i < nmatches ; i++) {
- matches[i] = NULL;
- }
- i = 0;
-
-#ifdef sun
- /* Check for driver type based on /dev/fb type and if valid, use
- it instead of PCI bus probe results */
- if (xf86Info.consoleFd >= 0) {
- struct vis_identifier visid;
- const char *cp;
- extern char xf86SolarisFbDev[PATH_MAX];
- int iret;
-
- SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
- if (iret < 0) {
- int fbfd;
-
- fbfd = open(xf86SolarisFbDev, O_RDONLY);
- if (fbfd >= 0) {
- SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
- close(fbfd);
- }
- }
-
- if (iret < 0) {
- xf86Msg(X_WARNING,
- "could not get frame buffer identifier from %s\n",
- xf86SolarisFbDev);
- } else {
- xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
-
- /* Special case from before the general case was set */
- if (strcmp(visid.name, "NVDAnvda") == 0) {
- matches[i++] = xnfstrdup("nvidia");
- }
-
- /* General case - split into vendor name (initial all-caps
- prefix) & driver name (rest of the string). */
- if (strcmp(visid.name, "SUNWtext") != 0) {
- for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
- /* find end of all uppercase vendor section */
- }
- if ((cp != visid.name) && (*cp != '\0')) {
- char *driverName = xnfstrdup(cp);
- char *vendorName = xnfstrdup(visid.name);
- vendorName[cp - visid.name] = '\0';
-
- matches[i++] = vendorName;
- matches[i++] = driverName;
- }
- }
- }
- }
-#endif
-#ifdef __sparc__
- {
- char *sbusDriver = sparcDriverName();
- if (sbusDriver)
- matches[i++] = xnfstrdup(sbusDriver);
- }
-#endif
-
- /* Find the primary device, and get some information about it. */
- iter = pci_slot_match_iterator_create(NULL);
- while ((info = pci_device_next(iter)) != NULL) {
- if (xf86IsPrimaryPci(info)) {
- break;
- }
- }
-
- pci_iterator_destroy(iter);
-
- if (!info) {
- ErrorF("Primary device is not PCI\n");
- }
-#ifdef __linux__
- else {
- matchDriverFromFiles(matches, info->vendor_id, info->device_id);
- }
-#endif /* __linux__ */
-
- for (i = 0; (i < nmatches) && (matches[i]); i++) {
- /* find end of matches list */
- }
-
- if ((info != NULL) && (i < nmatches)) {
- i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
- }
-
- /* Fallback to platform default hardware */
- if (i < (nmatches - 1)) {
-#if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
- matches[i++] = xnfstrdup("vesa");
-#elif defined(__sparc__) && !defined(sun)
- matches[i++] = xnfstrdup("sunffb");
-#endif
- }
-
- /* Fallback to platform default frame buffer driver */
- if (i < (nmatches - 1)) {
-#if !defined(__linux__) && defined(__sparc__)
- matches[i++] = xnfstrdup("wsfb");
-#else
- matches[i++] = xnfstrdup("fbdev");
-#endif
- }
-}
-
-/* copy a screen section and enter the desired driver
- * and insert it at i in the list of screens */
-static Bool
-copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
-{
- GDevPtr cptr = NULL;
-
- xf86ConfigLayout.screens[i].screen = xnfcalloc(1, sizeof(confScreenRec));
- if(!xf86ConfigLayout.screens[i].screen)
- return FALSE;
- memcpy(xf86ConfigLayout.screens[i].screen, oscreen, sizeof(confScreenRec));
-
- cptr = xcalloc(1, sizeof(GDevRec));
- if (!cptr)
- return FALSE;
- memcpy(cptr, odev, sizeof(GDevRec));
-
- cptr->identifier = Xprintf("Autoconfigured Video Device %s", driver);
- cptr->driver = driver;
-
- /* now associate the new driver entry with the new screen entry */
- xf86ConfigLayout.screens[i].screen->device = cptr;
- cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
-
- return TRUE;
-}
-
-GDevPtr
-autoConfigDevice(GDevPtr preconf_device)
-{
- GDevPtr ptr = NULL;
- char *matches[20]; /* If we have more than 20 drivers we're in trouble */
- int num_matches = 0, num_screens = 0, i;
- screenLayoutPtr slp;
-
- if (!xf86configptr) {
- return NULL;
- }
-
- /* If there's a configured section with no driver chosen, use it */
- if (preconf_device) {
- ptr = preconf_device;
- } else {
- ptr = xcalloc(1, sizeof(GDevRec));
- if (!ptr) {
- return NULL;
- }
- ptr->chipID = -1;
- ptr->chipRev = -1;
- ptr->irq = -1;
-
- ptr->active = TRUE;
- ptr->claimed = FALSE;
- ptr->identifier = "Autoconfigured Video Device";
- ptr->driver = NULL;
- }
- if (!ptr->driver) {
- /* get all possible video drivers and count them */
- listPossibleVideoDrivers(matches, 20);
- for (; matches[num_matches]; num_matches++) {
- xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
- matches[num_matches], num_matches);
- }
-
- slp = xf86ConfigLayout.screens;
- if (slp) {
- /* count the number of screens and make space for
- * a new screen for each additional possible driver
- * minus one for the already existing first one
- * plus one for the terminating NULL */
- for (; slp[num_screens].screen; num_screens++);
- xf86ConfigLayout.screens = xnfcalloc(num_screens + num_matches,
- sizeof(screenLayoutRec));
- xf86ConfigLayout.screens[0] = slp[0];
-
- /* do the first match and set that for the original first screen */
- ptr->driver = matches[0];
- if (!xf86ConfigLayout.screens[0].screen->device) {
- xf86ConfigLayout.screens[0].screen->device = ptr;
- ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
- }
-
- /* for each other driver found, copy the first screen, insert it
- * into the list of screens and set the driver */
- i = 0;
- while (i++ < num_matches) {
- if (!copyScreen(slp[0].screen, ptr, i, matches[i]))
- return NULL;
- }
-
- /* shift the rest of the original screen list
- * to the end of the current screen list
- *
- * TODO Handle rest of multiple screen sections */
- for (i = 1; i < num_screens; i++) {
- xf86ConfigLayout.screens[i+num_matches] = slp[i];
- }
- xf86ConfigLayout.screens[num_screens+num_matches-1].screen = NULL;
- xfree(slp);
- } else {
- /* layout does not have any screens, not much to do */
- ptr->driver = matches[0];
- for (i = 1; matches[i] ; i++) {
- if (matches[i] != matches[0]) {
- xfree(matches[i]);
- }
- }
- }
- }
-
- xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
-
- return ptr;
-}
+/*
+ * Copyright 2003 by David H. Dawes.
+ * Copyright 2003 by X-Oz Technologies.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ *
+ * Author: David Dawes <dawes@XFree86.Org>.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "xf86Config.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#ifdef __sparc__
+# include "xf86sbusBus.h"
+#endif
+#include "dirent.h"
+
+#ifdef sun
+# include <sys/visual_io.h>
+# include <ctype.h>
+#endif
+
+/* Sections for the default built-in configuration. */
+
+#define BUILTIN_DEVICE_NAME \
+ "\"Builtin Default %s Device %d\""
+
+#define BUILTIN_DEVICE_SECTION_PRE \
+ "Section \"Device\"\n" \
+ "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
+ "\tDriver\t\"%s\"\n"
+
+#define BUILTIN_DEVICE_SECTION_POST \
+ "EndSection\n\n"
+
+#define BUILTIN_DEVICE_SECTION \
+ BUILTIN_DEVICE_SECTION_PRE \
+ BUILTIN_DEVICE_SECTION_POST
+
+#define BUILTIN_SCREEN_NAME \
+ "\"Builtin Default %s Screen %d\""
+
+#define BUILTIN_SCREEN_SECTION \
+ "Section \"Screen\"\n" \
+ "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
+ "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
+ "EndSection\n\n"
+
+#define BUILTIN_LAYOUT_SECTION_PRE \
+ "Section \"ServerLayout\"\n" \
+ "\tIdentifier\t\"Builtin Default Layout\"\n"
+
+#define BUILTIN_LAYOUT_SCREEN_LINE \
+ "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
+
+#define BUILTIN_LAYOUT_SECTION_POST \
+ "EndSection\n\n"
+
+static const char **builtinConfig = NULL;
+static int builtinLines = 0;
+
+static void listPossibleVideoDrivers(char *matches[], int nmatches);
+
+/*
+ * A built-in config file is stored as an array of strings, with each string
+ * representing a single line. AppendToConfig() breaks up the string "s"
+ * into lines, and appends those lines it to builtinConfig.
+ */
+
+static void
+AppendToList(const char *s, const char ***list, int *lines)
+{
+ char *str, *newstr, *p;
+
+ str = xnfstrdup(s);
+ for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
+ (*lines)++;
+ *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
+ newstr = xnfalloc(strlen(p) + 2);
+ strcpy(newstr, p);
+ strcat(newstr, "\n");
+ (*list)[*lines - 1] = newstr;
+ (*list)[*lines] = NULL;
+ }
+ free(str);
+}
+
+static void
+FreeList(const char ***list, int *lines)
+{
+ int i;
+
+ for (i = 0; i < *lines; i++) {
+ if ((*list)[i])
+ free((*list)[i]);
+ }
+ free(*list);
+ *list = NULL;
+ *lines = 0;
+}
+
+static void
+FreeConfig(void)
+{
+ FreeList(&builtinConfig, &builtinLines);
+}
+
+static void
+AppendToConfig(const char *s)
+{
+ AppendToList(s, &builtinConfig, &builtinLines);
+}
+
+static int
+videoPtrToDriverList(struct pci_device *dev,
+ char *returnList[], int returnListMax)
+{
+ int i;
+ /* Add more entries here if we ever return more than 4 drivers for
+ any device */
+ char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
+
+ switch (dev->vendor_id)
+ {
+ /* AMD Geode LX */
+ case 0x1022:
+ if (dev->device_id == 0x2081)
+ driverList[0] = "geode";
+ break;
+ /* older Geode products acquired by AMD still carry an NSC vendor_id */
+ case 0x100b:
+ if (dev->device_id == 0x0030) {
+ /* NSC Geode GX2 specifically */
+ driverList[0] = "geode";
+ /* GX2 support started its life in the NSC tree and was later
+ forked by AMD for GEODE so we keep it as a backup */
+ driverList[1] = "nsc";
+ } else
+ /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
+ driverList[0] = "nsc";
+ break;
+ /* Cyrix Geode GX1 */
+ case 0x1078:
+ if (dev->device_id == 0x0104)
+ driverList[0] = "cyrix";
+ break;
+ case 0x1142: driverList[0] = "apm"; break;
+ case 0xedd8: driverList[0] = "ark"; break;
+ case 0x1a03: driverList[0] = "ast"; break;
+ case 0x1002: driverList[0] = "ati"; break;
+ case 0x102c: driverList[0] = "chips"; break;
+ case 0x1013: driverList[0] = "cirrus"; break;
+ case 0x3d3d: driverList[0] = "glint"; break;
+ case 0x105d: driverList[0] = "i128"; break;
+ case 0x8086:
+ if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
+ driverList[0] = "i740";
+ } else if (dev->device_id == 0x8108) {
+ break; /* "hooray" for poulsbo */
+ } else {
+ driverList[0] = "intel";
+ }
+ break;
+ case 0x102b: driverList[0] = "mga"; break;
+ case 0x10c8: driverList[0] = "neomagic"; break;
+ case 0x10de: case 0x12d2: driverList[0] = "nv"; break;
+ case 0x1106: driverList[0] = "openchrome"; break;
+ case 0x1b36: driverList[0] = "qxl"; break;
+ case 0x1163: driverList[0] = "rendition"; break;
+ case 0x5333:
+ switch (dev->device_id)
+ {
+ case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
+ case 0x8812: case 0x8814: case 0x8901:
+ driverList[0] = "s3"; break;
+ case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
+ case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
+ driverList[0] = "s3virge"; break;
+ default:
+ driverList[0] = "savage"; break;
+ }
+ break;
+ case 0x1039: driverList[0] = "sis"; break;
+ case 0x126f: driverList[0] = "siliconmotion"; break;
+ case 0x121a:
+ if (dev->device_id < 0x0003)
+ driverList[0] = "voodoo";
+ else
+ driverList[0] = "tdfx";
+ break;
+ case 0x1011: driverList[0] = "tga"; break;
+ case 0x1023: driverList[0] = "trident"; break;
+ case 0x100c: driverList[0] = "tseng"; break;
+ case 0x80ee: driverList[0] = "vboxvideo"; break;
+ case 0x15ad: driverList[0] = "vmware"; break;
+ case 0x18ca:
+ if (dev->device_id == 0x47)
+ driverList[0] = "xgixp";
+ else
+ driverList[0] = "xgi";
+ break;
+ default: break;
+ }
+ for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) {
+ returnList[i] = xnfstrdup(driverList[i]);
+ }
+ return i; /* Number of entries added */
+}
+
+Bool
+xf86AutoConfig(void)
+{
+ char *deviceList[20];
+ char **p;
+ const char **cp;
+ char buf[1024];
+ ConfigStatus ret;
+
+ listPossibleVideoDrivers(deviceList, 20);
+
+ for (p = deviceList; *p; p++) {
+ snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
+ AppendToConfig(buf);
+ snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
+ AppendToConfig(buf);
+ }
+
+ AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
+ for (p = deviceList; *p; p++) {
+ snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
+ AppendToConfig(buf);
+ }
+ AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
+
+ for (p = deviceList; *p; p++) {
+ free(*p);
+ }
+
+ xf86MsgVerb(X_DEFAULT, 0,
+ "Using default built-in configuration (%d lines)\n",
+ builtinLines);
+
+ xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
+ for (cp = builtinConfig; *cp; cp++)
+ xf86ErrorFVerb(3, "\t%s", *cp);
+ xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
+
+ xf86initConfigFiles();
+ xf86setBuiltinConfig(builtinConfig);
+ ret = xf86HandleConfigFile(TRUE);
+ FreeConfig();
+
+ if (ret != CONFIG_OK)
+ xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
+
+ return (ret == CONFIG_OK);
+}
+
+static int
+xchomp(char *line)
+{
+ size_t len = 0;
+
+ if (!line) {
+ return 1;
+ }
+
+ len = strlen(line);
+ if (line[len - 1] == '\n' && len > 0) {
+ line[len - 1] = '\0';
+ }
+ return 0;
+}
+
+#ifdef __linux__
+/* This function is used to provide a workaround for binary drivers that
+ * don't export their PCI ID's properly. If distros don't end up using this
+ * feature it can and should be removed because the symbol-based resolution
+ * scheme should be the primary one */
+static void
+matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
+{
+ DIR *idsdir;
+ FILE *fp;
+ struct dirent *direntry;
+ char *line = NULL;
+ size_t len;
+ ssize_t read;
+ char path_name[256], vendor_str[5], chip_str[5];
+ uint16_t vendor, chip;
+ int i, j;
+
+ idsdir = opendir(PCI_TXT_IDS_PATH);
+ if (!idsdir)
+ return;
+
+ xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH);
+ direntry = readdir(idsdir);
+ /* Read the directory */
+ while (direntry) {
+ if (direntry->d_name[0] == '.') {
+ direntry = readdir(idsdir);
+ continue;
+ }
+ len = strlen(direntry->d_name);
+ /* A tiny bit of sanity checking. We should probably do better */
+ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
+ /* We need the full path name to open the file */
+ strncpy(path_name, PCI_TXT_IDS_PATH, 256);
+ strncat(path_name, "/", 1);
+ strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1));
+ fp = fopen(path_name, "r");
+ if (fp == NULL) {
+ xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
+ goto end;
+ }
+ /* Read the file */
+#ifdef __GLIBC__
+ while ((read = getline(&line, &len, fp)) != -1) {
+#else
+ while ((line = fgetln(fp, &len)) != (char *)NULL) {
+#endif /* __GLIBC __ */
+ xchomp(line);
+ if (isdigit(line[0])) {
+ strncpy(vendor_str, line, 4);
+ vendor_str[4] = '\0';
+ vendor = (int)strtol(vendor_str, NULL, 16);
+ if ((strlen(&line[4])) == 0) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Handle trailing whitespace */
+ if (isspace(line[4])) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Ok, it's a real ID */
+ strncpy(chip_str, &line[4], 4);
+ chip_str[4] = '\0';
+ chip = (int)strtol(chip_str, NULL, 16);
+ }
+ }
+ if (vendor == match_vendor && chip == match_chip ) {
+ i = 0;
+ while (matches[i]) {
+ i++;
+ }
+ matches[i] = (char*)malloc(sizeof(char) * strlen(direntry->d_name) - 3);
+ if (!matches[i]) {
+ xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
+ goto end;
+ }
+ /* hack off the .ids suffix. This should guard
+ * against other problems, but it will end up
+ * taking off anything after the first '.' */
+ for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
+ if (direntry->d_name[j] == '.') {
+ matches[i][j] = '\0';
+ break;
+ } else {
+ matches[i][j] = direntry->d_name[j];
+ }
+ }
+ xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name);
+ }
+ } else {
+ /* TODO Handle driver overrides here */
+ }
+ }
+ fclose(fp);
+ }
+ direntry = readdir(idsdir);
+ }
+ end:
+ free(line);
+ closedir(idsdir);
+}
+#endif /* __linux__ */
+
+static void
+listPossibleVideoDrivers(char *matches[], int nmatches)
+{
+ struct pci_device * info = NULL;
+ struct pci_device_iterator *iter;
+ int i;
+
+ for (i = 0 ; i < nmatches ; i++) {
+ matches[i] = NULL;
+ }
+ i = 0;
+
+#ifdef sun
+ /* Check for driver type based on /dev/fb type and if valid, use
+ it instead of PCI bus probe results */
+ if (xf86Info.consoleFd >= 0) {
+ struct vis_identifier visid;
+ const char *cp;
+ extern char xf86SolarisFbDev[PATH_MAX];
+ int iret;
+
+ SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
+ if (iret < 0) {
+ int fbfd;
+
+ fbfd = open(xf86SolarisFbDev, O_RDONLY);
+ if (fbfd >= 0) {
+ SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
+ close(fbfd);
+ }
+ }
+
+ if (iret < 0) {
+ xf86Msg(X_WARNING,
+ "could not get frame buffer identifier from %s\n",
+ xf86SolarisFbDev);
+ } else {
+ xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
+
+ /* Special case from before the general case was set */
+ if (strcmp(visid.name, "NVDAnvda") == 0) {
+ matches[i++] = xnfstrdup("nvidia");
+ }
+
+ /* General case - split into vendor name (initial all-caps
+ prefix) & driver name (rest of the string). */
+ if (strcmp(visid.name, "SUNWtext") != 0) {
+ for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
+ /* find end of all uppercase vendor section */
+ }
+ if ((cp != visid.name) && (*cp != '\0')) {
+ char *driverName = xnfstrdup(cp);
+ char *vendorName = xnfstrdup(visid.name);
+ vendorName[cp - visid.name] = '\0';
+
+ matches[i++] = vendorName;
+ matches[i++] = driverName;
+ }
+ }
+ }
+ }
+#endif
+#ifdef __sparc__
+ {
+ char *sbusDriver = sparcDriverName();
+ if (sbusDriver)
+ matches[i++] = xnfstrdup(sbusDriver);
+ }
+#endif
+
+ /* Find the primary device, and get some information about it. */
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((info = pci_device_next(iter)) != NULL) {
+ if (xf86IsPrimaryPci(info)) {
+ break;
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+ if (!info) {
+ ErrorF("Primary device is not PCI\n");
+ }
+#ifdef __linux__
+ else {
+ matchDriverFromFiles(matches, info->vendor_id, info->device_id);
+ }
+#endif /* __linux__ */
+
+ for (i = 0; (i < nmatches) && (matches[i]); i++) {
+ /* find end of matches list */
+ }
+
+ if ((info != NULL) && (i < nmatches)) {
+ i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
+ }
+
+ /* Fallback to platform default hardware */
+ if (i < (nmatches - 1)) {
+#if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
+ matches[i++] = xnfstrdup("vesa");
+#elif defined(__sparc__) && !defined(sun)
+ matches[i++] = xnfstrdup("sunffb");
+#endif
+ }
+
+ /* Fallback to platform default frame buffer driver */
+ if (i < (nmatches - 1)) {
+#if !defined(__linux__) && defined(__sparc__)
+ matches[i++] = xnfstrdup("wsfb");
+#else
+ matches[i++] = xnfstrdup("fbdev");
+#endif
+ }
+}
+
+/* copy a screen section and enter the desired driver
+ * and insert it at i in the list of screens */
+static Bool
+copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
+{
+ GDevPtr cptr = NULL;
+
+ xf86ConfigLayout.screens[i].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if(!xf86ConfigLayout.screens[i].screen)
+ return FALSE;
+ memcpy(xf86ConfigLayout.screens[i].screen, oscreen, sizeof(confScreenRec));
+
+ cptr = calloc(1, sizeof(GDevRec));
+ if (!cptr)
+ return FALSE;
+ memcpy(cptr, odev, sizeof(GDevRec));
+
+ cptr->identifier = Xprintf("Autoconfigured Video Device %s", driver);
+ cptr->driver = driver;
+
+ /* now associate the new driver entry with the new screen entry */
+ xf86ConfigLayout.screens[i].screen->device = cptr;
+ cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
+
+ return TRUE;
+}
+
+GDevPtr
+autoConfigDevice(GDevPtr preconf_device)
+{
+ GDevPtr ptr = NULL;
+ char *matches[20]; /* If we have more than 20 drivers we're in trouble */
+ int num_matches = 0, num_screens = 0, i;
+ screenLayoutPtr slp;
+
+ if (!xf86configptr) {
+ return NULL;
+ }
+
+ /* If there's a configured section with no driver chosen, use it */
+ if (preconf_device) {
+ ptr = preconf_device;
+ } else {
+ ptr = calloc(1, sizeof(GDevRec));
+ if (!ptr) {
+ return NULL;
+ }
+ ptr->chipID = -1;
+ ptr->chipRev = -1;
+ ptr->irq = -1;
+
+ ptr->active = TRUE;
+ ptr->claimed = FALSE;
+ ptr->identifier = "Autoconfigured Video Device";
+ ptr->driver = NULL;
+ }
+ if (!ptr->driver) {
+ /* get all possible video drivers and count them */
+ listPossibleVideoDrivers(matches, 20);
+ for (; matches[num_matches]; num_matches++) {
+ xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
+ matches[num_matches], num_matches);
+ }
+
+ slp = xf86ConfigLayout.screens;
+ if (slp) {
+ /* count the number of screens and make space for
+ * a new screen for each additional possible driver
+ * minus one for the already existing first one
+ * plus one for the terminating NULL */
+ for (; slp[num_screens].screen; num_screens++);
+ xf86ConfigLayout.screens = xnfcalloc(num_screens + num_matches,
+ sizeof(screenLayoutRec));
+ xf86ConfigLayout.screens[0] = slp[0];
+
+ /* do the first match and set that for the original first screen */
+ ptr->driver = matches[0];
+ if (!xf86ConfigLayout.screens[0].screen->device) {
+ xf86ConfigLayout.screens[0].screen->device = ptr;
+ ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
+ }
+
+ /* for each other driver found, copy the first screen, insert it
+ * into the list of screens and set the driver */
+ i = 0;
+ while (i++ < num_matches) {
+ if (!copyScreen(slp[0].screen, ptr, i, matches[i]))
+ return NULL;
+ }
+
+ /* shift the rest of the original screen list
+ * to the end of the current screen list
+ *
+ * TODO Handle rest of multiple screen sections */
+ for (i = 1; i < num_screens; i++) {
+ xf86ConfigLayout.screens[i+num_matches] = slp[i];
+ }
+ xf86ConfigLayout.screens[num_screens+num_matches-1].screen = NULL;
+ free(slp);
+ } else {
+ /* layout does not have any screens, not much to do */
+ ptr->driver = matches[0];
+ for (i = 1; matches[i] ; i++) {
+ if (matches[i] != matches[0]) {
+ free(matches[i]);
+ }
+ }
+ }
+ }
+
+ xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
+
+ return ptr;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Bus.c b/xorg-server/hw/xfree86/common/xf86Bus.c
index 9d243c172..5c1668644 100644
--- a/xorg-server/hw/xfree86/common/xf86Bus.c
+++ b/xorg-server/hw/xfree86/common/xf86Bus.c
@@ -1,683 +1,683 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the interfaces to the bus-specific code
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-/* Bus-specific headers */
-
-#include "xf86Bus.h"
-
-#define XF86_OS_PRIVS
-#include "xf86_OSproc.h"
-#include "xf86VGAarbiter.h"
-
-#include "Pci.h"
-
-/* Entity data */
-EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */
-int xf86NumEntities = 0;
-static int xf86EntityPrivateCount = 0;
-
-BusRec primaryBus = { BUS_NONE, { 0 } };
-
-static Bool xf86ResAccessEnter = FALSE;
-
-static Bool doFramebufferMode = FALSE;
-
-/*
- * Call the bus probes relevant to the architecture.
- *
- * The only one available so far is for PCI and SBUS.
- */
-
-void
-xf86BusProbe(void)
-{
- xf86PciProbe();
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- xf86SbusProbe();
-#endif
-}
-
-/*
- * Determine what bus type the busID string represents. The start of the
- * bus-dependent part of the string is returned as retID.
- */
-
-BusType
-StringToBusType(const char* busID, const char **retID)
-{
- char *p, *s;
- BusType ret = BUS_NONE;
-
- /* If no type field, Default to PCI */
- if (isdigit(busID[0])) {
- if (retID)
- *retID = busID;
- return BUS_PCI;
- }
-
- s = xstrdup(busID);
- p = strtok(s, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return BUS_NONE;
- }
- if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
- ret = BUS_PCI;
- if (!xf86NameCmp(p, "sbus"))
- ret = BUS_SBUS;
- if (ret != BUS_NONE)
- if (retID)
- *retID = busID + strlen(p) + 1;
- xfree(s);
- return ret;
-}
-
-/*
- * Entity related code.
- */
-
-void
-xf86EntityInit(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityInit) {
- xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
- }
-}
-
-int
-xf86AllocateEntity(void)
-{
- xf86NumEntities++;
- xf86Entities = xnfrealloc(xf86Entities,
- sizeof(EntityPtr) * xf86NumEntities);
- xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
- xf86Entities[xf86NumEntities - 1]->entityPrivates =
- xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
- return (xf86NumEntities - 1);
-}
-
-static void
-EntityEnter(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityEnter) {
- xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
- }
-}
-
-static void
-EntityLeave(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityLeave) {
- xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
- }
-}
-
-Bool
-xf86IsEntityPrimary(int entityIndex)
-{
- EntityPtr pEnt = xf86Entities[entityIndex];
-
- if (primaryBus.type != pEnt->bus.type) return FALSE;
-
- switch (pEnt->bus.type) {
- case BUS_PCI:
- return (pEnt->bus.id.pci == primaryBus.id.pci);
- case BUS_SBUS:
- return (pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum);
- default:
- return FALSE;
- }
-}
-
-Bool
-xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
- EntityProc leave, pointer private)
-{
- if (entityIndex >= xf86NumEntities)
- return FALSE;
- xf86Entities[entityIndex]->entityInit = init;
- xf86Entities[entityIndex]->entityEnter = enter;
- xf86Entities[entityIndex]->entityLeave = leave;
- xf86Entities[entityIndex]->private = private;
- return TRUE;
-}
-
-Bool
-xf86DriverHasEntities(DriverPtr drvp)
-{
- int i;
- for (i = 0; i < xf86NumEntities; i++) {
- if (xf86Entities[i]->driver == drvp)
- return TRUE;
- }
- return FALSE;
-}
-
-void
-xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
-{
- if (entityIndex == -1)
- return;
- if (xf86Entities[entityIndex]->inUse &&
- !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
- ErrorF("Requested Entity already in use!\n");
- return;
- }
-
- pScrn->numEntities++;
- pScrn->entityList = xnfrealloc(pScrn->entityList,
- pScrn->numEntities * sizeof(int));
- pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
- xf86Entities[entityIndex]->inUse = TRUE;
- pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
- pScrn->numEntities * sizeof(int));
- pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
- pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
-}
-
-void
-xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
-{
- int i;
-
- if (entityIndex == -1 || entityIndex >= xf86NumEntities)
- return;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- if (pScrn->entityList[i] == entityIndex) {
- pScrn->entityInstanceList[i] = instance;
- break;
- }
- }
-}
-
-/*
- * XXX This needs to be updated for the case where a single entity may have
- * instances associated with more than one screen.
- */
-ScrnInfoPtr
-xf86FindScreenForEntity(int entityIndex)
-{
- int i,j;
-
- if (entityIndex == -1) return NULL;
-
- if (xf86Screens) {
- for (i = 0; i < xf86NumScreens; i++) {
- for (j = 0; j < xf86Screens[i]->numEntities; j++) {
- if ( xf86Screens[i]->entityList[j] == entityIndex )
- return (xf86Screens[i]);
- }
- }
- }
- return NULL;
-}
-
-void
-xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
-{
- int i;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- if (pScrn->entityList[i] == entityIndex) {
- for (i++; i < pScrn->numEntities; i++)
- pScrn->entityList[i-1] = pScrn->entityList[i];
- pScrn->numEntities--;
- xf86Entities[entityIndex]->inUse = FALSE;
- break;
- }
- }
-}
-
-/*
- * xf86ClearEntitiesForScreen() - called when a screen is deleted
- * to mark it's entities unused. Called by xf86DeleteScreen().
- */
-void
-xf86ClearEntityListForScreen(int scrnIndex)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int i, entityIndex;
-
- if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- entityIndex = pScrn->entityList[i];
- xf86Entities[entityIndex]->inUse = FALSE;
- /* disable resource: call the disable function */
- }
- xfree(pScrn->entityList);
- xfree(pScrn->entityInstanceList);
- pScrn->entityList = NULL;
- pScrn->entityInstanceList = NULL;
-}
-
-/*
- * Add an extra device section (GDevPtr) to an entity.
- */
-
-void
-xf86AddDevToEntity(int entityIndex, GDevPtr dev)
-{
- EntityPtr pEnt;
-
- if (entityIndex >= xf86NumEntities)
- return;
-
- pEnt = xf86Entities[entityIndex];
- pEnt->numInstances++;
- pEnt->devices = xnfrealloc(pEnt->devices,
- pEnt->numInstances * sizeof(GDevPtr));
- pEnt->devices[pEnt->numInstances - 1] = dev;
- dev->claimed = TRUE;
-}
-
-/*
- * xf86GetEntityInfo() -- This function hands information from the
- * EntityRec struct to the drivers. The EntityRec structure itself
- * remains invisible to the driver.
- */
-EntityInfoPtr
-xf86GetEntityInfo(int entityIndex)
-{
- EntityInfoPtr pEnt;
- int i;
-
- if (entityIndex == -1)
- return NULL;
-
- if (entityIndex >= xf86NumEntities)
- return NULL;
-
- pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
- pEnt->index = entityIndex;
- pEnt->location = xf86Entities[entityIndex]->bus;
- pEnt->active = xf86Entities[entityIndex]->active;
- pEnt->chipset = xf86Entities[entityIndex]->chipset;
- pEnt->driver = xf86Entities[entityIndex]->driver;
- if ( (xf86Entities[entityIndex]->devices) &&
- (xf86Entities[entityIndex]->devices[0]) ) {
- for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
- if (xf86Entities[entityIndex]->devices[i]->screen == 0)
- break;
- pEnt->device = xf86Entities[entityIndex]->devices[i];
- } else
- pEnt->device = NULL;
-
- return pEnt;
-}
-
-int
-xf86GetNumEntityInstances(int entityIndex)
-{
- if (entityIndex >= xf86NumEntities)
- return -1;
-
- return xf86Entities[entityIndex]->numInstances;
-}
-
-GDevPtr
-xf86GetDevFromEntity(int entityIndex, int instance)
-{
- int i;
-
- /* We might not use AddDevtoEntity */
- if ( (!xf86Entities[entityIndex]->devices) ||
- (!xf86Entities[entityIndex]->devices[0]) )
- return NULL;
-
- if (entityIndex >= xf86NumEntities ||
- instance >= xf86Entities[entityIndex]->numInstances)
- return NULL;
-
- for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
- if (xf86Entities[entityIndex]->devices[i]->screen == instance)
- break;
- return xf86Entities[entityIndex]->devices[i];
-}
-
-/*
- * xf86AccessInit() - set up everything needed for access control
- * called only once on first server generation.
- */
-void
-xf86AccessInit(void)
-{
- xf86ResAccessEnter = TRUE;
-}
-
-/*
- * xf86AccessEnter() -- gets called to save the text mode VGA IO
- * resources when reentering the server after a VT switch.
- */
-void
-xf86AccessEnter(void)
-{
- if (xf86ResAccessEnter)
- return;
-
- /*
- * on enter we simply disable routing of special resources
- * to any bus and let the RAC code to "open" the right bridges.
- */
- EntityEnter();
- xf86EnterServerState(SETUP);
- xf86ResAccessEnter = TRUE;
-}
-
-/*
- * xf86AccessLeave() -- prepares access for and calls the
- * entityLeave() functions.
- * xf86AccessLeaveState() --- gets called to restore the
- * access to the VGA IO resources when switching VT or on
- * server exit.
- * This was split to call xf86AccessLeaveState() from
- * ddxGiveUp().
- */
-void
-xf86AccessLeave(void)
-{
- if (!xf86ResAccessEnter)
- return;
- EntityLeave();
-}
-
-/*
- * xf86EnableAccess() -- enable access to controlled resources.
- * To reduce latency when switching access the ScrnInfoRec has
- * a linked list of the EntityAccPtr of all screen entities.
- */
-/*
- * switching access needs to be done in te following oder:
- * disable
- * 1. disable old entity
- * 2. reroute bus
- * 3. enable new entity
- * Otherwise resources needed for access control might be shadowed
- * by other resources!
- */
-
-void
-xf86EnableAccess(ScrnInfoPtr pScrn)
-{
- DebugF("Enable access %i\n",pScrn->scrnIndex);
-
- return;
-}
-
-/*
- * xf86EnterServerState() -- set state the server is in.
- */
-
-typedef enum { TRI_UNSET, TRI_TRUE, TRI_FALSE } TriState;
-
-static void
-SetSIGIOForState(xf86State state)
-{
- static int sigio_state;
- static TriState sigio_blocked = TRI_UNSET;
-
- if ((state == SETUP) && (sigio_blocked != TRI_TRUE)) {
- sigio_state = xf86BlockSIGIO();
- sigio_blocked = TRI_TRUE;
- } else if ((state == OPERATING) && (sigio_blocked != TRI_UNSET)) {
- xf86UnblockSIGIO(sigio_state);
- sigio_blocked = TRI_FALSE;
- }
-}
-
-void
-xf86EnterServerState(xf86State state)
-{
- /*
- * This is a good place to block SIGIO during SETUP state.
- * SIGIO should be blocked in SETUP state otherwise (u)sleep()
- * might get interrupted early.
- * We take care not to call xf86BlockSIGIO() twice.
- */
- SetSIGIOForState(state);
- if (state == SETUP)
- DebugF("Entering SETUP state\n");
- else
- DebugF("Entering OPERATING state\n");
-
- return;
-}
-
-/*
- * xf86PostProbe() -- Allocate all non conflicting resources
- * This function gets called by xf86Init().
- */
-void
-xf86PostProbe(void)
-{
- if (fbSlotClaimed) {
- if (pciSlotClaimed
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- || sbusSlotClaimed
-#endif
- ) {
- FatalError("Cannot run in framebuffer mode. Please specify busIDs "
- " for all framebuffer devices\n");
- return;
- } else {
- xf86Msg(X_INFO,"Running in FRAMEBUFFER Mode\n");
- doFramebufferMode = TRUE;
-
- return;
- }
- }
-}
-
-void
-xf86PostScreenInit(void)
-{
- if (doFramebufferMode) {
- SetSIGIOForState(OPERATING);
- return;
- }
-
- xf86VGAarbiterWrapFunctions();
-
- DebugF("PostScreenInit generation: %i\n",serverGeneration);
- xf86EnterServerState(OPERATING);
-}
-
-/*
- * xf86FindPrimaryDevice() - Find the display device which
- * was active when the server was started.
- */
-void
-xf86FindPrimaryDevice(void)
-{
- if (primaryBus.type != BUS_NONE) {
- char *bus;
- char loc[16];
-
- switch (primaryBus.type) {
- case BUS_PCI:
- bus = "PCI";
- snprintf(loc, sizeof(loc), " %2.2x@%2.2x:%2.2x:%1.1x",
- primaryBus.id.pci->bus,
- primaryBus.id.pci->domain,
- primaryBus.id.pci->dev,
- primaryBus.id.pci->func);
- break;
- case BUS_SBUS:
- bus = "SBUS";
- snprintf(loc, sizeof(loc), " %2.2x", primaryBus.id.sbus.fbNum);
- break;
- default:
- bus = "";
- loc[0] = '\0';
- }
-
- xf86MsgVerb(X_INFO, 2, "Primary Device is: %s%s\n",bus,loc);
- }
-}
-
-int
-xf86GetLastScrnFlag(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- return(xf86Entities[entityIndex]->lastScrnFlag);
- } else {
- return -1;
- }
-}
-
-void
-xf86SetLastScrnFlag(int entityIndex, int scrnIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
- }
-}
-
-Bool
-xf86IsEntityShared(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetEntityShared(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
- }
-}
-
-Bool
-xf86IsEntitySharable(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetEntitySharable(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
- }
-}
-
-Bool
-xf86IsPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
- }
-}
-
-void
-xf86ClearPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
- }
-}
-
-
-/*
- * Allocate a private in the entities.
- */
-
-int
-xf86AllocateEntityPrivateIndex(void)
-{
- int idx, i;
- EntityPtr pEnt;
- DevUnion *nprivs;
-
- idx = xf86EntityPrivateCount++;
- for (i = 0; i < xf86NumEntities; i++) {
- pEnt = xf86Entities[i];
- nprivs = xnfrealloc(pEnt->entityPrivates,
- xf86EntityPrivateCount * sizeof(DevUnion));
- /* Zero the new private */
- bzero(&nprivs[idx], sizeof(DevUnion));
- pEnt->entityPrivates = nprivs;
- }
- return idx;
-}
-
-DevUnion *
-xf86GetEntityPrivate(int entityIndex, int privIndex)
-{
- if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
- return NULL;
-
- return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
-}
-
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the interfaces to the bus-specific code
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+/* Bus-specific headers */
+
+#include "xf86Bus.h"
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+#include "xf86VGAarbiter.h"
+
+#include "Pci.h"
+
+/* Entity data */
+EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */
+int xf86NumEntities = 0;
+static int xf86EntityPrivateCount = 0;
+
+BusRec primaryBus = { BUS_NONE, { 0 } };
+
+static Bool xf86ResAccessEnter = FALSE;
+
+static Bool doFramebufferMode = FALSE;
+
+/*
+ * Call the bus probes relevant to the architecture.
+ *
+ * The only one available so far is for PCI and SBUS.
+ */
+
+void
+xf86BusProbe(void)
+{
+ xf86PciProbe();
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ xf86SbusProbe();
+#endif
+}
+
+/*
+ * Determine what bus type the busID string represents. The start of the
+ * bus-dependent part of the string is returned as retID.
+ */
+
+BusType
+StringToBusType(const char* busID, const char **retID)
+{
+ char *p, *s;
+ BusType ret = BUS_NONE;
+
+ /* If no type field, Default to PCI */
+ if (isdigit(busID[0])) {
+ if (retID)
+ *retID = busID;
+ return BUS_PCI;
+ }
+
+ s = xstrdup(busID);
+ p = strtok(s, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return BUS_NONE;
+ }
+ if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
+ ret = BUS_PCI;
+ if (!xf86NameCmp(p, "sbus"))
+ ret = BUS_SBUS;
+ if (ret != BUS_NONE)
+ if (retID)
+ *retID = busID + strlen(p) + 1;
+ free(s);
+ return ret;
+}
+
+/*
+ * Entity related code.
+ */
+
+void
+xf86EntityInit(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityInit) {
+ xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
+ }
+}
+
+int
+xf86AllocateEntity(void)
+{
+ xf86NumEntities++;
+ xf86Entities = xnfrealloc(xf86Entities,
+ sizeof(EntityPtr) * xf86NumEntities);
+ xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
+ xf86Entities[xf86NumEntities - 1]->entityPrivates =
+ xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
+ return (xf86NumEntities - 1);
+}
+
+static void
+EntityEnter(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityEnter) {
+ xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
+ }
+}
+
+static void
+EntityLeave(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityLeave) {
+ xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
+ }
+}
+
+Bool
+xf86IsEntityPrimary(int entityIndex)
+{
+ EntityPtr pEnt = xf86Entities[entityIndex];
+
+ if (primaryBus.type != pEnt->bus.type) return FALSE;
+
+ switch (pEnt->bus.type) {
+ case BUS_PCI:
+ return (pEnt->bus.id.pci == primaryBus.id.pci);
+ case BUS_SBUS:
+ return (pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum);
+ default:
+ return FALSE;
+ }
+}
+
+Bool
+xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
+ EntityProc leave, pointer private)
+{
+ if (entityIndex >= xf86NumEntities)
+ return FALSE;
+ xf86Entities[entityIndex]->entityInit = init;
+ xf86Entities[entityIndex]->entityEnter = enter;
+ xf86Entities[entityIndex]->entityLeave = leave;
+ xf86Entities[entityIndex]->private = private;
+ return TRUE;
+}
+
+Bool
+xf86DriverHasEntities(DriverPtr drvp)
+{
+ int i;
+ for (i = 0; i < xf86NumEntities; i++) {
+ if (xf86Entities[i]->driver == drvp)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
+{
+ if (entityIndex == -1)
+ return;
+ if (xf86Entities[entityIndex]->inUse &&
+ !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
+ ErrorF("Requested Entity already in use!\n");
+ return;
+ }
+
+ pScrn->numEntities++;
+ pScrn->entityList = xnfrealloc(pScrn->entityList,
+ pScrn->numEntities * sizeof(int));
+ pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
+ xf86Entities[entityIndex]->inUse = TRUE;
+ pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
+ pScrn->numEntities * sizeof(int));
+ pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
+ pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
+}
+
+void
+xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
+{
+ int i;
+
+ if (entityIndex == -1 || entityIndex >= xf86NumEntities)
+ return;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ if (pScrn->entityList[i] == entityIndex) {
+ pScrn->entityInstanceList[i] = instance;
+ break;
+ }
+ }
+}
+
+/*
+ * XXX This needs to be updated for the case where a single entity may have
+ * instances associated with more than one screen.
+ */
+ScrnInfoPtr
+xf86FindScreenForEntity(int entityIndex)
+{
+ int i,j;
+
+ if (entityIndex == -1) return NULL;
+
+ if (xf86Screens) {
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numEntities; j++) {
+ if ( xf86Screens[i]->entityList[j] == entityIndex )
+ return (xf86Screens[i]);
+ }
+ }
+ }
+ return NULL;
+}
+
+void
+xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
+{
+ int i;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ if (pScrn->entityList[i] == entityIndex) {
+ for (i++; i < pScrn->numEntities; i++)
+ pScrn->entityList[i-1] = pScrn->entityList[i];
+ pScrn->numEntities--;
+ xf86Entities[entityIndex]->inUse = FALSE;
+ break;
+ }
+ }
+}
+
+/*
+ * xf86ClearEntitiesForScreen() - called when a screen is deleted
+ * to mark it's entities unused. Called by xf86DeleteScreen().
+ */
+void
+xf86ClearEntityListForScreen(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int i, entityIndex;
+
+ if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ entityIndex = pScrn->entityList[i];
+ xf86Entities[entityIndex]->inUse = FALSE;
+ /* disable resource: call the disable function */
+ }
+ free(pScrn->entityList);
+ free(pScrn->entityInstanceList);
+ pScrn->entityList = NULL;
+ pScrn->entityInstanceList = NULL;
+}
+
+/*
+ * Add an extra device section (GDevPtr) to an entity.
+ */
+
+void
+xf86AddDevToEntity(int entityIndex, GDevPtr dev)
+{
+ EntityPtr pEnt;
+
+ if (entityIndex >= xf86NumEntities)
+ return;
+
+ pEnt = xf86Entities[entityIndex];
+ pEnt->numInstances++;
+ pEnt->devices = xnfrealloc(pEnt->devices,
+ pEnt->numInstances * sizeof(GDevPtr));
+ pEnt->devices[pEnt->numInstances - 1] = dev;
+ dev->claimed = TRUE;
+}
+
+/*
+ * xf86GetEntityInfo() -- This function hands information from the
+ * EntityRec struct to the drivers. The EntityRec structure itself
+ * remains invisible to the driver.
+ */
+EntityInfoPtr
+xf86GetEntityInfo(int entityIndex)
+{
+ EntityInfoPtr pEnt;
+ int i;
+
+ if (entityIndex == -1)
+ return NULL;
+
+ if (entityIndex >= xf86NumEntities)
+ return NULL;
+
+ pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
+ pEnt->index = entityIndex;
+ pEnt->location = xf86Entities[entityIndex]->bus;
+ pEnt->active = xf86Entities[entityIndex]->active;
+ pEnt->chipset = xf86Entities[entityIndex]->chipset;
+ pEnt->driver = xf86Entities[entityIndex]->driver;
+ if ( (xf86Entities[entityIndex]->devices) &&
+ (xf86Entities[entityIndex]->devices[0]) ) {
+ for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
+ if (xf86Entities[entityIndex]->devices[i]->screen == 0)
+ break;
+ pEnt->device = xf86Entities[entityIndex]->devices[i];
+ } else
+ pEnt->device = NULL;
+
+ return pEnt;
+}
+
+int
+xf86GetNumEntityInstances(int entityIndex)
+{
+ if (entityIndex >= xf86NumEntities)
+ return -1;
+
+ return xf86Entities[entityIndex]->numInstances;
+}
+
+GDevPtr
+xf86GetDevFromEntity(int entityIndex, int instance)
+{
+ int i;
+
+ /* We might not use AddDevtoEntity */
+ if ( (!xf86Entities[entityIndex]->devices) ||
+ (!xf86Entities[entityIndex]->devices[0]) )
+ return NULL;
+
+ if (entityIndex >= xf86NumEntities ||
+ instance >= xf86Entities[entityIndex]->numInstances)
+ return NULL;
+
+ for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
+ if (xf86Entities[entityIndex]->devices[i]->screen == instance)
+ break;
+ return xf86Entities[entityIndex]->devices[i];
+}
+
+/*
+ * xf86AccessInit() - set up everything needed for access control
+ * called only once on first server generation.
+ */
+void
+xf86AccessInit(void)
+{
+ xf86ResAccessEnter = TRUE;
+}
+
+/*
+ * xf86AccessEnter() -- gets called to save the text mode VGA IO
+ * resources when reentering the server after a VT switch.
+ */
+void
+xf86AccessEnter(void)
+{
+ if (xf86ResAccessEnter)
+ return;
+
+ /*
+ * on enter we simply disable routing of special resources
+ * to any bus and let the RAC code to "open" the right bridges.
+ */
+ EntityEnter();
+ xf86EnterServerState(SETUP);
+ xf86ResAccessEnter = TRUE;
+}
+
+/*
+ * xf86AccessLeave() -- prepares access for and calls the
+ * entityLeave() functions.
+ * xf86AccessLeaveState() --- gets called to restore the
+ * access to the VGA IO resources when switching VT or on
+ * server exit.
+ * This was split to call xf86AccessLeaveState() from
+ * ddxGiveUp().
+ */
+void
+xf86AccessLeave(void)
+{
+ if (!xf86ResAccessEnter)
+ return;
+ EntityLeave();
+}
+
+/*
+ * xf86EnableAccess() -- enable access to controlled resources.
+ * To reduce latency when switching access the ScrnInfoRec has
+ * a linked list of the EntityAccPtr of all screen entities.
+ */
+/*
+ * switching access needs to be done in te following oder:
+ * disable
+ * 1. disable old entity
+ * 2. reroute bus
+ * 3. enable new entity
+ * Otherwise resources needed for access control might be shadowed
+ * by other resources!
+ */
+
+void
+xf86EnableAccess(ScrnInfoPtr pScrn)
+{
+ DebugF("Enable access %i\n",pScrn->scrnIndex);
+
+ return;
+}
+
+/*
+ * xf86EnterServerState() -- set state the server is in.
+ */
+
+typedef enum { TRI_UNSET, TRI_TRUE, TRI_FALSE } TriState;
+
+static void
+SetSIGIOForState(xf86State state)
+{
+ static int sigio_state;
+ static TriState sigio_blocked = TRI_UNSET;
+
+ if ((state == SETUP) && (sigio_blocked != TRI_TRUE)) {
+ sigio_state = xf86BlockSIGIO();
+ sigio_blocked = TRI_TRUE;
+ } else if ((state == OPERATING) && (sigio_blocked != TRI_UNSET)) {
+ xf86UnblockSIGIO(sigio_state);
+ sigio_blocked = TRI_FALSE;
+ }
+}
+
+void
+xf86EnterServerState(xf86State state)
+{
+ /*
+ * This is a good place to block SIGIO during SETUP state.
+ * SIGIO should be blocked in SETUP state otherwise (u)sleep()
+ * might get interrupted early.
+ * We take care not to call xf86BlockSIGIO() twice.
+ */
+ SetSIGIOForState(state);
+ if (state == SETUP)
+ DebugF("Entering SETUP state\n");
+ else
+ DebugF("Entering OPERATING state\n");
+
+ return;
+}
+
+/*
+ * xf86PostProbe() -- Allocate all non conflicting resources
+ * This function gets called by xf86Init().
+ */
+void
+xf86PostProbe(void)
+{
+ if (fbSlotClaimed) {
+ if (pciSlotClaimed
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ || sbusSlotClaimed
+#endif
+ ) {
+ FatalError("Cannot run in framebuffer mode. Please specify busIDs "
+ " for all framebuffer devices\n");
+ return;
+ } else {
+ xf86Msg(X_INFO,"Running in FRAMEBUFFER Mode\n");
+ doFramebufferMode = TRUE;
+
+ return;
+ }
+ }
+}
+
+void
+xf86PostScreenInit(void)
+{
+ if (doFramebufferMode) {
+ SetSIGIOForState(OPERATING);
+ return;
+ }
+
+ xf86VGAarbiterWrapFunctions();
+
+ DebugF("PostScreenInit generation: %i\n",serverGeneration);
+ xf86EnterServerState(OPERATING);
+}
+
+/*
+ * xf86FindPrimaryDevice() - Find the display device which
+ * was active when the server was started.
+ */
+void
+xf86FindPrimaryDevice(void)
+{
+ if (primaryBus.type != BUS_NONE) {
+ char *bus;
+ char loc[16];
+
+ switch (primaryBus.type) {
+ case BUS_PCI:
+ bus = "PCI";
+ snprintf(loc, sizeof(loc), " %2.2x@%2.2x:%2.2x:%1.1x",
+ primaryBus.id.pci->bus,
+ primaryBus.id.pci->domain,
+ primaryBus.id.pci->dev,
+ primaryBus.id.pci->func);
+ break;
+ case BUS_SBUS:
+ bus = "SBUS";
+ snprintf(loc, sizeof(loc), " %2.2x", primaryBus.id.sbus.fbNum);
+ break;
+ default:
+ bus = "";
+ loc[0] = '\0';
+ }
+
+ xf86MsgVerb(X_INFO, 2, "Primary Device is: %s%s\n",bus,loc);
+ }
+}
+
+int
+xf86GetLastScrnFlag(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ return(xf86Entities[entityIndex]->lastScrnFlag);
+ } else {
+ return -1;
+ }
+}
+
+void
+xf86SetLastScrnFlag(int entityIndex, int scrnIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
+ }
+}
+
+Bool
+xf86IsEntityShared(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetEntityShared(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
+ }
+}
+
+Bool
+xf86IsEntitySharable(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetEntitySharable(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
+ }
+}
+
+Bool
+xf86IsPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
+ }
+}
+
+void
+xf86ClearPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
+ }
+}
+
+
+/*
+ * Allocate a private in the entities.
+ */
+
+int
+xf86AllocateEntityPrivateIndex(void)
+{
+ int idx, i;
+ EntityPtr pEnt;
+ DevUnion *nprivs;
+
+ idx = xf86EntityPrivateCount++;
+ for (i = 0; i < xf86NumEntities; i++) {
+ pEnt = xf86Entities[i];
+ nprivs = xnfrealloc(pEnt->entityPrivates,
+ xf86EntityPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pEnt->entityPrivates = nprivs;
+ }
+ return idx;
+}
+
+DevUnion *
+xf86GetEntityPrivate(int entityIndex, int privIndex)
+{
+ if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
+ return NULL;
+
+ return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
+}
+
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 9a2837e7b..33b38930f 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -1,2586 +1,2586 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-
-/*
- * Copyright 1992-2003 by The XFree86 Project, Inc.
- * Copyright 1997 by Metro Link, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- *
- * Authors:
- * Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * Egbert Eich <eich@XFree86.Org>
- * ... and others
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#ifdef XF86DRI
-#include <sys/types.h>
-#include <grp.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "xf86Config.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "configProcs.h"
-#include "globals.h"
-#include "extension.h"
-#include "Pci.h"
-
-#include "xf86Xinput.h"
-extern DeviceAssocRec mouse_assoc;
-
-#include "xkbsrv.h"
-
-#include "picture.h"
-
-/*
- * These paths define the way the config file search is done. The escape
- * sequences are documented in parser/scan.c.
- */
-#ifndef ROOT_CONFIGPATH
-#define ROOT_CONFIGPATH "%A," "%R," \
- "/etc/X11/%R," "%P/etc/X11/%R," \
- "%E," "%F," \
- "/etc/X11/%F," "%P/etc/X11/%F," \
- "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-#ifndef USER_CONFIGPATH
-#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
- "/etc/X11/%G," "%P/etc/X11/%G," \
- "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-#ifndef ROOT_CONFIGDIRPATH
-#define ROOT_CONFIGDIRPATH "%A," "%R," \
- "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef USER_CONFIGDIRPATH
-#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef SYS_CONFIGDIRPATH
-#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
-#endif
-#ifndef PROJECTROOT
-#define PROJECTROOT "/usr/X11R6"
-#endif
-
-static ModuleDefault ModuleDefaults[] = {
- {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
-#ifdef DBE
- {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef GLXEXT
- {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XRECORD
- {.name = "record", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XF86DRI
- {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef DRI2
- {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
-#endif
- {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
-};
-
-
-/* Forward declarations */
-static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
- int scrnum, MessageType from);
-static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
-static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
- Bool active);
-static Bool configInput(IDevPtr inputp, XF86ConfInputPtr conf_input,
- MessageType from);
-static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
-static Bool addDefaultModes(MonPtr monitorp);
-#ifdef XF86DRI
-static void configDRI(XF86ConfDRIPtr drip);
-#endif
-static void configExtensions(XF86ConfExtensionsPtr conf_ext);
-
-/*
- * xf86GetPathElem --
- * Extract a single element from the font path string starting at
- * pnt. The font path element will be returned, and pnt will be
- * updated to point to the start of the next element, or set to
- * NULL if there are no more.
- */
-static char *
-xf86GetPathElem(char **pnt)
-{
- char *p1;
-
- p1 = *pnt;
- *pnt = index(*pnt, ',');
- if (*pnt != NULL) {
- **pnt = '\0';
- *pnt += 1;
- }
- return(p1);
-}
-
-/*
- * xf86ValidateFontPath --
- * Validates the user-specified font path. Each element that
- * begins with a '/' is checked to make sure the directory exists.
- * If the directory exists, the existence of a file named 'fonts.dir'
- * is checked. If either check fails, an error is printed and the
- * element is removed from the font path.
- */
-
-#define DIR_FILE "/fonts.dir"
-static char *
-xf86ValidateFontPath(char *path)
-{
- char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
- struct stat stat_buf;
- int flag;
- int dirlen;
-
- tmp_path = xcalloc(1,strlen(path)+1);
- out_pnt = tmp_path;
- path_elem = NULL;
- next = path;
- while (next != NULL) {
- path_elem = xf86GetPathElem(&next);
- if (*path_elem == '/') {
- dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
- if ((p1 = strchr(path_elem, ':')) != 0)
- dirlen = p1 - path_elem;
- else
- dirlen = strlen(path_elem);
- strncpy(dir_elem, path_elem, dirlen);
- dir_elem[dirlen] = '\0';
- flag = stat(dir_elem, &stat_buf);
- if (flag == 0)
- if (!S_ISDIR(stat_buf.st_mode))
- flag = -1;
- if (flag != 0) {
- xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- xfree(dir_elem);
- continue;
- }
- else {
- p1 = xnfalloc(strlen(dir_elem)+strlen(DIR_FILE)+1);
- strcpy(p1, dir_elem);
- strcat(p1, DIR_FILE);
- flag = stat(p1, &stat_buf);
- if (flag == 0)
- if (!S_ISREG(stat_buf.st_mode))
- flag = -1;
- xfree(p1);
- if (flag != 0) {
- xf86Msg(X_WARNING,
- "`fonts.dir' not found (or not valid) in \"%s\".\n",
- dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
- xfree(dir_elem);
- continue;
- }
- }
- xfree(dir_elem);
- }
-
- /*
- * Either an OK directory, or a font server name. So add it to
- * the path.
- */
- if (out_pnt != tmp_path)
- *out_pnt++ = ',';
- strcat(out_pnt, path_elem);
- out_pnt += strlen(path_elem);
- }
- return(tmp_path);
-}
-
-
-/*
- * use the datastructure that the parser provides and pick out the parts
- * that we need at this point
- */
-char **
-xf86ModulelistFromConfig(pointer **optlist)
-{
- int count = 0, i = 0;
- char **modulearray;
- char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
- "freetype", "type1",
- NULL };
- pointer *optarray;
- XF86LoadPtr modp;
- Bool found;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- if (xf86configptr->conf_modules) {
- /* Walk the disable list and let people know what we've parsed to
- * not be loaded
- */
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
- modp = (XF86LoadPtr) modp->list.next;
- }
- /*
- * Walk the default settings table. For each module listed to be
- * loaded, make sure it's in the mod_load_lst. If it's not, make
- * sure it's not in the mod_no_load_lst. If it's not disabled,
- * append it to mod_load_lst
- */
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == FALSE) {
- xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
- continue;
- }
- found = FALSE;
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- if (found == FALSE) {
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- if (found == FALSE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
- }
- }
- } else {
- xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == TRUE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- }
- }
- }
-
- /*
- * Walk the list of modules in the "Module" section to determine how
- * many we have.
- */
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- for (i = 0; ignore[i]; i++) {
- if (strcmp(modp->load_name, ignore[i]) == 0)
- modp->ignore = 1;
- }
- if (!modp->ignore)
- count++;
- modp = (XF86LoadPtr) modp->list.next;
- }
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- optarray = xnfalloc((count + 1) * sizeof(pointer));
- count = 0;
- if (xf86configptr->conf_modules) {
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (!modp->ignore) {
- modulearray[count] = modp->load_name;
- optarray[count] = modp->load_opt;
- count++;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- modulearray[count] = NULL;
- optarray[count] = NULL;
- if (optlist)
- *optlist = optarray;
- else
- xfree(optarray);
- return modulearray;
-}
-
-
-char **
-xf86DriverlistFromConfig(void)
-{
- int count = 0;
- int j;
- char **modulearray;
- screenLayoutPtr slp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "Device" sections to
- * determine now many implicitly loaded modules there are.
- *
- */
- if (xf86ConfigLayout.screens) {
- slp = xf86ConfigLayout.screens;
- while ((slp++)->screen) {
- count++;
- }
- }
-
- /*
- * Handle the set of inactive "Device" sections.
- */
- j = 0;
- while (xf86ConfigLayout.inactives[j++].identifier)
- count++;
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- slp = xf86ConfigLayout.screens;
- while (slp->screen) {
- modulearray[count] = slp->screen->device->driver;
- count++;
- slp++;
- }
-
- j = 0;
-
- while (xf86ConfigLayout.inactives[j].identifier)
- modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
-
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-char **
-xf86InputDriverlistFromConfig(void)
-{
- int count = 0;
- char **modulearray;
- IDevPtr* idp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "InputDevice" sections to
- * determine now many implicitly loaded modules there are.
- */
- if (xf86ConfigLayout.inputs) {
- idp = xf86ConfigLayout.inputs;
- while (*idp) {
- count++;
- idp++;
- }
- }
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- idp = xf86ConfigLayout.inputs;
- while (idp && *idp) {
- modulearray[count] = (*idp)->driver;
- count++;
- idp++;
- }
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-static void
-fixup_video_driver_list(char **drivers)
-{
- static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
- char **end, **drv;
- char *x;
- char **ati, **atimisc;
- int i;
-
- /* walk to the end of the list */
- for (end = drivers; *end && **end; end++) ;
- end--;
-
- /*
- * for each of the fallback drivers, if we find it in the list,
- * swap it with the last available non-fallback driver.
- */
- for (i = 0; fallback[i]; i++) {
- for (drv = drivers; drv != end; drv++) {
- if (strstr(*drv, fallback[i])) {
- x = *drv; *drv = *end; *end = x;
- end--;
- break;
- }
- }
- }
- /*
- * since the ati wrapper driver is gross and awful, sort ati before
- * atimisc, which makes sure all the ati symbols are visible in xorgcfg.
- */
- for (drv = drivers; drv != end; drv++) {
- if (!strcmp(*drv, "atimisc")) {
- atimisc = drv;
- for (drv = atimisc; drv != end; drv++) {
- if (!strcmp(*drv, "ati")) {
- ati = drv;
- x = *ati; *ati = *atimisc; *atimisc = x;
- return;
- }
- }
- /* if we get here, ati was already ahead of atimisc */
- return;
- }
- }
-}
-
-static char **
-GenerateDriverlist(char * dirname)
-{
- char **ret;
- const char *subdirs[] = { dirname, NULL };
- static const char *patlist[] = {"(.*)_drv\\.so", "(.*)_drv\\.o", NULL};
- ret = LoaderListDirs(subdirs, patlist);
-
- /* fix up the probe order for video drivers */
- if (strstr(dirname, "drivers") && ret != NULL)
- fixup_video_driver_list(ret);
-
- return ret;
-}
-
-char **
-xf86DriverlistFromCompile(void)
-{
- static char **driverlist = NULL;
-
- if (!driverlist)
- driverlist = GenerateDriverlist("drivers");
-
- return driverlist;
-}
-
-/*
- * xf86ConfigError --
- * Print a READABLE ErrorMessage!!! All information that is
- * available is printed.
- */
-static void
-xf86ConfigError(char *msg, ...)
-{
- va_list ap;
-
- ErrorF("\nConfig Error:\n");
- va_start(ap, msg);
- VErrorF(msg, ap);
- va_end(ap);
- ErrorF("\n");
- return;
-}
-
-static void
-configFiles(XF86ConfFilesPtr fileconf)
-{
- MessageType pathFrom;
- Bool must_copy;
- int size, countDirs;
- char *temp_path, *log_buf, *start, *end;
-
- /* FontPath */
- must_copy = TRUE;
-
- temp_path = defaultFontPath ? defaultFontPath : "";
- if (xf86fpFlag)
- pathFrom = X_CMDLINE;
- else if (fileconf && fileconf->file_fontpath) {
- pathFrom = X_CONFIG;
- if (xf86Info.useDefaultFontPath) {
- defaultFontPath = Xprintf("%s%s%s",
- fileconf->file_fontpath,
- *temp_path ? "," : "", temp_path);
- if (defaultFontPath != NULL) {
- must_copy = FALSE;
- }
- }
- else
- defaultFontPath = fileconf->file_fontpath;
- }
- else
- pathFrom = X_DEFAULT;
- temp_path = defaultFontPath ? defaultFontPath : "";
-
- /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
- temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
- defaultFontPath = xf86ValidateFontPath(temp_path);
- xfree(temp_path);
-
- /* make fontpath more readable in the logfiles */
- countDirs = 1;
- temp_path = defaultFontPath;
- while ((temp_path = index(temp_path, ',')) != NULL) {
- countDirs++;
- temp_path++;
- }
-
- log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
- temp_path = log_buf;
- start = defaultFontPath;
- while((end = index(start, ',')) != NULL) {
- size = (end - start) + 1;
- *(temp_path++) = '\t';
- strncpy(temp_path, start, size);
- temp_path += size;
- *(temp_path++) = '\n';
- start += size;
- }
- /* copy last entry */
- *(temp_path++) = '\t';
- strcpy(temp_path, start);
- xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
- xfree(log_buf);
-
- /* ModulePath */
-
- if (fileconf) {
- if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
- xf86ModulePath = fileconf->file_modulepath;
- xf86ModPathFrom = X_CONFIG;
- }
- }
-
- xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
-
- if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
- XkbBaseDirectory = fileconf->file_xkbdir;
- xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
- XkbBaseDirectory);
- }
-#if 0
- /* LogFile */
- /*
- * XXX The problem with this is that the log file is already open.
- * One option might be to copy the exiting contents to the new location.
- * and re-open it. The down side is that the default location would
- * already have been overwritten. Another option would be to start with
- * unique temporary location, then copy it once the correct name is known.
- * A problem with this is what happens if the server exits before that
- * happens.
- */
- if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
- xf86LogFile = fileconf->file_logfile;
- xf86LogFileFrom = X_CONFIG;
- }
-#endif
-
- return;
-}
-
-typedef enum {
- FLAG_NOTRAPSIGNALS,
- FLAG_DONTVTSWITCH,
- FLAG_DONTZAP,
- FLAG_DONTZOOM,
- FLAG_DISABLEVIDMODE,
- FLAG_ALLOWNONLOCAL,
- FLAG_ALLOWMOUSEOPENFAIL,
- FLAG_VTSYSREQ,
- FLAG_SAVER_BLANKTIME,
- FLAG_DPMS_STANDBYTIME,
- FLAG_DPMS_SUSPENDTIME,
- FLAG_DPMS_OFFTIME,
- FLAG_PIXMAP,
- FLAG_PC98,
- FLAG_NOPM,
- FLAG_XINERAMA,
- FLAG_LOG,
- FLAG_RENDER_COLORMAP_MODE,
- FLAG_RANDR,
- FLAG_AIGLX,
- FLAG_IGNORE_ABI,
- FLAG_ALLOW_EMPTY_INPUT,
- FLAG_USE_DEFAULT_FONT_PATH,
- FLAG_AUTO_ADD_DEVICES,
- FLAG_AUTO_ENABLE_DEVICES,
- FLAG_GLX_VISUALS,
- FLAG_DRI2,
- FLAG_USE_SIGIO
-} FlagValues;
-
-/**
- * NOTE: the last value for each entry is NOT the default. It is set to TRUE
- * if the parser found the option in the config file.
- */
-static OptionInfoRec FlagOptions[] = {
- { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PC98, "PC98", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_LOG, "Log", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOW_EMPTY_INPUT, "AllowEmptyInput", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
- {0}, FALSE },
- { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-#ifdef SUPPORT_PC98
-static Bool
-detectPC98(void)
-{
- unsigned char buf[2];
-
- if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
- return FALSE;
- if ((buf[0] == 0x98) && (buf[1] == 0x21))
- return TRUE;
- else
- return FALSE;
-}
-#endif
-
-static Bool
-configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
-{
- XF86OptionPtr optp, tmp;
- int i;
- Pix24Flags pix24 = Pix24DontCare;
- Bool value;
- MessageType from;
- const char *s;
- XkbRMLVOSet set;
- /* Default options. */
- set.rules = "base";
- set.model = "pc105";
- set.layout = "us";
- set.variant = NULL;
- set.options = NULL;
-
- /*
- * Merge the ServerLayout and ServerFlags options. The former have
- * precedence over the latter.
- */
- optp = NULL;
- if (flagsconf && flagsconf->flg_option_lst)
- optp = xf86optionListDup(flagsconf->flg_option_lst);
- if (layoutopts) {
- tmp = xf86optionListDup(layoutopts);
- if (optp)
- optp = xf86optionListMerge(optp, tmp);
- else
- optp = tmp;
- }
-
- xf86ProcessOptions(-1, optp, FlagOptions);
-
- xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
- xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
-
- xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
- if (xf86Info.ignoreABI) {
- xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
- }
-
- if (xf86SIGIOSupported()) {
- xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
- if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
- from = X_CONFIG;
- } else {
- from = X_DEFAULT;
- }
- if (!xf86Info.useSIGIO) {
- xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
- } else if (from == X_CONFIG) {
- xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
- }
- } else {
- xf86Info.useSIGIO = FALSE;
- }
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
- &xf86Info.autoAddDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically adding devices\n",
- xf86Info.autoAddDevices ? "A" : "Not a");
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
- &xf86Info.autoEnableDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically enabling devices\n",
- xf86Info.autoEnableDevices ? "A" : "Not a");
-
- /*
- * Set things up based on the config file information. Some of these
- * settings may be overridden later when the command line options are
- * checked.
- */
-#ifdef XF86VIDMODE
- if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
- xf86Info.vidModeEnabled = !value;
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
- xf86Info.vidModeAllowNonLocal = value;
-#endif
-
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
- xf86Info.allowMouseOpenFail = value;
-
- if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
-#ifdef USE_VT_SYSREQ
- xf86Info.vtSysreq = value;
- xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
-#else
- if (value)
- xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
-#endif
- }
-
- xf86Info.pmFlag = TRUE;
- if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
- xf86Info.pmFlag = !value;
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
- if (!xf86NameCmp(s,"flush")) {
- xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
- xf86Info.log = LogFlush;
- LogSetParameter(XLOG_FLUSH, TRUE);
- } else if (!xf86NameCmp(s,"sync")) {
- xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
- xf86Info.log = LogSync;
- LogSetParameter(XLOG_FLUSH, TRUE);
- LogSetParameter(XLOG_SYNC, TRUE);
- } else {
- xf86Msg(X_WARNING,"Unknown Log option\n");
- }
- }
- }
-
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
- int policy = PictureParseCmapPolicy (s);
- if (policy == PictureCmapPolicyInvalid)
- xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
- else
- {
- xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
- PictureCmapPolicy = policy;
- }
- }
- }
-
-#ifdef RANDR
- xf86Info.disableRandR = FALSE;
- xf86Info.randRFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
- xf86Info.disableRandR = !value;
- xf86Info.randRFrom = X_CONFIG;
- }
-#endif
-
- xf86Info.aiglx = TRUE;
- xf86Info.aiglxFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-
-#ifdef GLXEXT
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- xf86Info.glxVisualsFrom = X_DEFAULT;
- if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
- if (!xf86NameCmp(s, "minimal")) {
- xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
- } else if (!xf86NameCmp(s, "typical")) {
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- } else if (!xf86NameCmp(s, "all")) {
- xf86Info.glxVisuals = XF86_GlxVisualsAll;
- } else {
- xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
- }
- }
-
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-#endif
-
- /* AllowEmptyInput is automatically true if we're hotplugging */
- xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
- xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput);
-
- /* AEI on? Then we're not using kbd, so use the evdev rules set. */
-#if defined(linux)
- if (xf86Info.allowEmptyInput)
- set.rules = "evdev";
-#endif
- XkbSetRulesDflts(&set);
-
- xf86Info.useDefaultFontPath = TRUE;
- xf86Info.useDefaultFontPathFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
- xf86Info.useDefaultFontPath = value;
- xf86Info.useDefaultFontPathFrom = X_CONFIG;
- }
-
-/* Make sure that timers don't overflow CARD32's after multiplying */
-#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-
-#ifdef DPMSExtension
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSStandbyTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSSuspendTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSOffTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-#endif
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
- switch (i) {
- case 24:
- pix24 = Pix24Use24;
- break;
- case 32:
- pix24 = Pix24Use32;
- break;
- case -1:
- break;
- default:
- xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
- return FALSE;
- }
- if (xf86Pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = xf86Pix24;
- xf86Info.pix24From = X_CMDLINE;
- } else if (pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = pix24;
- xf86Info.pix24From = X_CONFIG;
- } else {
- xf86Info.pixmap24 = Pix24DontCare;
- xf86Info.pix24From = X_DEFAULT;
- }
-#ifdef SUPPORT_PC98
- if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
- xf86Info.pc98 = value;
- if (value) {
- xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
- }
- } else
- if (detectPC98()) {
- xf86Info.pc98 = TRUE;
- xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
- }
-#endif
-
-#ifdef PANORAMIX
- from = X_DEFAULT;
- if (!noPanoramiXExtension)
- from = X_CMDLINE;
- else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
- noPanoramiXExtension = !value;
- from = X_CONFIG;
- }
- if (!noPanoramiXExtension)
- xf86Msg(from, "Xinerama: enabled\n");
-#endif
-
-#ifdef DRI2
- xf86Info.dri2 = FALSE;
- xf86Info.dri2From = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
- xf86Info.dri2 = value;
- xf86Info.dri2From = X_CONFIG;
- }
-#endif
-
- return TRUE;
-}
-
-Bool xf86DRI2Enabled(void)
-{
- return xf86Info.dri2;
-}
-
-/*
- * Locate the core input devices. These can be specified/located in
- * the following ways, in order of priority:
- *
- * 1. The InputDevices named by the -pointer and -keyboard command line
- * options.
- * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
- * the active ServerLayout.
- * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
- * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
- * driver (mouse, synaptics, evdev, vmmouse, void)
- * 5. Default devices with an empty (default) configuration. These defaults
- * will reference the 'mouse' and 'keyboard' drivers.
- */
-
-static Bool
-checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
-{
- IDevPtr corePointer = NULL, coreKeyboard = NULL;
- Bool foundPointer = FALSE, foundKeyboard = FALSE;
- const char *pointerMsg = NULL, *keyboardMsg = NULL;
- IDevPtr *devs, /* iterator */
- indp;
- IDevRec Pointer, Keyboard;
- XF86ConfInputPtr confInput;
- XF86ConfInputRec defPtr, defKbd;
- int count = 0;
- MessageType from = X_DEFAULT;
- int found = 0;
- const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
- "void", NULL };
-
- /*
- * First check if a core pointer or core keyboard have been specified
- * in the active ServerLayout. If more than one is specified for either,
- * remove the core attribute from the later ones.
- */
- for (devs = servlayoutp->inputs; devs && *devs; devs++) {
- pointer opt1 = NULL, opt2 = NULL;
- indp = *devs;
- if (indp->commonOptions &&
- xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
- opt1 = indp->commonOptions;
- }
- if (indp->extraOptions &&
- xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
- opt2 = indp->extraOptions;
- }
- if (opt1 || opt2) {
- if (!corePointer) {
- corePointer = indp;
- } else {
- if (opt1)
- xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
- if (opt2)
- xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
- xf86Msg(X_WARNING, "Duplicate core pointer devices. "
- "Removing core pointer attribute from \"%s\"\n",
- indp->identifier);
- }
- }
- opt1 = opt2 = NULL;
- if (indp->commonOptions &&
- xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
- opt1 = indp->commonOptions;
- }
- if (indp->extraOptions &&
- xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
- opt2 = indp->extraOptions;
- }
- if (opt1 || opt2) {
- if (!coreKeyboard) {
- coreKeyboard = indp;
- } else {
- if (opt1)
- xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
- if (opt2)
- xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
- xf86Msg(X_WARNING, "Duplicate core keyboard devices. "
- "Removing core keyboard attribute from \"%s\"\n",
- indp->identifier);
- }
- }
- count++;
- }
-
- confInput = NULL;
-
- /* 1. Check for the -pointer command line option. */
- if (xf86PointerName) {
- confInput = xf86findInput(xf86PointerName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86PointerName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * removed.
- */
- if (corePointer) {
- for (devs = servlayoutp->inputs; devs && *devs; devs++)
- if (*devs == corePointer)
- {
- xfree(*devs);
- *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
- break;
- }
- for (; devs && *devs; devs++)
- devs[0] = devs[1];
- count--;
- }
- corePointer = NULL;
- foundPointer = TRUE;
- }
-
- /* 2. ServerLayout-specified core pointer. */
- if (corePointer) {
- foundPointer = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core pointer device. */
- if (!foundPointer && (!xf86Info.allowEmptyInput || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
- confInput = p;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first core pointer device";
- break;
- }
- }
- }
-
- /* 4. First pointer with an allowed mouse driver. */
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- const char **driver = mousedrivers;
- confInput = xf86findInput(CONF_IMPLICIT_POINTER,
- xf86configptr->conf_input_lst);
- while (*driver && !confInput) {
- confInput = xf86findInputByDriver(*driver,
- xf86configptr->conf_input_lst);
- driver++;
- }
- if (confInput) {
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first mouse device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- bzero(&defPtr, sizeof(defPtr));
- defPtr.inp_identifier = strdup("<default pointer>");
- defPtr.inp_driver = strdup("mouse");
- confInput = &defPtr;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "default mouse configuration";
- }
-
- /* Add the core pointer device to the layout, and set it to Core. */
- if (foundPointer && confInput) {
- foundPointer = configInput(&Pointer, confInput, from);
- if (foundPointer) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Pointer;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
- return FALSE;
- }
-
- /*
- * always synthesize a 'mouse' section configured to send core
- * events, unless a 'void' section is found, in which case the user
- * probably wants to run footless.
- *
- * If you're using an evdev keyboard and expect a default mouse
- * section ... deal.
- */
- for (devs = servlayoutp->inputs; devs && *devs; devs++) {
- const char **driver = mousedrivers;
- while(*driver) {
- if (!strcmp((*devs)->driver, *driver)) {
- found = 1;
- break;
- }
- driver++;
- }
- }
- if (!found && !xf86Info.allowEmptyInput) {
- xf86Msg(X_INFO, "No default mouse found, adding one\n");
- bzero(&defPtr, sizeof(defPtr));
- defPtr.inp_identifier = strdup("<default pointer>");
- defPtr.inp_driver = strdup("mouse");
- confInput = &defPtr;
- foundPointer = configInput(&Pointer, confInput, from);
- if (foundPointer) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Pointer;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- confInput = NULL;
-
- /* 1. Check for the -keyboard command line option. */
- if (xf86KeyboardName) {
- confInput = xf86findInput(xf86KeyboardName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86KeyboardName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * removed.
- */
- if (coreKeyboard) {
- for (devs = servlayoutp->inputs; devs && *devs; devs++)
- if (*devs == coreKeyboard)
- {
- xfree(*devs);
- *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
- break;
- }
- for (; devs && *devs; devs++)
- devs[0] = devs[1];
- count--;
- }
- coreKeyboard = NULL;
- foundKeyboard = TRUE;
- }
-
- /* 2. ServerLayout-specified core keyboard. */
- if (coreKeyboard) {
- foundKeyboard = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core keyboard device. */
- if (!foundKeyboard && (!xf86Info.allowEmptyInput || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
- confInput = p;
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first core keyboard device";
- break;
- }
- }
- }
-
- /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- confInput = xf86findInputByDriver("kbd",
- xf86configptr->conf_input_lst);
- }
- if (confInput) {
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first keyboard device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- bzero(&defKbd, sizeof(defKbd));
- defKbd.inp_identifier = strdup("<default keyboard>");
- defKbd.inp_driver = strdup("kbd");
- confInput = &defKbd;
- foundKeyboard = TRUE;
- keyboardMsg = "default keyboard configuration";
- from = X_DEFAULT;
- }
-
- /* Add the core keyboard device to the layout, and set it to Core. */
- if (foundKeyboard && confInput) {
- foundKeyboard = configInput(&Keyboard, confInput, from);
- if (foundKeyboard) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Keyboard;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
- return FALSE;
- }
-
- if (pointerMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- pointerMsg);
- else
- xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", pointerMsg);
- }
-
- if (keyboardMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- keyboardMsg);
- else
- xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", keyboardMsg);
- }
-
- if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
-#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
- const char *config_backend;
-#if defined(CONFIG_HAL)
- config_backend = "HAL";
-#else
- config_backend = "udev";
-#endif
- xf86Msg(X_INFO, "The server relies on %s to provide the list of "
- "input devices.\n\tIf no devices become available, "
- "reconfigure %s or disable AutoAddDevices.\n",
- config_backend, config_backend);
-#else
- xf86Msg(X_INFO, "Hotplugging is disabled and no input devices were configured.\n"
- "\tTry disabling AllowEmptyInput.\n");
-#endif
- }
-
- return TRUE;
-}
-
-typedef enum {
- LAYOUT_ISOLATEDEVICE,
- LAYOUT_SINGLECARD
-} LayoutValues;
-
-static OptionInfoRec LayoutOptions[] = {
- { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
- {0}, FALSE },
- { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
-{
- XF86ConfInputrefPtr irp;
- IDevPtr *indp;
- int count = 0;
-
- /*
- * Count the number of input devices.
- */
- irp = layout->lay_input_lst;
- while (irp) {
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- DebugF("Found %d input devices in the layout section %s\n",
- count, layout->lay_identifier);
- indp = xnfcalloc((count + 1), sizeof(IDevPtr));
- indp[count] = NULL;
- irp = layout->lay_input_lst;
- count = 0;
- while (irp) {
- indp[count] = xnfalloc(sizeof(IDevRec));
- if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
- while(count--)
- xfree(indp[count]);
- xfree(indp);
- return FALSE;
- }
- indp[count]->extraOptions = irp->iref_option_lst;
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- servlayoutp->inputs = indp;
-
- return TRUE;
-}
-
-
-/*
- * figure out which layout is active, which screens are used in that layout,
- * which drivers and monitors are used in these screens
- */
-static Bool
-configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
- char *default_layout)
-{
- XF86ConfAdjacencyPtr adjp;
- XF86ConfInactivePtr idp;
- int count = 0;
- int scrnum;
- XF86ConfLayoutPtr l;
- MessageType from;
- screenLayoutPtr slp;
- GDevPtr gdp;
- int i = 0, j;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which layout section is the active one?
- *
- * If there is a -layout command line option, use that one, otherwise
- * pick the first one.
- */
- from = X_DEFAULT;
- if (xf86LayoutName != NULL)
- from = X_CMDLINE;
- else if (default_layout) {
- xf86LayoutName = default_layout;
- from = X_CONFIG;
- }
- if (xf86LayoutName != NULL) {
- if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
- xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
- xf86LayoutName);
- return FALSE;
- }
- conf_layout = l;
- }
- xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
- adjp = conf_layout->lay_adjacency_lst;
-
- /*
- * we know that each screen is referenced exactly once on the left side
- * of a layout statement in the Layout section. So to allocate the right
- * size for the array we do a quick walk of the list to figure out how
- * many sections we have
- */
- while (adjp) {
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- DebugF("Found %d screens in the layout section %s",
- count, conf_layout->lay_identifier);
- if (!count) /* alloc enough storage even if no screen is specified */
- count = 1;
-
- slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
- slp[count].screen = NULL;
- /*
- * now that we have storage, loop over the list again and fill in our
- * data structure; at this point we do not fill in the adjacency
- * information as it is not clear if we need it at all
- */
- adjp = conf_layout->lay_adjacency_lst;
- count = 0;
- while (adjp) {
- slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (adjp->adj_scrnum < 0)
- scrnum = count;
- else
- scrnum = adjp->adj_scrnum;
- if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
- X_CONFIG)) {
- xfree(slp);
- return FALSE;
- }
- slp[count].x = adjp->adj_x;
- slp[count].y = adjp->adj_y;
- slp[count].refname = adjp->adj_refscreen;
- switch (adjp->adj_where) {
- case CONF_ADJ_OBSOLETE:
- slp[count].where = PosObsolete;
- slp[count].topname = adjp->adj_top_str;
- slp[count].bottomname = adjp->adj_bottom_str;
- slp[count].leftname = adjp->adj_left_str;
- slp[count].rightname = adjp->adj_right_str;
- break;
- case CONF_ADJ_ABSOLUTE:
- slp[count].where = PosAbsolute;
- break;
- case CONF_ADJ_RIGHTOF:
- slp[count].where = PosRightOf;
- break;
- case CONF_ADJ_LEFTOF:
- slp[count].where = PosLeftOf;
- break;
- case CONF_ADJ_ABOVE:
- slp[count].where = PosAbove;
- break;
- case CONF_ADJ_BELOW:
- slp[count].where = PosBelow;
- break;
- case CONF_ADJ_RELATIVE:
- slp[count].where = PosRelative;
- break;
- }
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- /* No screen was specified in the layout. take the first one from the
- * config file, or - if it is NULL - configScreen autogenerates one for
- * us */
- if (!count)
- {
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
- 0, X_CONFIG)) {
- xfree(slp[0].screen);
- xfree(slp);
- return FALSE;
- }
- }
-
- /* XXX Need to tie down the upper left screen. */
-
- /* Fill in the refscreen and top/bottom/left/right values */
- for (i = 0; i < count; i++) {
- for (j = 0; j < count; j++) {
- if (slp[i].refname &&
- strcmp(slp[i].refname, slp[j].screen->id) == 0) {
- slp[i].refscreen = slp[j].screen;
- }
- if (slp[i].topname &&
- strcmp(slp[i].topname, slp[j].screen->id) == 0) {
- slp[i].top = slp[j].screen;
- }
- if (slp[i].bottomname &&
- strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
- slp[i].bottom = slp[j].screen;
- }
- if (slp[i].leftname &&
- strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
- slp[i].left = slp[j].screen;
- }
- if (slp[i].rightname &&
- strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
- slp[i].right = slp[j].screen;
- }
- }
- if (slp[i].where != PosObsolete
- && slp[i].where != PosAbsolute
- && !slp[i].refscreen) {
- xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
- slp[i].refname);
- slp[i].where = PosAbsolute;
- slp[i].x = 0;
- slp[i].y = 0;
- }
- }
-
- /*
- * Count the number of inactive devices.
- */
- count = 0;
- idp = conf_layout->lay_inactive_lst;
- while (idp) {
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
- DebugF("Found %d inactive devices in the layout section %s\n",
- count, conf_layout->lay_identifier);
- gdp = xnfalloc((count + 1) * sizeof(GDevRec));
- gdp[count].identifier = NULL;
- idp = conf_layout->lay_inactive_lst;
- count = 0;
- while (idp) {
- if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) {
- xfree(gdp);
- return FALSE;
- }
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
-
- if (!configInputDevices(conf_layout, servlayoutp))
- return FALSE;
-
- servlayoutp->id = conf_layout->lay_identifier;
- servlayoutp->screens = slp;
- servlayoutp->inactives = gdp;
- servlayoutp->options = conf_layout->lay_option_lst;
- from = X_DEFAULT;
-
- return TRUE;
-}
-
-/*
- * No layout section, so find the first Screen section and set that up as
- * the only active screen.
- */
-static Bool
-configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
- XF86ConfigPtr xf86configptr)
-{
- MessageType from;
- XF86ConfScreenPtr s;
- screenLayoutPtr slp;
- IDevPtr *indp;
- XF86ConfLayoutRec layout;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which screen section is the active one?
- *
- * If there is a -screen option, use that one, otherwise use the first
- * one.
- */
-
- from = X_CONFIG;
- if (xf86ScreenName != NULL) {
- if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
- xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
- xf86ScreenName);
- return FALSE;
- }
- conf_screen = s;
- from = X_CMDLINE;
- }
-
- /* We have exactly one screen */
-
- slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- slp[1].screen = NULL;
- if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
- xfree(slp);
- return FALSE;
- }
- servlayoutp->id = "(implicit)";
- servlayoutp->screens = slp;
- servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
- servlayoutp->options = NULL;
-
- memset(&layout, 0, sizeof(layout));
- layout.lay_identifier = servlayoutp->id;
- if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
- if (!configInputDevices(&layout, servlayoutp))
- return FALSE;
- from = X_DEFAULT;
- } else {
- /* Set up an empty input device list, then look for some core devices. */
- indp = xnfalloc(sizeof(IDevPtr));
- *indp = NULL;
- servlayoutp->inputs = indp;
- }
-
- return TRUE;
-}
-
-static Bool
-configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
-{
- int count = 0;
- XF86ConfVideoPortPtr conf_port;
-
- xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
- conf_adaptor->va_identifier);
- adaptor->identifier = conf_adaptor->va_identifier;
- adaptor->options = conf_adaptor->va_option_lst;
- if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
- xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
- return FALSE;
- }
-
- /*
- * figure out how many videoport subsections there are and fill them in
- */
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
- adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
- adaptor->numports = count;
- count = 0;
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- adaptor->ports[count].identifier = conf_port->vp_identifier;
- adaptor->ports[count].options = conf_port->vp_option_lst;
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
-
- return TRUE;
-}
-
-static Bool
-configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
- MessageType from)
-{
- int count = 0;
- XF86ConfDisplayPtr dispptr;
- XF86ConfAdaptorLinkPtr conf_adaptor;
- Bool defaultMonitor = FALSE;
-
- if (!conf_screen) {
- conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
- conf_screen->scrn_identifier = "Default Screen Section";
- xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
- }
-
- xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
- scrnum);
- /*
- * now we fill in the elements of the screen
- */
- screenp->id = conf_screen->scrn_identifier;
- screenp->screennum = scrnum;
- screenp->defaultdepth = conf_screen->scrn_defaultdepth;
- screenp->defaultbpp = conf_screen->scrn_defaultbpp;
- screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
- screenp->monitor = xnfcalloc(1, sizeof(MonRec));
- /* If no monitor is specified, create a default one. */
- if (!conf_screen->scrn_monitor) {
- XF86ConfMonitorRec defMon;
-
- bzero(&defMon, sizeof(defMon));
- defMon.mon_identifier = "<default monitor>";
- if (!configMonitor(screenp->monitor, &defMon))
- return FALSE;
- defaultMonitor = TRUE;
- } else {
- if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
- return FALSE;
- }
- /* Configure the device. If there isn't one configured, attach to the
- * first inactive one that we can configure. If there's none that work,
- * set it to NULL so that the section can be autoconfigured later */
- screenp->device = xnfcalloc(1, sizeof(GDevRec));
- if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
- conf_screen->scrn_device = xf86configptr->conf_device_lst;
- xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
- "\tUsing the first device section listed.\n", screenp->id);
- }
- if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
- screenp->device->myScreenSection = screenp;
- } else {
- screenp->device = NULL;
- }
- screenp->options = conf_screen->scrn_option_lst;
-
- /*
- * figure out how many display subsections there are and fill them in
- */
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
- screenp->displays = xnfalloc((count) * sizeof(DispRec));
- screenp->numdisplays = count;
-
- /* Fill in the default Virtual size, if any */
- if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
- for (count = 0, dispptr = conf_screen->scrn_display_lst;
- dispptr;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
- screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
- screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
- }
- }
-
- /* Now do the per-Display Virtual sizes */
- count = 0;
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- configDisplay(&(screenp->displays[count]),dispptr);
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
-
- /*
- * figure out how many videoadaptor references there are and fill them in
- */
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- count++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
- screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
- screenp->numxvadaptors = 0;
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
- conf_adaptor->al_adaptor))
- screenp->numxvadaptors++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
-
- if (defaultMonitor) {
- xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
- "\tUsing a default monitor configuration.\n", screenp->id);
- }
- return TRUE;
-}
-
-typedef enum {
- MON_REDUCEDBLANKING,
- MON_MAX_PIX_CLOCK,
-} MonitorValues;
-
-static OptionInfoRec MonitorOptions[] = {
- { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
- {0}, FALSE },
- { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
-{
- int count;
- DisplayModePtr mode,last = NULL;
- XF86ConfModeLinePtr cmodep;
- XF86ConfModesPtr modes;
- XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
- Gamma zeros = {0.0, 0.0, 0.0};
- float badgamma = 0.0;
- double maxPixClock;
-
- xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
- conf_monitor->mon_identifier);
- monitorp->id = conf_monitor->mon_identifier;
- monitorp->vendor = conf_monitor->mon_vendor;
- monitorp->model = conf_monitor->mon_modelname;
- monitorp->Modes = NULL;
- monitorp->Last = NULL;
- monitorp->gamma = zeros;
- monitorp->widthmm = conf_monitor->mon_width;
- monitorp->heightmm = conf_monitor->mon_height;
- monitorp->reducedblanking = FALSE;
- monitorp->maxPixClock = 0;
- monitorp->options = conf_monitor->mon_option_lst;
-
- /*
- * fill in the monitor structure
- */
- for( count = 0 ;
- count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
- count++) {
- monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
- monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
- }
- monitorp->nHsync = count;
- for( count = 0 ;
- count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
- count++) {
- monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
- monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
- }
- monitorp->nVrefresh = count;
-
- /*
- * first we collect the mode lines from the UseModes directive
- */
- while(modeslnk)
- {
- modes = xf86findModes (modeslnk->ml_modes_str,
- xf86configptr->conf_modes_lst);
- modeslnk->ml_modes = modes;
-
-
- /* now add the modes found in the modes
- section to the list of modes for this
- monitor unless it has been added before
- because we are reusing the same section
- for another screen */
- if (xf86itemNotSublist(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst)) {
- conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
- xf86addListItem(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst);
- }
- modeslnk = modeslnk->list.next;
- }
-
- /*
- * we need to hook in the mode lines now
- * here both data structures use lists, only our internal one
- * is double linked
- */
- cmodep = conf_monitor->mon_modeline_lst;
- while( cmodep ) {
- mode = xnfcalloc(1, sizeof(DisplayModeRec));
- mode->type = 0;
- mode->Clock = cmodep->ml_clock;
- mode->HDisplay = cmodep->ml_hdisplay;
- mode->HSyncStart = cmodep->ml_hsyncstart;
- mode->HSyncEnd = cmodep->ml_hsyncend;
- mode->HTotal = cmodep->ml_htotal;
- mode->VDisplay = cmodep->ml_vdisplay;
- mode->VSyncStart = cmodep->ml_vsyncstart;
- mode->VSyncEnd = cmodep->ml_vsyncend;
- mode->VTotal = cmodep->ml_vtotal;
- mode->Flags = cmodep->ml_flags;
- mode->HSkew = cmodep->ml_hskew;
- mode->VScan = cmodep->ml_vscan;
- mode->name = xnfstrdup(cmodep->ml_identifier);
- if( last ) {
- mode->prev = last;
- last->next = mode;
- }
- else {
- /*
- * this is the first mode
- */
- monitorp->Modes = mode;
- mode->prev = NULL;
- }
- last = mode;
- cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
- }
- if(last){
- last->next = NULL;
- }
- monitorp->Last = last;
-
- /* add the (VESA) default modes */
- if (! addDefaultModes(monitorp) )
- return FALSE;
-
- if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
- monitorp->gamma.red = conf_monitor->mon_gamma_red;
- if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
- monitorp->gamma.green = conf_monitor->mon_gamma_green;
- if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
- monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
-
- /* Check that the gamma values are within range */
- if (monitorp->gamma.red > GAMMA_ZERO &&
- (monitorp->gamma.red < GAMMA_MIN ||
- monitorp->gamma.red > GAMMA_MAX)) {
- badgamma = monitorp->gamma.red;
- } else if (monitorp->gamma.green > GAMMA_ZERO &&
- (monitorp->gamma.green < GAMMA_MIN ||
- monitorp->gamma.green > GAMMA_MAX)) {
- badgamma = monitorp->gamma.green;
- } else if (monitorp->gamma.blue > GAMMA_ZERO &&
- (monitorp->gamma.blue < GAMMA_MIN ||
- monitorp->gamma.blue > GAMMA_MAX)) {
- badgamma = monitorp->gamma.blue;
- }
- if (badgamma > GAMMA_ZERO) {
- xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
- badgamma, GAMMA_MIN, GAMMA_MAX);
- return FALSE;
- }
-
- xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
- xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
- &monitorp->reducedblanking);
- if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
- &maxPixClock) == TRUE) {
- monitorp->maxPixClock = (int) maxPixClock;
- }
-
- return TRUE;
-}
-
-static int
-lookupVisual(const char *visname)
-{
- int i;
-
- if (!visname || !*visname)
- return -1;
-
- for (i = 0; i <= DirectColor; i++) {
- if (!xf86nameCompare(visname, xf86VisualNames[i]))
- break;
- }
-
- if (i <= DirectColor)
- return i;
-
- return -1;
-}
-
-
-static Bool
-configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
-{
- int count = 0;
- XF86ModePtr modep;
-
- displayp->frameX0 = conf_display->disp_frameX0;
- displayp->frameY0 = conf_display->disp_frameY0;
- displayp->virtualX = conf_display->disp_virtualX;
- displayp->virtualY = conf_display->disp_virtualY;
- displayp->depth = conf_display->disp_depth;
- displayp->fbbpp = conf_display->disp_bpp;
- displayp->weight.red = conf_display->disp_weight.red;
- displayp->weight.green = conf_display->disp_weight.green;
- displayp->weight.blue = conf_display->disp_weight.blue;
- displayp->blackColour.red = conf_display->disp_black.red;
- displayp->blackColour.green = conf_display->disp_black.green;
- displayp->blackColour.blue = conf_display->disp_black.blue;
- displayp->whiteColour.red = conf_display->disp_white.red;
- displayp->whiteColour.green = conf_display->disp_white.green;
- displayp->whiteColour.blue = conf_display->disp_white.blue;
- displayp->options = conf_display->disp_option_lst;
- if (conf_display->disp_visual) {
- displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
- if (displayp->defaultVisual == -1) {
- xf86ConfigError("Invalid visual name: \"%s\"",
- conf_display->disp_visual);
- return FALSE;
- }
- } else {
- displayp->defaultVisual = -1;
- }
-
- /*
- * now hook in the modes
- */
- modep = conf_display->disp_mode_lst;
- while(modep) {
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes = xnfalloc((count+1) * sizeof(char*));
- modep = conf_display->disp_mode_lst;
- count = 0;
- while(modep) {
- displayp->modes[count] = modep->mode_name;
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes[count] = NULL;
-
- return TRUE;
-}
-
-static Bool
-configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
-{
- int i;
-
- if (!conf_device) {
- return FALSE;
- }
-
- if (active)
- xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
- conf_device->dev_identifier);
- else
- xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
- conf_device->dev_identifier);
-
- devicep->identifier = conf_device->dev_identifier;
- devicep->vendor = conf_device->dev_vendor;
- devicep->board = conf_device->dev_board;
- devicep->chipset = conf_device->dev_chipset;
- devicep->ramdac = conf_device->dev_ramdac;
- devicep->driver = conf_device->dev_driver;
- devicep->active = active;
- devicep->videoRam = conf_device->dev_videoram;
- devicep->BiosBase = conf_device->dev_bios_base;
- devicep->MemBase = conf_device->dev_mem_base;
- devicep->IOBase = conf_device->dev_io_base;
- devicep->clockchip = conf_device->dev_clockchip;
- devicep->busID = conf_device->dev_busid;
- devicep->textClockFreq = conf_device->dev_textclockfreq;
- devicep->chipID = conf_device->dev_chipid;
- devicep->chipRev = conf_device->dev_chiprev;
- devicep->options = conf_device->dev_option_lst;
- devicep->irq = conf_device->dev_irq;
- devicep->screen = conf_device->dev_screen;
-
- for (i = 0; i < MAXDACSPEEDS; i++) {
- if (i < CONF_MAXDACSPEEDS)
- devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
- else
- devicep->dacSpeeds[i] = 0;
- }
- devicep->numclocks = conf_device->dev_clocks;
- if (devicep->numclocks > MAXCLOCKS)
- devicep->numclocks = MAXCLOCKS;
- for (i = 0; i < devicep->numclocks; i++) {
- devicep->clock[i] = conf_device->dev_clock[i];
- }
- devicep->claimed = FALSE;
-
- return TRUE;
-}
-
-#ifdef XF86DRI
-static void
-configDRI(XF86ConfDRIPtr drip)
-{
- int count = 0;
- XF86ConfBuffersPtr bufs;
- int i;
- struct group *grp;
-
- xf86ConfigDRI.group = -1;
- xf86ConfigDRI.mode = 0;
- xf86ConfigDRI.bufs_count = 0;
- xf86ConfigDRI.bufs = NULL;
-
- if (drip) {
- if (drip->dri_group_name) {
- if ((grp = getgrnam(drip->dri_group_name)))
- xf86ConfigDRI.group = grp->gr_gid;
- } else {
- if (drip->dri_group >= 0)
- xf86ConfigDRI.group = drip->dri_group;
- }
- xf86ConfigDRI.mode = drip->dri_mode;
- for (bufs = drip->dri_buffers_lst; bufs; bufs = bufs->list.next)
- ++count;
-
- xf86ConfigDRI.bufs_count = count;
- xf86ConfigDRI.bufs = xnfalloc(count * sizeof(*xf86ConfigDRI.bufs));
-
- for (i = 0, bufs = drip->dri_buffers_lst;
- i < count;
- i++, bufs = bufs->list.next) {
-
- xf86ConfigDRI.bufs[i].count = bufs->buf_count;
- xf86ConfigDRI.bufs[i].size = bufs->buf_size;
- /* FIXME: Flags not implemented. These
- could be used, for example, to specify a
- contiguous block and/or write-combining
- cache policy. */
- xf86ConfigDRI.bufs[i].flags = 0;
- }
- }
-}
-#endif
-
-static void
-configExtensions(XF86ConfExtensionsPtr conf_ext)
-{
- XF86OptionPtr o;
-
- if (conf_ext && conf_ext->ext_option_lst) {
- for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
- char *name = xf86OptionName(o);
- char *val = xf86OptionValue(o);
- char *n;
- Bool enable = TRUE;
-
- /* Handle "No<ExtensionName>" */
- n = xf86NormalizeName(name);
- if (strncmp(n, "no", 2) == 0) {
- name += 2;
- enable = FALSE;
- }
-
- if (!val ||
- xf86NameCmp(val, "enable") == 0 ||
- xf86NameCmp(val, "enabled") == 0 ||
- xf86NameCmp(val, "on") == 0 ||
- xf86NameCmp(val, "1") == 0 ||
- xf86NameCmp(val, "yes") == 0 ||
- xf86NameCmp(val, "true") == 0) {
- /* NOTHING NEEDED -- enabling is handled below */
- } else if (xf86NameCmp(val, "disable") == 0 ||
- xf86NameCmp(val, "disabled") == 0 ||
- xf86NameCmp(val, "off") == 0 ||
- xf86NameCmp(val, "0") == 0 ||
- xf86NameCmp(val, "no") == 0 ||
- xf86NameCmp(val, "false") == 0) {
- enable = !enable;
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
- xfree(n);
- continue;
- }
-
- if (EnableDisableExtension(name, enable)) {
- xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
- name, enable ? "enabled" : "disabled");
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
- name);
- }
- xfree(n);
- }
- }
-}
-
-static Bool
-configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
-{
- xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
- inputp->identifier = conf_input->inp_identifier;
- inputp->driver = conf_input->inp_driver;
- inputp->commonOptions = conf_input->inp_option_lst;
- inputp->extraOptions = NULL;
-
- return TRUE;
-}
-
-static Bool
-modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
-{
- DisplayModePtr knownmodes = monitorp->Modes;
-
- /* all I can think of is a linear search... */
- while(knownmodes != NULL)
- {
- if(!strcmp(mode->name, knownmodes->name) &&
- !(knownmodes->type & M_T_DEFAULT))
- return TRUE;
- knownmodes = knownmodes->next;
- }
- return FALSE;
-}
-
-static Bool
-addDefaultModes(MonPtr monitorp)
-{
- DisplayModePtr mode;
- DisplayModePtr last = monitorp->Last;
- int i = 0;
-
- for (i = 0; i < xf86NumDefaultModes; i++)
- {
- mode = xf86DuplicateMode(&xf86DefaultModes[i]);
- if (!modeIsPresent(mode, monitorp))
- {
- monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
- last = mode;
- } else {
- xfree(mode);
- }
- }
- monitorp->Last = last;
-
- return TRUE;
-}
-
-static void
-checkInput(serverLayoutPtr layout, Bool implicit_layout) {
- checkCoreInputDevices(layout, implicit_layout);
-
- /* AllowEmptyInput and the "kbd" and "mouse" drivers are mutually
- * exclusive. Trawl the list for mouse/kbd devices and disable them.
- */
- if (xf86Info.allowEmptyInput && layout->inputs)
- {
- IDevPtr *dev = layout->inputs;
- BOOL warned = FALSE;
-
- while(*dev)
- {
- if (strcmp((*dev)->driver, "kbd") == 0 ||
- strcmp((*dev)->driver, "mouse") == 0 ||
- strcmp((*dev)->driver, "vmmouse") == 0)
- {
- IDevPtr *current;
- if (!warned)
- {
- xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
- "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
- warned = TRUE;
- }
-
- xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
-
- current = dev;
- xfree(*dev);
-
- do {
- *current = *(current + 1);
- current++;
- } while(*current);
- } else
- dev++;
- }
- }
-}
-
-/*
- * load the config file and fill the global data structure
- */
-ConfigStatus
-xf86HandleConfigFile(Bool autoconfig)
-{
- const char *filename, *dirname, *sysdirname;
- char *filesearch, *dirsearch;
- MessageType filefrom = X_DEFAULT;
- MessageType dirfrom = X_DEFAULT;
- char *scanptr;
- Bool singlecard = 0;
- Bool implicit_layout = FALSE;
-
- if (!autoconfig) {
- if (getuid() == 0) {
- filesearch = ROOT_CONFIGPATH;
- dirsearch = ROOT_CONFIGDIRPATH;
- } else {
- filesearch = USER_CONFIGPATH;
- dirsearch = USER_CONFIGDIRPATH;
- }
-
- if (xf86ConfigFile)
- filefrom = X_CMDLINE;
- if (xf86ConfigDir)
- dirfrom = X_CMDLINE;
-
- xf86initConfigFiles();
- sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
- PROJECTROOT);
- dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
- filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
- if (filename) {
- xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
- xf86ConfigFile = xnfstrdup(filename);
- } else {
- if (xf86ConfigFile)
- xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
- xf86ConfigFile);
- }
- if (dirname) {
- xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
- dirname);
- xf86ConfigDir = xnfstrdup(dirname);
- } else {
- if (xf86ConfigDir)
- xf86Msg(X_ERROR,
- "Unable to locate/open config directory: \"%s\"\n",
- xf86ConfigDir);
- }
- if (sysdirname)
- xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
- sysdirname);
- if (!filename && !dirname && !sysdirname)
- return CONFIG_NOFILE;
- }
-
- if ((xf86configptr = xf86readConfigFile ()) == NULL) {
- xf86Msg(X_ERROR, "Problem parsing the config file\n");
- return CONFIG_PARSE_ERROR;
- }
- xf86closeConfigFile ();
-
- /* Initialise a few things. */
-
- /*
- * now we convert part of the information contained in the parser
- * structures into our own structures.
- * The important part here is to figure out which Screen Sections
- * in the XF86Config file are active so that we can piece together
- * the modes that we need later down the road.
- * And while we are at it, we'll decode the rest of the stuff as well
- */
-
- /* First check if a layout section is present, and if it is valid. */
-
- if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
- if (xf86ScreenName == NULL) {
- xf86Msg(X_DEFAULT,
- "No Layout section. Using the first Screen section.\n");
- }
- if (!configImpliedLayout(&xf86ConfigLayout,
- xf86configptr->conf_screen_lst,
- xf86configptr)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- implicit_layout = TRUE;
- } else {
- if (xf86configptr->conf_flags != NULL) {
- char *dfltlayout = NULL;
- pointer optlist = xf86configptr->conf_flags->flg_option_lst;
-
- if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
- dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- dfltlayout)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- } else {
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- NULL)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- }
- }
-
- xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
-
- if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
- ; /* IsolateDevice specified; overrides SingleCard */
- } else {
- xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
- if (singlecard)
- scanptr = xf86ConfigLayout.screens->screen->device->busID;
- }
- if (scanptr) {
- int bus, device, func;
- if (strncmp(scanptr, "PCI:", 4) != 0) {
- xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
- "\tIgnoring IsolateDevice option.\n");
- } else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
- xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
- xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
- xf86IsolateDevice.dev = device;
- xf86IsolateDevice.func = func;
- xf86Msg(X_INFO,
- "Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
- }
- }
-
- /* Now process everything else */
- if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
- ErrorF ("Problem when converting the config data structures\n");
- return CONFIG_PARSE_ERROR;
- }
-
- configFiles(xf86configptr->conf_files);
- configExtensions(xf86configptr->conf_extensions);
-#ifdef XF86DRI
- configDRI(xf86configptr->conf_dri);
-#endif
-
- checkInput(&xf86ConfigLayout, implicit_layout);
-
- /*
- * Handle some command line options that can override some of the
- * ServerFlags settings.
- */
-#ifdef XF86VIDMODE
- if (xf86VidModeDisabled)
- xf86Info.vidModeEnabled = FALSE;
- if (xf86VidModeAllowNonLocal)
- xf86Info.vidModeAllowNonLocal = TRUE;
-#endif
-
- if (xf86AllowMouseOpenFail)
- xf86Info.allowMouseOpenFail = TRUE;
-
- return CONFIG_OK;
-}
-
-Bool
-xf86PathIsSafe(const char *path)
-{
- return (xf86pathIsSafe(path) != 0);
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+
+/*
+ * Copyright 1992-2003 by The XFree86 Project, Inc.
+ * Copyright 1997 by Metro Link, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ *
+ * Authors:
+ * Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * Marc La France <tsi@XFree86.Org>
+ * Egbert Eich <eich@XFree86.Org>
+ * ... and others
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XF86DRI
+#include <sys/types.h>
+#include <grp.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "xf86Config.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "configProcs.h"
+#include "globals.h"
+#include "extension.h"
+#include "Pci.h"
+
+#include "xf86Xinput.h"
+extern DeviceAssocRec mouse_assoc;
+
+#include "xkbsrv.h"
+
+#include "picture.h"
+
+/*
+ * These paths define the way the config file search is done. The escape
+ * sequences are documented in parser/scan.c.
+ */
+#ifndef ROOT_CONFIGPATH
+#define ROOT_CONFIGPATH "%A," "%R," \
+ "/etc/X11/%R," "%P/etc/X11/%R," \
+ "%E," "%F," \
+ "/etc/X11/%F," "%P/etc/X11/%F," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef USER_CONFIGPATH
+#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
+ "/etc/X11/%G," "%P/etc/X11/%G," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef ROOT_CONFIGDIRPATH
+#define ROOT_CONFIGDIRPATH "%A," "%R," \
+ "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef USER_CONFIGDIRPATH
+#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef SYS_CONFIGDIRPATH
+#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
+#endif
+#ifndef PROJECTROOT
+#define PROJECTROOT "/usr/X11R6"
+#endif
+
+static ModuleDefault ModuleDefaults[] = {
+ {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
+#ifdef DBE
+ {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef GLXEXT
+ {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XRECORD
+ {.name = "record", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XF86DRI
+ {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef DRI2
+ {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
+#endif
+ {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
+};
+
+
+/* Forward declarations */
+static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
+ int scrnum, MessageType from);
+static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
+static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
+ Bool active);
+static Bool configInput(IDevPtr inputp, XF86ConfInputPtr conf_input,
+ MessageType from);
+static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
+static Bool addDefaultModes(MonPtr monitorp);
+#ifdef XF86DRI
+static void configDRI(XF86ConfDRIPtr drip);
+#endif
+static void configExtensions(XF86ConfExtensionsPtr conf_ext);
+
+/*
+ * xf86GetPathElem --
+ * Extract a single element from the font path string starting at
+ * pnt. The font path element will be returned, and pnt will be
+ * updated to point to the start of the next element, or set to
+ * NULL if there are no more.
+ */
+static char *
+xf86GetPathElem(char **pnt)
+{
+ char *p1;
+
+ p1 = *pnt;
+ *pnt = index(*pnt, ',');
+ if (*pnt != NULL) {
+ **pnt = '\0';
+ *pnt += 1;
+ }
+ return(p1);
+}
+
+/*
+ * xf86ValidateFontPath --
+ * Validates the user-specified font path. Each element that
+ * begins with a '/' is checked to make sure the directory exists.
+ * If the directory exists, the existence of a file named 'fonts.dir'
+ * is checked. If either check fails, an error is printed and the
+ * element is removed from the font path.
+ */
+
+#define DIR_FILE "/fonts.dir"
+static char *
+xf86ValidateFontPath(char *path)
+{
+ char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
+ struct stat stat_buf;
+ int flag;
+ int dirlen;
+
+ tmp_path = calloc(1,strlen(path)+1);
+ out_pnt = tmp_path;
+ path_elem = NULL;
+ next = path;
+ while (next != NULL) {
+ path_elem = xf86GetPathElem(&next);
+ if (*path_elem == '/') {
+ dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
+ if ((p1 = strchr(path_elem, ':')) != 0)
+ dirlen = p1 - path_elem;
+ else
+ dirlen = strlen(path_elem);
+ strncpy(dir_elem, path_elem, dirlen);
+ dir_elem[dirlen] = '\0';
+ flag = stat(dir_elem, &stat_buf);
+ if (flag == 0)
+ if (!S_ISDIR(stat_buf.st_mode))
+ flag = -1;
+ if (flag != 0) {
+ xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ free(dir_elem);
+ continue;
+ }
+ else {
+ p1 = xnfalloc(strlen(dir_elem)+strlen(DIR_FILE)+1);
+ strcpy(p1, dir_elem);
+ strcat(p1, DIR_FILE);
+ flag = stat(p1, &stat_buf);
+ if (flag == 0)
+ if (!S_ISREG(stat_buf.st_mode))
+ flag = -1;
+ free(p1);
+ if (flag != 0) {
+ xf86Msg(X_WARNING,
+ "`fonts.dir' not found (or not valid) in \"%s\".\n",
+ dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
+ free(dir_elem);
+ continue;
+ }
+ }
+ free(dir_elem);
+ }
+
+ /*
+ * Either an OK directory, or a font server name. So add it to
+ * the path.
+ */
+ if (out_pnt != tmp_path)
+ *out_pnt++ = ',';
+ strcat(out_pnt, path_elem);
+ out_pnt += strlen(path_elem);
+ }
+ return(tmp_path);
+}
+
+
+/*
+ * use the datastructure that the parser provides and pick out the parts
+ * that we need at this point
+ */
+char **
+xf86ModulelistFromConfig(pointer **optlist)
+{
+ int count = 0, i = 0;
+ char **modulearray;
+ char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
+ "freetype", "type1",
+ NULL };
+ pointer *optarray;
+ XF86LoadPtr modp;
+ Bool found;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ if (xf86configptr->conf_modules) {
+ /* Walk the disable list and let people know what we've parsed to
+ * not be loaded
+ */
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ /*
+ * Walk the default settings table. For each module listed to be
+ * loaded, make sure it's in the mod_load_lst. If it's not, make
+ * sure it's not in the mod_no_load_lst. If it's not disabled,
+ * append it to mod_load_lst
+ */
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == FALSE) {
+ xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
+ continue;
+ }
+ found = FALSE;
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ if (found == FALSE) {
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ if (found == FALSE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
+ }
+ }
+ } else {
+ xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == TRUE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ }
+ }
+ }
+
+ /*
+ * Walk the list of modules in the "Module" section to determine how
+ * many we have.
+ */
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ for (i = 0; ignore[i]; i++) {
+ if (strcmp(modp->load_name, ignore[i]) == 0)
+ modp->ignore = 1;
+ }
+ if (!modp->ignore)
+ count++;
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ optarray = xnfalloc((count + 1) * sizeof(pointer));
+ count = 0;
+ if (xf86configptr->conf_modules) {
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (!modp->ignore) {
+ modulearray[count] = modp->load_name;
+ optarray[count] = modp->load_opt;
+ count++;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ modulearray[count] = NULL;
+ optarray[count] = NULL;
+ if (optlist)
+ *optlist = optarray;
+ else
+ free(optarray);
+ return modulearray;
+}
+
+
+char **
+xf86DriverlistFromConfig(void)
+{
+ int count = 0;
+ int j;
+ char **modulearray;
+ screenLayoutPtr slp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "Device" sections to
+ * determine now many implicitly loaded modules there are.
+ *
+ */
+ if (xf86ConfigLayout.screens) {
+ slp = xf86ConfigLayout.screens;
+ while ((slp++)->screen) {
+ count++;
+ }
+ }
+
+ /*
+ * Handle the set of inactive "Device" sections.
+ */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j++].identifier)
+ count++;
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ slp = xf86ConfigLayout.screens;
+ while (slp->screen) {
+ modulearray[count] = slp->screen->device->driver;
+ count++;
+ slp++;
+ }
+
+ j = 0;
+
+ while (xf86ConfigLayout.inactives[j].identifier)
+ modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
+
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+char **
+xf86InputDriverlistFromConfig(void)
+{
+ int count = 0;
+ char **modulearray;
+ IDevPtr* idp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "InputDevice" sections to
+ * determine now many implicitly loaded modules there are.
+ */
+ if (xf86ConfigLayout.inputs) {
+ idp = xf86ConfigLayout.inputs;
+ while (*idp) {
+ count++;
+ idp++;
+ }
+ }
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ idp = xf86ConfigLayout.inputs;
+ while (idp && *idp) {
+ modulearray[count] = (*idp)->driver;
+ count++;
+ idp++;
+ }
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+static void
+fixup_video_driver_list(char **drivers)
+{
+ static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
+ char **end, **drv;
+ char *x;
+ char **ati, **atimisc;
+ int i;
+
+ /* walk to the end of the list */
+ for (end = drivers; *end && **end; end++) ;
+ end--;
+
+ /*
+ * for each of the fallback drivers, if we find it in the list,
+ * swap it with the last available non-fallback driver.
+ */
+ for (i = 0; fallback[i]; i++) {
+ for (drv = drivers; drv != end; drv++) {
+ if (strstr(*drv, fallback[i])) {
+ x = *drv; *drv = *end; *end = x;
+ end--;
+ break;
+ }
+ }
+ }
+ /*
+ * since the ati wrapper driver is gross and awful, sort ati before
+ * atimisc, which makes sure all the ati symbols are visible in xorgcfg.
+ */
+ for (drv = drivers; drv != end; drv++) {
+ if (!strcmp(*drv, "atimisc")) {
+ atimisc = drv;
+ for (drv = atimisc; drv != end; drv++) {
+ if (!strcmp(*drv, "ati")) {
+ ati = drv;
+ x = *ati; *ati = *atimisc; *atimisc = x;
+ return;
+ }
+ }
+ /* if we get here, ati was already ahead of atimisc */
+ return;
+ }
+ }
+}
+
+static char **
+GenerateDriverlist(char * dirname)
+{
+ char **ret;
+ const char *subdirs[] = { dirname, NULL };
+ static const char *patlist[] = {"(.*)_drv\\.so", "(.*)_drv\\.o", NULL};
+ ret = LoaderListDirs(subdirs, patlist);
+
+ /* fix up the probe order for video drivers */
+ if (strstr(dirname, "drivers") && ret != NULL)
+ fixup_video_driver_list(ret);
+
+ return ret;
+}
+
+char **
+xf86DriverlistFromCompile(void)
+{
+ static char **driverlist = NULL;
+
+ if (!driverlist)
+ driverlist = GenerateDriverlist("drivers");
+
+ return driverlist;
+}
+
+/*
+ * xf86ConfigError --
+ * Print a READABLE ErrorMessage!!! All information that is
+ * available is printed.
+ */
+static void
+xf86ConfigError(char *msg, ...)
+{
+ va_list ap;
+
+ ErrorF("\nConfig Error:\n");
+ va_start(ap, msg);
+ VErrorF(msg, ap);
+ va_end(ap);
+ ErrorF("\n");
+ return;
+}
+
+static void
+configFiles(XF86ConfFilesPtr fileconf)
+{
+ MessageType pathFrom;
+ Bool must_copy;
+ int size, countDirs;
+ char *temp_path, *log_buf, *start, *end;
+
+ /* FontPath */
+ must_copy = TRUE;
+
+ temp_path = defaultFontPath ? defaultFontPath : "";
+ if (xf86fpFlag)
+ pathFrom = X_CMDLINE;
+ else if (fileconf && fileconf->file_fontpath) {
+ pathFrom = X_CONFIG;
+ if (xf86Info.useDefaultFontPath) {
+ defaultFontPath = Xprintf("%s%s%s",
+ fileconf->file_fontpath,
+ *temp_path ? "," : "", temp_path);
+ if (defaultFontPath != NULL) {
+ must_copy = FALSE;
+ }
+ }
+ else
+ defaultFontPath = fileconf->file_fontpath;
+ }
+ else
+ pathFrom = X_DEFAULT;
+ temp_path = defaultFontPath ? defaultFontPath : "";
+
+ /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
+ temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
+ defaultFontPath = xf86ValidateFontPath(temp_path);
+ free(temp_path);
+
+ /* make fontpath more readable in the logfiles */
+ countDirs = 1;
+ temp_path = defaultFontPath;
+ while ((temp_path = index(temp_path, ',')) != NULL) {
+ countDirs++;
+ temp_path++;
+ }
+
+ log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
+ temp_path = log_buf;
+ start = defaultFontPath;
+ while((end = index(start, ',')) != NULL) {
+ size = (end - start) + 1;
+ *(temp_path++) = '\t';
+ strncpy(temp_path, start, size);
+ temp_path += size;
+ *(temp_path++) = '\n';
+ start += size;
+ }
+ /* copy last entry */
+ *(temp_path++) = '\t';
+ strcpy(temp_path, start);
+ xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
+ free(log_buf);
+
+ /* ModulePath */
+
+ if (fileconf) {
+ if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
+ xf86ModulePath = fileconf->file_modulepath;
+ xf86ModPathFrom = X_CONFIG;
+ }
+ }
+
+ xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
+
+ if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
+ XkbBaseDirectory = fileconf->file_xkbdir;
+ xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
+ XkbBaseDirectory);
+ }
+#if 0
+ /* LogFile */
+ /*
+ * XXX The problem with this is that the log file is already open.
+ * One option might be to copy the exiting contents to the new location.
+ * and re-open it. The down side is that the default location would
+ * already have been overwritten. Another option would be to start with
+ * unique temporary location, then copy it once the correct name is known.
+ * A problem with this is what happens if the server exits before that
+ * happens.
+ */
+ if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
+ xf86LogFile = fileconf->file_logfile;
+ xf86LogFileFrom = X_CONFIG;
+ }
+#endif
+
+ return;
+}
+
+typedef enum {
+ FLAG_NOTRAPSIGNALS,
+ FLAG_DONTVTSWITCH,
+ FLAG_DONTZAP,
+ FLAG_DONTZOOM,
+ FLAG_DISABLEVIDMODE,
+ FLAG_ALLOWNONLOCAL,
+ FLAG_ALLOWMOUSEOPENFAIL,
+ FLAG_VTSYSREQ,
+ FLAG_SAVER_BLANKTIME,
+ FLAG_DPMS_STANDBYTIME,
+ FLAG_DPMS_SUSPENDTIME,
+ FLAG_DPMS_OFFTIME,
+ FLAG_PIXMAP,
+ FLAG_PC98,
+ FLAG_NOPM,
+ FLAG_XINERAMA,
+ FLAG_LOG,
+ FLAG_RENDER_COLORMAP_MODE,
+ FLAG_RANDR,
+ FLAG_AIGLX,
+ FLAG_IGNORE_ABI,
+ FLAG_ALLOW_EMPTY_INPUT,
+ FLAG_USE_DEFAULT_FONT_PATH,
+ FLAG_AUTO_ADD_DEVICES,
+ FLAG_AUTO_ENABLE_DEVICES,
+ FLAG_GLX_VISUALS,
+ FLAG_DRI2,
+ FLAG_USE_SIGIO
+} FlagValues;
+
+/**
+ * NOTE: the last value for each entry is NOT the default. It is set to TRUE
+ * if the parser found the option in the config file.
+ */
+static OptionInfoRec FlagOptions[] = {
+ { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PC98, "PC98", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_LOG, "Log", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOW_EMPTY_INPUT, "AllowEmptyInput", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+#ifdef SUPPORT_PC98
+static Bool
+detectPC98(void)
+{
+ unsigned char buf[2];
+
+ if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
+ return FALSE;
+ if ((buf[0] == 0x98) && (buf[1] == 0x21))
+ return TRUE;
+ else
+ return FALSE;
+}
+#endif
+
+static Bool
+configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
+{
+ XF86OptionPtr optp, tmp;
+ int i;
+ Pix24Flags pix24 = Pix24DontCare;
+ Bool value;
+ MessageType from;
+ const char *s;
+ XkbRMLVOSet set;
+ /* Default options. */
+ set.rules = "base";
+ set.model = "pc105";
+ set.layout = "us";
+ set.variant = NULL;
+ set.options = NULL;
+
+ /*
+ * Merge the ServerLayout and ServerFlags options. The former have
+ * precedence over the latter.
+ */
+ optp = NULL;
+ if (flagsconf && flagsconf->flg_option_lst)
+ optp = xf86optionListDup(flagsconf->flg_option_lst);
+ if (layoutopts) {
+ tmp = xf86optionListDup(layoutopts);
+ if (optp)
+ optp = xf86optionListMerge(optp, tmp);
+ else
+ optp = tmp;
+ }
+
+ xf86ProcessOptions(-1, optp, FlagOptions);
+
+ xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
+
+ xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
+ if (xf86Info.ignoreABI) {
+ xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
+ }
+
+ if (xf86SIGIOSupported()) {
+ xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
+ if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
+ from = X_CONFIG;
+ } else {
+ from = X_DEFAULT;
+ }
+ if (!xf86Info.useSIGIO) {
+ xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
+ } else if (from == X_CONFIG) {
+ xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
+ }
+ } else {
+ xf86Info.useSIGIO = FALSE;
+ }
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
+ &xf86Info.autoAddDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically adding devices\n",
+ xf86Info.autoAddDevices ? "A" : "Not a");
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
+ &xf86Info.autoEnableDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically enabling devices\n",
+ xf86Info.autoEnableDevices ? "A" : "Not a");
+
+ /*
+ * Set things up based on the config file information. Some of these
+ * settings may be overridden later when the command line options are
+ * checked.
+ */
+#ifdef XF86VIDMODE
+ if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
+ xf86Info.vidModeEnabled = !value;
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
+ xf86Info.vidModeAllowNonLocal = value;
+#endif
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
+ xf86Info.allowMouseOpenFail = value;
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
+#ifdef USE_VT_SYSREQ
+ xf86Info.vtSysreq = value;
+ xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
+#else
+ if (value)
+ xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
+#endif
+ }
+
+ xf86Info.pmFlag = TRUE;
+ if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
+ xf86Info.pmFlag = !value;
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
+ if (!xf86NameCmp(s,"flush")) {
+ xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
+ xf86Info.log = LogFlush;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ } else if (!xf86NameCmp(s,"sync")) {
+ xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
+ xf86Info.log = LogSync;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ LogSetParameter(XLOG_SYNC, TRUE);
+ } else {
+ xf86Msg(X_WARNING,"Unknown Log option\n");
+ }
+ }
+ }
+
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
+ int policy = PictureParseCmapPolicy (s);
+ if (policy == PictureCmapPolicyInvalid)
+ xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
+ else
+ {
+ xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
+ PictureCmapPolicy = policy;
+ }
+ }
+ }
+
+#ifdef RANDR
+ xf86Info.disableRandR = FALSE;
+ xf86Info.randRFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
+ xf86Info.disableRandR = !value;
+ xf86Info.randRFrom = X_CONFIG;
+ }
+#endif
+
+ xf86Info.aiglx = TRUE;
+ xf86Info.aiglxFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+
+#ifdef GLXEXT
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ xf86Info.glxVisualsFrom = X_DEFAULT;
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
+ if (!xf86NameCmp(s, "minimal")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
+ } else if (!xf86NameCmp(s, "typical")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ } else if (!xf86NameCmp(s, "all")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsAll;
+ } else {
+ xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
+ }
+ }
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+#endif
+
+ /* AllowEmptyInput is automatically true if we're hotplugging */
+ xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
+ xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput);
+
+ /* AEI on? Then we're not using kbd, so use the evdev rules set. */
+#if defined(linux)
+ if (xf86Info.allowEmptyInput)
+ set.rules = "evdev";
+#endif
+ XkbSetRulesDflts(&set);
+
+ xf86Info.useDefaultFontPath = TRUE;
+ xf86Info.useDefaultFontPathFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
+ xf86Info.useDefaultFontPath = value;
+ xf86Info.useDefaultFontPathFrom = X_CONFIG;
+ }
+
+/* Make sure that timers don't overflow CARD32's after multiplying */
+#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+
+#ifdef DPMSExtension
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSStandbyTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSSuspendTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSOffTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+#endif
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
+ switch (i) {
+ case 24:
+ pix24 = Pix24Use24;
+ break;
+ case 32:
+ pix24 = Pix24Use32;
+ break;
+ case -1:
+ break;
+ default:
+ xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
+ return FALSE;
+ }
+ if (xf86Pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = xf86Pix24;
+ xf86Info.pix24From = X_CMDLINE;
+ } else if (pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = pix24;
+ xf86Info.pix24From = X_CONFIG;
+ } else {
+ xf86Info.pixmap24 = Pix24DontCare;
+ xf86Info.pix24From = X_DEFAULT;
+ }
+#ifdef SUPPORT_PC98
+ if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
+ xf86Info.pc98 = value;
+ if (value) {
+ xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
+ }
+ } else
+ if (detectPC98()) {
+ xf86Info.pc98 = TRUE;
+ xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
+ }
+#endif
+
+#ifdef PANORAMIX
+ from = X_DEFAULT;
+ if (!noPanoramiXExtension)
+ from = X_CMDLINE;
+ else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
+ noPanoramiXExtension = !value;
+ from = X_CONFIG;
+ }
+ if (!noPanoramiXExtension)
+ xf86Msg(from, "Xinerama: enabled\n");
+#endif
+
+#ifdef DRI2
+ xf86Info.dri2 = FALSE;
+ xf86Info.dri2From = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
+ xf86Info.dri2 = value;
+ xf86Info.dri2From = X_CONFIG;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool xf86DRI2Enabled(void)
+{
+ return xf86Info.dri2;
+}
+
+/*
+ * Locate the core input devices. These can be specified/located in
+ * the following ways, in order of priority:
+ *
+ * 1. The InputDevices named by the -pointer and -keyboard command line
+ * options.
+ * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
+ * the active ServerLayout.
+ * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
+ * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
+ * driver (mouse, synaptics, evdev, vmmouse, void)
+ * 5. Default devices with an empty (default) configuration. These defaults
+ * will reference the 'mouse' and 'keyboard' drivers.
+ */
+
+static Bool
+checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
+{
+ IDevPtr corePointer = NULL, coreKeyboard = NULL;
+ Bool foundPointer = FALSE, foundKeyboard = FALSE;
+ const char *pointerMsg = NULL, *keyboardMsg = NULL;
+ IDevPtr *devs, /* iterator */
+ indp;
+ IDevRec Pointer, Keyboard;
+ XF86ConfInputPtr confInput;
+ XF86ConfInputRec defPtr, defKbd;
+ int count = 0;
+ MessageType from = X_DEFAULT;
+ int found = 0;
+ const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
+ "void", NULL };
+
+ /*
+ * First check if a core pointer or core keyboard have been specified
+ * in the active ServerLayout. If more than one is specified for either,
+ * remove the core attribute from the later ones.
+ */
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ pointer opt1 = NULL, opt2 = NULL;
+ indp = *devs;
+ if (indp->commonOptions &&
+ xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
+ opt1 = indp->commonOptions;
+ }
+ if (indp->extraOptions &&
+ xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
+ opt2 = indp->extraOptions;
+ }
+ if (opt1 || opt2) {
+ if (!corePointer) {
+ corePointer = indp;
+ } else {
+ if (opt1)
+ xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
+ if (opt2)
+ xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
+ xf86Msg(X_WARNING, "Duplicate core pointer devices. "
+ "Removing core pointer attribute from \"%s\"\n",
+ indp->identifier);
+ }
+ }
+ opt1 = opt2 = NULL;
+ if (indp->commonOptions &&
+ xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
+ opt1 = indp->commonOptions;
+ }
+ if (indp->extraOptions &&
+ xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
+ opt2 = indp->extraOptions;
+ }
+ if (opt1 || opt2) {
+ if (!coreKeyboard) {
+ coreKeyboard = indp;
+ } else {
+ if (opt1)
+ xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
+ if (opt2)
+ xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
+ xf86Msg(X_WARNING, "Duplicate core keyboard devices. "
+ "Removing core keyboard attribute from \"%s\"\n",
+ indp->identifier);
+ }
+ }
+ count++;
+ }
+
+ confInput = NULL;
+
+ /* 1. Check for the -pointer command line option. */
+ if (xf86PointerName) {
+ confInput = xf86findInput(xf86PointerName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86PointerName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * removed.
+ */
+ if (corePointer) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == corePointer)
+ {
+ free(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
+ break;
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
+ count--;
+ }
+ corePointer = NULL;
+ foundPointer = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core pointer. */
+ if (corePointer) {
+ foundPointer = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core pointer device. */
+ if (!foundPointer && (!xf86Info.allowEmptyInput || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
+ confInput = p;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first core pointer device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First pointer with an allowed mouse driver. */
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ const char **driver = mousedrivers;
+ confInput = xf86findInput(CONF_IMPLICIT_POINTER,
+ xf86configptr->conf_input_lst);
+ while (*driver && !confInput) {
+ confInput = xf86findInputByDriver(*driver,
+ xf86configptr->conf_input_lst);
+ driver++;
+ }
+ if (confInput) {
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first mouse device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ bzero(&defPtr, sizeof(defPtr));
+ defPtr.inp_identifier = strdup("<default pointer>");
+ defPtr.inp_driver = strdup("mouse");
+ confInput = &defPtr;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "default mouse configuration";
+ }
+
+ /* Add the core pointer device to the layout, and set it to Core. */
+ if (foundPointer && confInput) {
+ foundPointer = configInput(&Pointer, confInput, from);
+ if (foundPointer) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
+ return FALSE;
+ }
+
+ /*
+ * always synthesize a 'mouse' section configured to send core
+ * events, unless a 'void' section is found, in which case the user
+ * probably wants to run footless.
+ *
+ * If you're using an evdev keyboard and expect a default mouse
+ * section ... deal.
+ */
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ const char **driver = mousedrivers;
+ while(*driver) {
+ if (!strcmp((*devs)->driver, *driver)) {
+ found = 1;
+ break;
+ }
+ driver++;
+ }
+ }
+ if (!found && !xf86Info.allowEmptyInput) {
+ xf86Msg(X_INFO, "No default mouse found, adding one\n");
+ bzero(&defPtr, sizeof(defPtr));
+ defPtr.inp_identifier = strdup("<default pointer>");
+ defPtr.inp_driver = strdup("mouse");
+ confInput = &defPtr;
+ foundPointer = configInput(&Pointer, confInput, from);
+ if (foundPointer) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ confInput = NULL;
+
+ /* 1. Check for the -keyboard command line option. */
+ if (xf86KeyboardName) {
+ confInput = xf86findInput(xf86KeyboardName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86KeyboardName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * removed.
+ */
+ if (coreKeyboard) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == coreKeyboard)
+ {
+ free(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
+ break;
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
+ count--;
+ }
+ coreKeyboard = NULL;
+ foundKeyboard = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core keyboard. */
+ if (coreKeyboard) {
+ foundKeyboard = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core keyboard device. */
+ if (!foundKeyboard && (!xf86Info.allowEmptyInput || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
+ confInput = p;
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first core keyboard device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ confInput = xf86findInputByDriver("kbd",
+ xf86configptr->conf_input_lst);
+ }
+ if (confInput) {
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first keyboard device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ bzero(&defKbd, sizeof(defKbd));
+ defKbd.inp_identifier = strdup("<default keyboard>");
+ defKbd.inp_driver = strdup("kbd");
+ confInput = &defKbd;
+ foundKeyboard = TRUE;
+ keyboardMsg = "default keyboard configuration";
+ from = X_DEFAULT;
+ }
+
+ /* Add the core keyboard device to the layout, and set it to Core. */
+ if (foundKeyboard && confInput) {
+ foundKeyboard = configInput(&Keyboard, confInput, from);
+ if (foundKeyboard) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Keyboard;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
+ return FALSE;
+ }
+
+ if (pointerMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ pointerMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", pointerMsg);
+ }
+
+ if (keyboardMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ keyboardMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", keyboardMsg);
+ }
+
+ if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
+#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
+ const char *config_backend;
+#if defined(CONFIG_HAL)
+ config_backend = "HAL";
+#else
+ config_backend = "udev";
+#endif
+ xf86Msg(X_INFO, "The server relies on %s to provide the list of "
+ "input devices.\n\tIf no devices become available, "
+ "reconfigure %s or disable AutoAddDevices.\n",
+ config_backend, config_backend);
+#else
+ xf86Msg(X_INFO, "Hotplugging is disabled and no input devices were configured.\n"
+ "\tTry disabling AllowEmptyInput.\n");
+#endif
+ }
+
+ return TRUE;
+}
+
+typedef enum {
+ LAYOUT_ISOLATEDEVICE,
+ LAYOUT_SINGLECARD
+} LayoutValues;
+
+static OptionInfoRec LayoutOptions[] = {
+ { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
+ {0}, FALSE },
+ { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
+{
+ XF86ConfInputrefPtr irp;
+ IDevPtr *indp;
+ int count = 0;
+
+ /*
+ * Count the number of input devices.
+ */
+ irp = layout->lay_input_lst;
+ while (irp) {
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ DebugF("Found %d input devices in the layout section %s\n",
+ count, layout->lay_identifier);
+ indp = xnfcalloc((count + 1), sizeof(IDevPtr));
+ indp[count] = NULL;
+ irp = layout->lay_input_lst;
+ count = 0;
+ while (irp) {
+ indp[count] = xnfalloc(sizeof(IDevRec));
+ if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
+ while(count--)
+ free(indp[count]);
+ free(indp);
+ return FALSE;
+ }
+ indp[count]->extraOptions = irp->iref_option_lst;
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ servlayoutp->inputs = indp;
+
+ return TRUE;
+}
+
+
+/*
+ * figure out which layout is active, which screens are used in that layout,
+ * which drivers and monitors are used in these screens
+ */
+static Bool
+configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
+ char *default_layout)
+{
+ XF86ConfAdjacencyPtr adjp;
+ XF86ConfInactivePtr idp;
+ int count = 0;
+ int scrnum;
+ XF86ConfLayoutPtr l;
+ MessageType from;
+ screenLayoutPtr slp;
+ GDevPtr gdp;
+ int i = 0, j;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which layout section is the active one?
+ *
+ * If there is a -layout command line option, use that one, otherwise
+ * pick the first one.
+ */
+ from = X_DEFAULT;
+ if (xf86LayoutName != NULL)
+ from = X_CMDLINE;
+ else if (default_layout) {
+ xf86LayoutName = default_layout;
+ from = X_CONFIG;
+ }
+ if (xf86LayoutName != NULL) {
+ if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
+ xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
+ xf86LayoutName);
+ return FALSE;
+ }
+ conf_layout = l;
+ }
+ xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
+ adjp = conf_layout->lay_adjacency_lst;
+
+ /*
+ * we know that each screen is referenced exactly once on the left side
+ * of a layout statement in the Layout section. So to allocate the right
+ * size for the array we do a quick walk of the list to figure out how
+ * many sections we have
+ */
+ while (adjp) {
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ DebugF("Found %d screens in the layout section %s",
+ count, conf_layout->lay_identifier);
+ if (!count) /* alloc enough storage even if no screen is specified */
+ count = 1;
+
+ slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
+ slp[count].screen = NULL;
+ /*
+ * now that we have storage, loop over the list again and fill in our
+ * data structure; at this point we do not fill in the adjacency
+ * information as it is not clear if we need it at all
+ */
+ adjp = conf_layout->lay_adjacency_lst;
+ count = 0;
+ while (adjp) {
+ slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (adjp->adj_scrnum < 0)
+ scrnum = count;
+ else
+ scrnum = adjp->adj_scrnum;
+ if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
+ X_CONFIG)) {
+ free(slp);
+ return FALSE;
+ }
+ slp[count].x = adjp->adj_x;
+ slp[count].y = adjp->adj_y;
+ slp[count].refname = adjp->adj_refscreen;
+ switch (adjp->adj_where) {
+ case CONF_ADJ_OBSOLETE:
+ slp[count].where = PosObsolete;
+ slp[count].topname = adjp->adj_top_str;
+ slp[count].bottomname = adjp->adj_bottom_str;
+ slp[count].leftname = adjp->adj_left_str;
+ slp[count].rightname = adjp->adj_right_str;
+ break;
+ case CONF_ADJ_ABSOLUTE:
+ slp[count].where = PosAbsolute;
+ break;
+ case CONF_ADJ_RIGHTOF:
+ slp[count].where = PosRightOf;
+ break;
+ case CONF_ADJ_LEFTOF:
+ slp[count].where = PosLeftOf;
+ break;
+ case CONF_ADJ_ABOVE:
+ slp[count].where = PosAbove;
+ break;
+ case CONF_ADJ_BELOW:
+ slp[count].where = PosBelow;
+ break;
+ case CONF_ADJ_RELATIVE:
+ slp[count].where = PosRelative;
+ break;
+ }
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ /* No screen was specified in the layout. take the first one from the
+ * config file, or - if it is NULL - configScreen autogenerates one for
+ * us */
+ if (!count)
+ {
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
+ 0, X_CONFIG)) {
+ free(slp[0].screen);
+ free(slp);
+ return FALSE;
+ }
+ }
+
+ /* XXX Need to tie down the upper left screen. */
+
+ /* Fill in the refscreen and top/bottom/left/right values */
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < count; j++) {
+ if (slp[i].refname &&
+ strcmp(slp[i].refname, slp[j].screen->id) == 0) {
+ slp[i].refscreen = slp[j].screen;
+ }
+ if (slp[i].topname &&
+ strcmp(slp[i].topname, slp[j].screen->id) == 0) {
+ slp[i].top = slp[j].screen;
+ }
+ if (slp[i].bottomname &&
+ strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
+ slp[i].bottom = slp[j].screen;
+ }
+ if (slp[i].leftname &&
+ strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
+ slp[i].left = slp[j].screen;
+ }
+ if (slp[i].rightname &&
+ strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
+ slp[i].right = slp[j].screen;
+ }
+ }
+ if (slp[i].where != PosObsolete
+ && slp[i].where != PosAbsolute
+ && !slp[i].refscreen) {
+ xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
+ slp[i].refname);
+ slp[i].where = PosAbsolute;
+ slp[i].x = 0;
+ slp[i].y = 0;
+ }
+ }
+
+ /*
+ * Count the number of inactive devices.
+ */
+ count = 0;
+ idp = conf_layout->lay_inactive_lst;
+ while (idp) {
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+ DebugF("Found %d inactive devices in the layout section %s\n",
+ count, conf_layout->lay_identifier);
+ gdp = xnfalloc((count + 1) * sizeof(GDevRec));
+ gdp[count].identifier = NULL;
+ idp = conf_layout->lay_inactive_lst;
+ count = 0;
+ while (idp) {
+ if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) {
+ free(gdp);
+ return FALSE;
+ }
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+
+ if (!configInputDevices(conf_layout, servlayoutp))
+ return FALSE;
+
+ servlayoutp->id = conf_layout->lay_identifier;
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = gdp;
+ servlayoutp->options = conf_layout->lay_option_lst;
+ from = X_DEFAULT;
+
+ return TRUE;
+}
+
+/*
+ * No layout section, so find the first Screen section and set that up as
+ * the only active screen.
+ */
+static Bool
+configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
+ XF86ConfigPtr xf86configptr)
+{
+ MessageType from;
+ XF86ConfScreenPtr s;
+ screenLayoutPtr slp;
+ IDevPtr *indp;
+ XF86ConfLayoutRec layout;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which screen section is the active one?
+ *
+ * If there is a -screen option, use that one, otherwise use the first
+ * one.
+ */
+
+ from = X_CONFIG;
+ if (xf86ScreenName != NULL) {
+ if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
+ xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
+ xf86ScreenName);
+ return FALSE;
+ }
+ conf_screen = s;
+ from = X_CMDLINE;
+ }
+
+ /* We have exactly one screen */
+
+ slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ slp[1].screen = NULL;
+ if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
+ free(slp);
+ return FALSE;
+ }
+ servlayoutp->id = "(implicit)";
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
+ servlayoutp->options = NULL;
+
+ memset(&layout, 0, sizeof(layout));
+ layout.lay_identifier = servlayoutp->id;
+ if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
+ if (!configInputDevices(&layout, servlayoutp))
+ return FALSE;
+ from = X_DEFAULT;
+ } else {
+ /* Set up an empty input device list, then look for some core devices. */
+ indp = xnfalloc(sizeof(IDevPtr));
+ *indp = NULL;
+ servlayoutp->inputs = indp;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
+{
+ int count = 0;
+ XF86ConfVideoPortPtr conf_port;
+
+ xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
+ conf_adaptor->va_identifier);
+ adaptor->identifier = conf_adaptor->va_identifier;
+ adaptor->options = conf_adaptor->va_option_lst;
+ if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
+ xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
+ return FALSE;
+ }
+
+ /*
+ * figure out how many videoport subsections there are and fill them in
+ */
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+ adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
+ adaptor->numports = count;
+ count = 0;
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ adaptor->ports[count].identifier = conf_port->vp_identifier;
+ adaptor->ports[count].options = conf_port->vp_option_lst;
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
+ MessageType from)
+{
+ int count = 0;
+ XF86ConfDisplayPtr dispptr;
+ XF86ConfAdaptorLinkPtr conf_adaptor;
+ Bool defaultMonitor = FALSE;
+
+ if (!conf_screen) {
+ conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
+ conf_screen->scrn_identifier = "Default Screen Section";
+ xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
+ }
+
+ xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
+ scrnum);
+ /*
+ * now we fill in the elements of the screen
+ */
+ screenp->id = conf_screen->scrn_identifier;
+ screenp->screennum = scrnum;
+ screenp->defaultdepth = conf_screen->scrn_defaultdepth;
+ screenp->defaultbpp = conf_screen->scrn_defaultbpp;
+ screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
+ screenp->monitor = xnfcalloc(1, sizeof(MonRec));
+ /* If no monitor is specified, create a default one. */
+ if (!conf_screen->scrn_monitor) {
+ XF86ConfMonitorRec defMon;
+
+ bzero(&defMon, sizeof(defMon));
+ defMon.mon_identifier = "<default monitor>";
+ if (!configMonitor(screenp->monitor, &defMon))
+ return FALSE;
+ defaultMonitor = TRUE;
+ } else {
+ if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
+ return FALSE;
+ }
+ /* Configure the device. If there isn't one configured, attach to the
+ * first inactive one that we can configure. If there's none that work,
+ * set it to NULL so that the section can be autoconfigured later */
+ screenp->device = xnfcalloc(1, sizeof(GDevRec));
+ if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
+ conf_screen->scrn_device = xf86configptr->conf_device_lst;
+ xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
+ "\tUsing the first device section listed.\n", screenp->id);
+ }
+ if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
+ screenp->device->myScreenSection = screenp;
+ } else {
+ screenp->device = NULL;
+ }
+ screenp->options = conf_screen->scrn_option_lst;
+
+ /*
+ * figure out how many display subsections there are and fill them in
+ */
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+ screenp->displays = xnfalloc((count) * sizeof(DispRec));
+ screenp->numdisplays = count;
+
+ /* Fill in the default Virtual size, if any */
+ if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
+ for (count = 0, dispptr = conf_screen->scrn_display_lst;
+ dispptr;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
+ screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
+ screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
+ }
+ }
+
+ /* Now do the per-Display Virtual sizes */
+ count = 0;
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ configDisplay(&(screenp->displays[count]),dispptr);
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+
+ /*
+ * figure out how many videoadaptor references there are and fill them in
+ */
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ count++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+ screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
+ screenp->numxvadaptors = 0;
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
+ conf_adaptor->al_adaptor))
+ screenp->numxvadaptors++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+
+ if (defaultMonitor) {
+ xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
+ "\tUsing a default monitor configuration.\n", screenp->id);
+ }
+ return TRUE;
+}
+
+typedef enum {
+ MON_REDUCEDBLANKING,
+ MON_MAX_PIX_CLOCK,
+} MonitorValues;
+
+static OptionInfoRec MonitorOptions[] = {
+ { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
+{
+ int count;
+ DisplayModePtr mode,last = NULL;
+ XF86ConfModeLinePtr cmodep;
+ XF86ConfModesPtr modes;
+ XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
+ Gamma zeros = {0.0, 0.0, 0.0};
+ float badgamma = 0.0;
+ double maxPixClock;
+
+ xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
+ conf_monitor->mon_identifier);
+ monitorp->id = conf_monitor->mon_identifier;
+ monitorp->vendor = conf_monitor->mon_vendor;
+ monitorp->model = conf_monitor->mon_modelname;
+ monitorp->Modes = NULL;
+ monitorp->Last = NULL;
+ monitorp->gamma = zeros;
+ monitorp->widthmm = conf_monitor->mon_width;
+ monitorp->heightmm = conf_monitor->mon_height;
+ monitorp->reducedblanking = FALSE;
+ monitorp->maxPixClock = 0;
+ monitorp->options = conf_monitor->mon_option_lst;
+
+ /*
+ * fill in the monitor structure
+ */
+ for( count = 0 ;
+ count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
+ count++) {
+ monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
+ monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
+ }
+ monitorp->nHsync = count;
+ for( count = 0 ;
+ count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
+ count++) {
+ monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
+ monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
+ }
+ monitorp->nVrefresh = count;
+
+ /*
+ * first we collect the mode lines from the UseModes directive
+ */
+ while(modeslnk)
+ {
+ modes = xf86findModes (modeslnk->ml_modes_str,
+ xf86configptr->conf_modes_lst);
+ modeslnk->ml_modes = modes;
+
+
+ /* now add the modes found in the modes
+ section to the list of modes for this
+ monitor unless it has been added before
+ because we are reusing the same section
+ for another screen */
+ if (xf86itemNotSublist(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst)) {
+ conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
+ xf86addListItem(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst);
+ }
+ modeslnk = modeslnk->list.next;
+ }
+
+ /*
+ * we need to hook in the mode lines now
+ * here both data structures use lists, only our internal one
+ * is double linked
+ */
+ cmodep = conf_monitor->mon_modeline_lst;
+ while( cmodep ) {
+ mode = xnfcalloc(1, sizeof(DisplayModeRec));
+ mode->type = 0;
+ mode->Clock = cmodep->ml_clock;
+ mode->HDisplay = cmodep->ml_hdisplay;
+ mode->HSyncStart = cmodep->ml_hsyncstart;
+ mode->HSyncEnd = cmodep->ml_hsyncend;
+ mode->HTotal = cmodep->ml_htotal;
+ mode->VDisplay = cmodep->ml_vdisplay;
+ mode->VSyncStart = cmodep->ml_vsyncstart;
+ mode->VSyncEnd = cmodep->ml_vsyncend;
+ mode->VTotal = cmodep->ml_vtotal;
+ mode->Flags = cmodep->ml_flags;
+ mode->HSkew = cmodep->ml_hskew;
+ mode->VScan = cmodep->ml_vscan;
+ mode->name = xnfstrdup(cmodep->ml_identifier);
+ if( last ) {
+ mode->prev = last;
+ last->next = mode;
+ }
+ else {
+ /*
+ * this is the first mode
+ */
+ monitorp->Modes = mode;
+ mode->prev = NULL;
+ }
+ last = mode;
+ cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
+ }
+ if(last){
+ last->next = NULL;
+ }
+ monitorp->Last = last;
+
+ /* add the (VESA) default modes */
+ if (! addDefaultModes(monitorp) )
+ return FALSE;
+
+ if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
+ monitorp->gamma.red = conf_monitor->mon_gamma_red;
+ if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
+ monitorp->gamma.green = conf_monitor->mon_gamma_green;
+ if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
+ monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
+
+ /* Check that the gamma values are within range */
+ if (monitorp->gamma.red > GAMMA_ZERO &&
+ (monitorp->gamma.red < GAMMA_MIN ||
+ monitorp->gamma.red > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.red;
+ } else if (monitorp->gamma.green > GAMMA_ZERO &&
+ (monitorp->gamma.green < GAMMA_MIN ||
+ monitorp->gamma.green > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.green;
+ } else if (monitorp->gamma.blue > GAMMA_ZERO &&
+ (monitorp->gamma.blue < GAMMA_MIN ||
+ monitorp->gamma.blue > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.blue;
+ }
+ if (badgamma > GAMMA_ZERO) {
+ xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
+ badgamma, GAMMA_MIN, GAMMA_MAX);
+ return FALSE;
+ }
+
+ xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
+ xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
+ &monitorp->reducedblanking);
+ if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
+ &maxPixClock) == TRUE) {
+ monitorp->maxPixClock = (int) maxPixClock;
+ }
+
+ return TRUE;
+}
+
+static int
+lookupVisual(const char *visname)
+{
+ int i;
+
+ if (!visname || !*visname)
+ return -1;
+
+ for (i = 0; i <= DirectColor; i++) {
+ if (!xf86nameCompare(visname, xf86VisualNames[i]))
+ break;
+ }
+
+ if (i <= DirectColor)
+ return i;
+
+ return -1;
+}
+
+
+static Bool
+configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
+{
+ int count = 0;
+ XF86ModePtr modep;
+
+ displayp->frameX0 = conf_display->disp_frameX0;
+ displayp->frameY0 = conf_display->disp_frameY0;
+ displayp->virtualX = conf_display->disp_virtualX;
+ displayp->virtualY = conf_display->disp_virtualY;
+ displayp->depth = conf_display->disp_depth;
+ displayp->fbbpp = conf_display->disp_bpp;
+ displayp->weight.red = conf_display->disp_weight.red;
+ displayp->weight.green = conf_display->disp_weight.green;
+ displayp->weight.blue = conf_display->disp_weight.blue;
+ displayp->blackColour.red = conf_display->disp_black.red;
+ displayp->blackColour.green = conf_display->disp_black.green;
+ displayp->blackColour.blue = conf_display->disp_black.blue;
+ displayp->whiteColour.red = conf_display->disp_white.red;
+ displayp->whiteColour.green = conf_display->disp_white.green;
+ displayp->whiteColour.blue = conf_display->disp_white.blue;
+ displayp->options = conf_display->disp_option_lst;
+ if (conf_display->disp_visual) {
+ displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
+ if (displayp->defaultVisual == -1) {
+ xf86ConfigError("Invalid visual name: \"%s\"",
+ conf_display->disp_visual);
+ return FALSE;
+ }
+ } else {
+ displayp->defaultVisual = -1;
+ }
+
+ /*
+ * now hook in the modes
+ */
+ modep = conf_display->disp_mode_lst;
+ while(modep) {
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes = xnfalloc((count+1) * sizeof(char*));
+ modep = conf_display->disp_mode_lst;
+ count = 0;
+ while(modep) {
+ displayp->modes[count] = modep->mode_name;
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes[count] = NULL;
+
+ return TRUE;
+}
+
+static Bool
+configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
+{
+ int i;
+
+ if (!conf_device) {
+ return FALSE;
+ }
+
+ if (active)
+ xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
+ conf_device->dev_identifier);
+ else
+ xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
+ conf_device->dev_identifier);
+
+ devicep->identifier = conf_device->dev_identifier;
+ devicep->vendor = conf_device->dev_vendor;
+ devicep->board = conf_device->dev_board;
+ devicep->chipset = conf_device->dev_chipset;
+ devicep->ramdac = conf_device->dev_ramdac;
+ devicep->driver = conf_device->dev_driver;
+ devicep->active = active;
+ devicep->videoRam = conf_device->dev_videoram;
+ devicep->BiosBase = conf_device->dev_bios_base;
+ devicep->MemBase = conf_device->dev_mem_base;
+ devicep->IOBase = conf_device->dev_io_base;
+ devicep->clockchip = conf_device->dev_clockchip;
+ devicep->busID = conf_device->dev_busid;
+ devicep->textClockFreq = conf_device->dev_textclockfreq;
+ devicep->chipID = conf_device->dev_chipid;
+ devicep->chipRev = conf_device->dev_chiprev;
+ devicep->options = conf_device->dev_option_lst;
+ devicep->irq = conf_device->dev_irq;
+ devicep->screen = conf_device->dev_screen;
+
+ for (i = 0; i < MAXDACSPEEDS; i++) {
+ if (i < CONF_MAXDACSPEEDS)
+ devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
+ else
+ devicep->dacSpeeds[i] = 0;
+ }
+ devicep->numclocks = conf_device->dev_clocks;
+ if (devicep->numclocks > MAXCLOCKS)
+ devicep->numclocks = MAXCLOCKS;
+ for (i = 0; i < devicep->numclocks; i++) {
+ devicep->clock[i] = conf_device->dev_clock[i];
+ }
+ devicep->claimed = FALSE;
+
+ return TRUE;
+}
+
+#ifdef XF86DRI
+static void
+configDRI(XF86ConfDRIPtr drip)
+{
+ int count = 0;
+ XF86ConfBuffersPtr bufs;
+ int i;
+ struct group *grp;
+
+ xf86ConfigDRI.group = -1;
+ xf86ConfigDRI.mode = 0;
+ xf86ConfigDRI.bufs_count = 0;
+ xf86ConfigDRI.bufs = NULL;
+
+ if (drip) {
+ if (drip->dri_group_name) {
+ if ((grp = getgrnam(drip->dri_group_name)))
+ xf86ConfigDRI.group = grp->gr_gid;
+ } else {
+ if (drip->dri_group >= 0)
+ xf86ConfigDRI.group = drip->dri_group;
+ }
+ xf86ConfigDRI.mode = drip->dri_mode;
+ for (bufs = drip->dri_buffers_lst; bufs; bufs = bufs->list.next)
+ ++count;
+
+ xf86ConfigDRI.bufs_count = count;
+ xf86ConfigDRI.bufs = xnfalloc(count * sizeof(*xf86ConfigDRI.bufs));
+
+ for (i = 0, bufs = drip->dri_buffers_lst;
+ i < count;
+ i++, bufs = bufs->list.next) {
+
+ xf86ConfigDRI.bufs[i].count = bufs->buf_count;
+ xf86ConfigDRI.bufs[i].size = bufs->buf_size;
+ /* FIXME: Flags not implemented. These
+ could be used, for example, to specify a
+ contiguous block and/or write-combining
+ cache policy. */
+ xf86ConfigDRI.bufs[i].flags = 0;
+ }
+ }
+}
+#endif
+
+static void
+configExtensions(XF86ConfExtensionsPtr conf_ext)
+{
+ XF86OptionPtr o;
+
+ if (conf_ext && conf_ext->ext_option_lst) {
+ for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
+ char *name = xf86OptionName(o);
+ char *val = xf86OptionValue(o);
+ char *n;
+ Bool enable = TRUE;
+
+ /* Handle "No<ExtensionName>" */
+ n = xf86NormalizeName(name);
+ if (strncmp(n, "no", 2) == 0) {
+ name += 2;
+ enable = FALSE;
+ }
+
+ if (!val ||
+ xf86NameCmp(val, "enable") == 0 ||
+ xf86NameCmp(val, "enabled") == 0 ||
+ xf86NameCmp(val, "on") == 0 ||
+ xf86NameCmp(val, "1") == 0 ||
+ xf86NameCmp(val, "yes") == 0 ||
+ xf86NameCmp(val, "true") == 0) {
+ /* NOTHING NEEDED -- enabling is handled below */
+ } else if (xf86NameCmp(val, "disable") == 0 ||
+ xf86NameCmp(val, "disabled") == 0 ||
+ xf86NameCmp(val, "off") == 0 ||
+ xf86NameCmp(val, "0") == 0 ||
+ xf86NameCmp(val, "no") == 0 ||
+ xf86NameCmp(val, "false") == 0) {
+ enable = !enable;
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
+ free(n);
+ continue;
+ }
+
+ if (EnableDisableExtension(name, enable)) {
+ xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
+ name, enable ? "enabled" : "disabled");
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
+ name);
+ }
+ free(n);
+ }
+ }
+}
+
+static Bool
+configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
+{
+ xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
+ inputp->identifier = conf_input->inp_identifier;
+ inputp->driver = conf_input->inp_driver;
+ inputp->commonOptions = conf_input->inp_option_lst;
+ inputp->extraOptions = NULL;
+
+ return TRUE;
+}
+
+static Bool
+modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
+{
+ DisplayModePtr knownmodes = monitorp->Modes;
+
+ /* all I can think of is a linear search... */
+ while(knownmodes != NULL)
+ {
+ if(!strcmp(mode->name, knownmodes->name) &&
+ !(knownmodes->type & M_T_DEFAULT))
+ return TRUE;
+ knownmodes = knownmodes->next;
+ }
+ return FALSE;
+}
+
+static Bool
+addDefaultModes(MonPtr monitorp)
+{
+ DisplayModePtr mode;
+ DisplayModePtr last = monitorp->Last;
+ int i = 0;
+
+ for (i = 0; i < xf86NumDefaultModes; i++)
+ {
+ mode = xf86DuplicateMode(&xf86DefaultModes[i]);
+ if (!modeIsPresent(mode, monitorp))
+ {
+ monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
+ last = mode;
+ } else {
+ free(mode);
+ }
+ }
+ monitorp->Last = last;
+
+ return TRUE;
+}
+
+static void
+checkInput(serverLayoutPtr layout, Bool implicit_layout) {
+ checkCoreInputDevices(layout, implicit_layout);
+
+ /* AllowEmptyInput and the "kbd" and "mouse" drivers are mutually
+ * exclusive. Trawl the list for mouse/kbd devices and disable them.
+ */
+ if (xf86Info.allowEmptyInput && layout->inputs)
+ {
+ IDevPtr *dev = layout->inputs;
+ BOOL warned = FALSE;
+
+ while(*dev)
+ {
+ if (strcmp((*dev)->driver, "kbd") == 0 ||
+ strcmp((*dev)->driver, "mouse") == 0 ||
+ strcmp((*dev)->driver, "vmmouse") == 0)
+ {
+ IDevPtr *current;
+ if (!warned)
+ {
+ xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
+ "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
+ warned = TRUE;
+ }
+
+ xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
+
+ current = dev;
+ free(*dev);
+
+ do {
+ *current = *(current + 1);
+ current++;
+ } while(*current);
+ } else
+ dev++;
+ }
+ }
+}
+
+/*
+ * load the config file and fill the global data structure
+ */
+ConfigStatus
+xf86HandleConfigFile(Bool autoconfig)
+{
+ const char *filename, *dirname, *sysdirname;
+ char *filesearch, *dirsearch;
+ MessageType filefrom = X_DEFAULT;
+ MessageType dirfrom = X_DEFAULT;
+ char *scanptr;
+ Bool singlecard = 0;
+ Bool implicit_layout = FALSE;
+
+ if (!autoconfig) {
+ if (getuid() == 0) {
+ filesearch = ROOT_CONFIGPATH;
+ dirsearch = ROOT_CONFIGDIRPATH;
+ } else {
+ filesearch = USER_CONFIGPATH;
+ dirsearch = USER_CONFIGDIRPATH;
+ }
+
+ if (xf86ConfigFile)
+ filefrom = X_CMDLINE;
+ if (xf86ConfigDir)
+ dirfrom = X_CMDLINE;
+
+ xf86initConfigFiles();
+ sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
+ PROJECTROOT);
+ dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
+ filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
+ if (filename) {
+ xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
+ xf86ConfigFile = xnfstrdup(filename);
+ } else {
+ if (xf86ConfigFile)
+ xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
+ xf86ConfigFile);
+ }
+ if (dirname) {
+ xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
+ dirname);
+ xf86ConfigDir = xnfstrdup(dirname);
+ } else {
+ if (xf86ConfigDir)
+ xf86Msg(X_ERROR,
+ "Unable to locate/open config directory: \"%s\"\n",
+ xf86ConfigDir);
+ }
+ if (sysdirname)
+ xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
+ sysdirname);
+ if (!filename && !dirname && !sysdirname)
+ return CONFIG_NOFILE;
+ }
+
+ if ((xf86configptr = xf86readConfigFile ()) == NULL) {
+ xf86Msg(X_ERROR, "Problem parsing the config file\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ xf86closeConfigFile ();
+
+ /* Initialise a few things. */
+
+ /*
+ * now we convert part of the information contained in the parser
+ * structures into our own structures.
+ * The important part here is to figure out which Screen Sections
+ * in the XF86Config file are active so that we can piece together
+ * the modes that we need later down the road.
+ * And while we are at it, we'll decode the rest of the stuff as well
+ */
+
+ /* First check if a layout section is present, and if it is valid. */
+
+ if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
+ if (xf86ScreenName == NULL) {
+ xf86Msg(X_DEFAULT,
+ "No Layout section. Using the first Screen section.\n");
+ }
+ if (!configImpliedLayout(&xf86ConfigLayout,
+ xf86configptr->conf_screen_lst,
+ xf86configptr)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ implicit_layout = TRUE;
+ } else {
+ if (xf86configptr->conf_flags != NULL) {
+ char *dfltlayout = NULL;
+ pointer optlist = xf86configptr->conf_flags->flg_option_lst;
+
+ if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
+ dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ dfltlayout)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ } else {
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ NULL)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ }
+ }
+
+ xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
+
+ if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
+ ; /* IsolateDevice specified; overrides SingleCard */
+ } else {
+ xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
+ if (singlecard)
+ scanptr = xf86ConfigLayout.screens->screen->device->busID;
+ }
+ if (scanptr) {
+ int bus, device, func;
+ if (strncmp(scanptr, "PCI:", 4) != 0) {
+ xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
+ "\tIgnoring IsolateDevice option.\n");
+ } else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
+ xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
+ xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
+ xf86IsolateDevice.dev = device;
+ xf86IsolateDevice.func = func;
+ xf86Msg(X_INFO,
+ "Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
+ }
+ }
+
+ /* Now process everything else */
+ if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
+ ErrorF ("Problem when converting the config data structures\n");
+ return CONFIG_PARSE_ERROR;
+ }
+
+ configFiles(xf86configptr->conf_files);
+ configExtensions(xf86configptr->conf_extensions);
+#ifdef XF86DRI
+ configDRI(xf86configptr->conf_dri);
+#endif
+
+ checkInput(&xf86ConfigLayout, implicit_layout);
+
+ /*
+ * Handle some command line options that can override some of the
+ * ServerFlags settings.
+ */
+#ifdef XF86VIDMODE
+ if (xf86VidModeDisabled)
+ xf86Info.vidModeEnabled = FALSE;
+ if (xf86VidModeAllowNonLocal)
+ xf86Info.vidModeAllowNonLocal = TRUE;
+#endif
+
+ if (xf86AllowMouseOpenFail)
+ xf86Info.allowMouseOpenFail = TRUE;
+
+ return CONFIG_OK;
+}
+
+Bool
+xf86PathIsSafe(const char *path)
+{
+ return (xf86pathIsSafe(path) != 0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c
index 67bf08bbf..883c666a6 100644
--- a/xorg-server/hw/xfree86/common/xf86Configure.c
+++ b/xorg-server/hw/xfree86/common/xf86Configure.c
@@ -1,892 +1,892 @@
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * 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 Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE 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.
- *
- * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-#define IN_XSERVER
-#include "Configint.h"
-#include "xf86DDC.h"
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-
-typedef struct _DevToConfig {
- GDevRec GDev;
- struct pci_device * pVideo;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- sbusDevicePtr sVideo;
-#endif
- int iDriver;
-} DevToConfigRec, *DevToConfigPtr;
-
-static DevToConfigPtr DevToConfig = NULL;
-static int nDevToConfig = 0, CurrentDriver;
-
-xf86MonPtr ConfiguredMonitor;
-Bool xf86DoConfigurePass1 = TRUE;
-static Bool foundMouse = FALSE;
-
-#if defined(__SCO__)
-static char *DFLT_MOUSE_PROTO = "OSMouse";
-#elif defined(__UNIXWARE__)
-static char *DFLT_MOUSE_PROTO = "OSMouse";
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#elif defined(linux)
-static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
-static char DFLT_MOUSE_PROTO[] = "auto";
-#else
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#endif
-
-static Bool
-bus_pci_configure(void *busData)
-{
- int i;
- struct pci_device * pVideo = NULL;
-
- pVideo = (struct pci_device *) busData;
- for (i = 0; i < nDevToConfig; i++)
- if (DevToConfig[i].pVideo &&
- (DevToConfig[i].pVideo->domain == pVideo->domain) &&
- (DevToConfig[i].pVideo->bus == pVideo->bus) &&
- (DevToConfig[i].pVideo->dev == pVideo->dev) &&
- (DevToConfig[i].pVideo->func == pVideo->func))
- return 0;
-
- return 1;
-}
-
-static Bool
-bus_sbus_configure(void *busData)
-{
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- int i;
-
- for (i = 0; i < nDevToConfig; i++)
- if (DevToConfig[i].sVideo &&
- DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
- return 0;
-
-#endif
- return 1;
-}
-
-static void
-bus_pci_newdev_configure(void *busData, int i, int *chipset)
-{
- const char *VendorName;
- const char *CardName;
- char busnum[8];
- struct pci_device * pVideo = NULL;
-
- pVideo = (struct pci_device *) busData;
-
- DevToConfig[i].pVideo = pVideo;
-
- VendorName = pci_device_get_vendor_name( pVideo );
- CardName = pci_device_get_device_name( pVideo );
-
- if (!VendorName) {
- VendorName = xnfalloc(15);
- sprintf((char*)VendorName, "Unknown Vendor");
- }
-
- if (!CardName) {
- CardName = xnfalloc(14);
- sprintf((char*)CardName, "Unknown Board");
- }
-
- DevToConfig[i].GDev.identifier =
- xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
- sprintf(DevToConfig[i].GDev.identifier, "%s %s", VendorName, CardName);
-
- DevToConfig[i].GDev.vendor = (char *)VendorName;
- DevToConfig[i].GDev.board = (char *)CardName;
-
- DevToConfig[i].GDev.busID = xnfalloc(16);
- xf86FormatPciBusNumber(pVideo->bus, busnum);
- sprintf(DevToConfig[i].GDev.busID, "PCI:%s:%d:%d",
- busnum, pVideo->dev, pVideo->func);
-
- DevToConfig[i].GDev.chipID = pVideo->device_id;
- DevToConfig[i].GDev.chipRev = pVideo->revision;
-
- if (*chipset < 0) {
- *chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
- }
-}
-
-static void
-bus_sbus_newdev_configure(void *busData, int i)
-{
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- char *promPath = NULL;
- DevToConfig[i].sVideo = (sbusDevicePtr) busData;
- DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr;
- if (sparcPromInit() >= 0) {
- promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node);
- sparcPromClose();
- }
- if (promPath) {
- DevToConfig[i].GDev.busID = xnfalloc(strlen(promPath) + 6);
- sprintf(DevToConfig[i].GDev.busID, "SBUS:%s", promPath);
- xfree(promPath);
- } else {
- DevToConfig[i].GDev.busID = xnfalloc(12);
- sprintf(DevToConfig[i].GDev.busID, "SBUS:fb%d",
- DevToConfig[i].sVideo->fbNum);
- }
-#endif
-}
-
-/*
- * This is called by the driver, either through xf86Match???Instances() or
- * directly. We allocate a GDevRec and fill it in as much as we can, letting
- * the caller fill in the rest and/or change it as it sees fit.
- */
-GDevPtr
-xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
-{
- int ret, i, j;
-
- if (!xf86DoConfigure || !xf86DoConfigurePass1)
- return NULL;
-
- /* Check for duplicates */
- switch (bus) {
- case BUS_PCI:
- ret = bus_pci_configure(busData);
- break;
- case BUS_SBUS:
- ret = bus_sbus_configure(busData);
- break;
- default:
- return NULL;
- }
-
- if (ret == 0)
- goto out;
-
- /* Allocate new structure occurrence */
- i = nDevToConfig++;
- DevToConfig =
- xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
- memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
-
- DevToConfig[i].GDev.chipID =
- DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
-
- DevToConfig[i].iDriver = CurrentDriver;
-
- /* Fill in what we know, converting the driver name to lower case */
- DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
- for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
-
- switch (bus) {
- case BUS_PCI:
- bus_pci_newdev_configure(busData, i, &chipset);
- break;
- case BUS_SBUS:
- bus_sbus_newdev_configure(busData, i);
- break;
- default:
- break;
- }
-
- /* Get driver's available options */
- if (xf86DriverList[CurrentDriver]->AvailableOptions)
- DevToConfig[i].GDev.options = (OptionInfoPtr)
- (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
- bus);
-
- return &DevToConfig[i].GDev;
-
-out:
- return NULL;
-}
-
-static XF86ConfInputPtr
-configureInputSection (void)
-{
- XF86ConfInputPtr mouse = NULL;
- parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
-
- ptr->inp_identifier = "Keyboard0";
- ptr->inp_driver = "kbd";
- ptr->list.next = NULL;
-
- /* Crude mechanism to auto-detect mouse (os dependent) */
- {
- int fd;
-#ifdef WSCONS_SUPPORT
- fd = open("/dev/wsmouse", 0);
- if (fd >= 0) {
- DFLT_MOUSE_DEV = "/dev/wsmouse";
- DFLT_MOUSE_PROTO = "wsmouse";
- close(fd);
- } else {
- ErrorF("cannot open /dev/wsmouse\n");
- }
-#endif
-
-#ifndef __SCO__
- fd = open(DFLT_MOUSE_DEV, 0);
- if (fd != -1) {
- foundMouse = TRUE;
- close(fd);
- }
-#else
- foundMouse = TRUE;
-#endif
- }
-
- mouse = calloc(1, sizeof(XF86ConfInputRec));
- mouse->inp_identifier = "Mouse0";
- mouse->inp_driver = "mouse";
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("Protocol"),
- xstrdup(DFLT_MOUSE_PROTO));
-#ifndef __SCO__
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("Device"),
- xstrdup(DFLT_MOUSE_DEV));
-#endif
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("ZAxisMapping"),
- xstrdup("4 5 6 7"));
- ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
- return ptr;
-}
-
-static XF86ConfScreenPtr
-configureScreenSection (int screennum)
-{
- int i;
- int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
- parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
-
- ptr->scrn_identifier = malloc(18);
- sprintf(ptr->scrn_identifier, "Screen%d", screennum);
- ptr->scrn_monitor_str = malloc(19);
- sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
- ptr->scrn_device_str = malloc(16);
- sprintf(ptr->scrn_device_str, "Card%d", screennum);
-
- for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
- {
- XF86ConfDisplayPtr display;
-
- display = calloc(1, sizeof(XF86ConfDisplayRec));
- display->disp_depth = depths[i];
- display->disp_black.red = display->disp_white.red = -1;
- display->disp_black.green = display->disp_white.green = -1;
- display->disp_black.blue = display->disp_white.blue = -1;
- ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
- (glp)ptr->scrn_display_lst, (glp)display);
- }
-
- return ptr;
-}
-
-static const char*
-optionTypeToSting(OptionValueType type)
-{
- switch (type) {
- case OPTV_NONE:
- return "";
- case OPTV_INTEGER:
- return "<i>";
- case OPTV_STRING:
- return "<str>";
- case OPTV_ANYSTR:
- return "[<str>]";
- case OPTV_REAL:
- return "<f>";
- case OPTV_BOOLEAN:
- return "[<bool>]";
- case OPTV_FREQ:
- return "<freq>";
- default:
- return "";
- }
-}
-
-static XF86ConfDevicePtr
-configureDeviceSection (int screennum)
-{
- char identifier[16];
- OptionInfoPtr p;
- int i = 0;
- parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
-
- /* Move device info to parser structure */
- sprintf(identifier, "Card%d", screennum);
- ptr->dev_identifier = strdup(identifier);
-/* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
- ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
- ptr->dev_board = DevToConfig[screennum].GDev.board;
- ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
- ptr->dev_busid = DevToConfig[screennum].GDev.busID;
- ptr->dev_driver = DevToConfig[screennum].GDev.driver;
- ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
- for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
- ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
- ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
- ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
- ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
- ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
- ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
- ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
- for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
- ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
- ptr->dev_clocks = i;
- ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
- ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
- ptr->dev_irq = DevToConfig[screennum].GDev.irq;
-
- /* Make sure older drivers don't segv */
- if (DevToConfig[screennum].GDev.options) {
- /* Fill in the available driver options for people to use */
- const char *descrip =
- " ### Available Driver options are:-\n"
- " ### Values: <i>: integer, <f>: float, "
- "<bool>: \"True\"/\"False\",\n"
- " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n"
- " ### [arg]: arg optional\n";
- ptr->dev_comment = xstrdup(descrip);
- if (ptr->dev_comment) {
- for (p = DevToConfig[screennum].GDev.options;
- p->name != NULL; p++) {
- char *p_e;
- const char *prefix = " #Option ";
- const char *middle = " \t# ";
- const char *suffix = "\n";
- const char *opttype = optionTypeToSting(p->type);
- char *optname;
- int len = strlen(ptr->dev_comment) + strlen(prefix) +
- strlen(middle) + strlen(suffix) + 1;
-
- optname = xalloc(strlen(p->name) + 2 + 1);
- if (!optname)
- break;
- sprintf(optname, "\"%s\"", p->name);
-
- len += max(20, strlen(optname));
- len += strlen(opttype);
-
- ptr->dev_comment = xrealloc(ptr->dev_comment, len);
- if (!ptr->dev_comment)
- break;
- p_e = ptr->dev_comment + strlen(ptr->dev_comment);
- sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
- opttype, suffix);
- xfree(optname);
- }
- }
- }
-
- return ptr;
-}
-
-static XF86ConfLayoutPtr
-configureLayoutSection (void)
-{
- int scrnum = 0;
- parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
-
- ptr->lay_identifier = "X.org Configured";
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Mouse0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, xstrdup("CorePointer"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Keyboard0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, xstrdup("CoreKeyboard"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
- XF86ConfAdjacencyPtr aptr;
-
- aptr = malloc (sizeof (XF86ConfAdjacencyRec));
- aptr->list.next = NULL;
- aptr->adj_x = 0;
- aptr->adj_y = 0;
- aptr->adj_scrnum = scrnum;
- aptr->adj_screen_str = xnfalloc(18);
- sprintf(aptr->adj_screen_str, "Screen%d", scrnum);
- if (scrnum == 0) {
- aptr->adj_where = CONF_ADJ_ABSOLUTE;
- aptr->adj_refscreen = NULL;
- }
- else {
- aptr->adj_where = CONF_ADJ_RIGHTOF;
- aptr->adj_refscreen = xnfalloc(18);
- sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
- }
- ptr->lay_adjacency_lst =
- (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
- (glp)aptr);
- }
-
- return ptr;
-}
-
-static XF86ConfFlagsPtr
-configureFlagsSection (void)
-{
- parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
-
- return ptr;
-}
-
-static XF86ConfModulePtr
-configureModuleSection (void)
-{
- char **elist, **el;
- /* Find the list of extension & font modules. */
- const char *esubdirs[] = {
- "extensions",
- "fonts",
- NULL
- };
- parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
-
- elist = LoaderListDirs(esubdirs, NULL);
- if (elist) {
- for (el = elist; *el; el++) {
- XF86LoadPtr module;
-
- module = calloc(1, sizeof(XF86LoadRec));
- module->load_name = *el;
- ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
- (glp)ptr->mod_load_lst, (glp)module);
- }
- xfree(elist);
- }
-
- return ptr;
-}
-
-static XF86ConfFilesPtr
-configureFilesSection (void)
-{
- parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
-
- if (xf86ModulePath)
- ptr->file_modulepath = strdup(xf86ModulePath);
- if (defaultFontPath)
- ptr->file_fontpath = strdup(defaultFontPath);
-
- return ptr;
-}
-
-static XF86ConfMonitorPtr
-configureMonitorSection (int screennum)
-{
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- ptr->mon_identifier = malloc(19);
- sprintf(ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup("Monitor Vendor");
- ptr->mon_modelname = strdup("Monitor Model");
-
- return ptr;
-}
-
-/* Initialize Configure Monitor from Detailed Timing Block */
-static void handle_detailed_input(struct detailed_monitor_section *det_mon,
- void *data)
-{
- XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
-
- switch (det_mon->type) {
- case DS_NAME:
- ptr->mon_modelname = realloc(ptr->mon_modelname,
- strlen((char*)(det_mon->section.name)) +
- 1);
- strcpy(ptr->mon_modelname,
- (char*)(det_mon->section.name));
- break;
- case DS_RANGES:
- ptr->mon_hsync[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_h;
- ptr->mon_hsync[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_h;
- ptr->mon_n_vrefresh = 1;
- ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_v;
- ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_v;
- ptr->mon_n_hsync++;
- default:
- break;
- }
-}
-
-static XF86ConfMonitorPtr
-configureDDCMonitorSection (int screennum)
-{
- int len, mon_width, mon_height;
-#define displaySizeMaxLen 80
- char displaySize_string[displaySizeMaxLen];
- int displaySizeLen;
-
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- ptr->mon_identifier = malloc(19);
- sprintf(ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
- ptr->mon_modelname = malloc(12);
- sprintf(ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
-
- /* features in centimetres, we want millimetres */
- mon_width = 10 * ConfiguredMonitor->features.hsize ;
- mon_height = 10 * ConfiguredMonitor->features.vsize ;
-
-#ifdef CONFIGURE_DISPLAYSIZE
- ptr->mon_width = mon_width;
- ptr->mon_height = mon_height;
-#else
- if (mon_width && mon_height) {
- /* when values available add DisplaySize option AS A COMMENT */
-
- displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
- "\t#DisplaySize\t%5d %5d\t# mm\n",
- mon_width, mon_height);
-
- if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
- if (ptr->mon_comment) {
- len = strlen(ptr->mon_comment);
- } else {
- len = 0;
- }
- if ((ptr->mon_comment =
- realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
- strcpy(ptr->mon_comment + len, displaySize_string);
- }
- }
- }
-#endif /* def CONFIGURE_DISPLAYSIZE */
-
- xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
- ptr);
-
- if (ConfiguredMonitor->features.dpms) {
- ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, xstrdup("DPMS"), NULL);
- }
-
- return ptr;
-}
-
-#if !defined(PATH_MAX)
-# define PATH_MAX 1024
-#endif
-
-void
-DoConfigure(void)
-{
- int i,j, screennum = -1;
- char *home = NULL;
- char filename[PATH_MAX];
- char *addslash = "";
- XF86ConfigPtr xf86config = NULL;
- char **vlist, **vl;
- int *dev2screen;
-
- vlist = xf86DriverlistFromCompile();
-
- if (!vlist) {
- ErrorF("Missing output drivers. Configuration failed.\n");
- goto bail;
- }
-
- ErrorF("List of video drivers:\n");
- for (vl = vlist; *vl; vl++)
- ErrorF("\t%s\n", *vl);
-
- /* Load all the drivers that were found. */
- xf86LoadModules(vlist, NULL);
-
- xfree(vlist);
-
- for (i = 0; i < xf86NumDrivers; i++) {
- xorgHWFlags flags;
- if (!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags)
- || NEED_IO_ENABLED(flags)) {
- xorgHWAccess = TRUE;
- break;
- }
- }
- /* Enable full I/O access */
- if (xorgHWAccess) {
- if(!xf86EnableIO())
- /* oops, we have failed */
- xorgHWAccess = FALSE;
- }
-
- xf86FindPrimaryDevice();
-
- /* Create XF86Config file structure */
- xf86config = calloc(1, sizeof(XF86ConfigRec));
-
- /* Call all of the probe functions, reporting the results. */
- for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
- xorgHWFlags flags;
- Bool found_screen;
- DriverRec * const drv = xf86DriverList[CurrentDriver];
-
- if (!xorgHWAccess) {
- if (!drv->driverFunc
- || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
- || NEED_IO_ENABLED(flags))
- continue;
- }
-
- found_screen = xf86CallDriverProbe( drv, TRUE );
- if ( found_screen && drv->Identify ) {
- (*drv->Identify)(0);
- }
- }
-
- if (nDevToConfig <= 0) {
- ErrorF("No devices to configure. Configuration failed.\n");
- goto bail;
- }
-
- /* Add device, monitor and screen sections for detected devices */
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- XF86ConfDevicePtr DevicePtr;
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- DevicePtr = configureDeviceSection(screennum);
- xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
- (glp)xf86config->conf_device_lst, (glp)DevicePtr);
- MonitorPtr = configureMonitorSection(screennum);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- ScreenPtr = configureScreenSection(screennum);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- xf86config->conf_files = configureFilesSection();
- xf86config->conf_modules = configureModuleSection();
- xf86config->conf_flags = configureFlagsSection();
- xf86config->conf_videoadaptor_lst = NULL;
- xf86config->conf_modes_lst = NULL;
- xf86config->conf_vendor_lst = NULL;
- xf86config->conf_dri = NULL;
- xf86config->conf_input_lst = configureInputSection();
- xf86config->conf_layout_lst = configureLayoutSection();
-
- home = getenv("HOME");
- if ((home == NULL) || (home[0] == '\0')) {
- home = "/";
- } else {
- /* Determine if trailing slash is present or needed */
- int l = strlen(home);
-
- if (home[l-1] != '/') {
- addslash = "/";
- }
- }
-
- snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
- home, addslash);
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
- /* Try to get DDC information filled in */
- xf86ConfigFile = filename;
- if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
-
- dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
-
- {
- Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- int k,l,n,oldNumScreens;
-
- i = DevToConfig[screennum].iDriver;
-
- if (driverProbed[i]) continue;
- driverProbed[i] = TRUE;
-
- oldNumScreens = xf86NumScreens;
-
- xf86CallDriverProbe( xf86DriverList[i], FALSE );
-
- /* reorder */
- k = screennum > 0 ? screennum : 1;
- for (l = oldNumScreens; l < xf86NumScreens; l++) {
- /* is screen primary? */
- Bool primary = FALSE;
- for (n = 0; n<xf86Screens[l]->numEntities; n++) {
- if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
- dev2screen[0] = l;
- primary = TRUE;
- break;
- }
- }
- if (primary) continue;
- /* not primary: assign it to next device of same driver */
- /*
- * NOTE: we assume that devices in DevToConfig
- * and xf86Screens[] have the same order except
- * for the primary device which always comes first.
- */
- for (; k < nDevToConfig; k++) {
- if (DevToConfig[k].iDriver == i) {
- dev2screen[k++] = l;
- break;
- }
- }
- }
- }
- xfree(driverProbed);
- }
-
-
- if (nDevToConfig != xf86NumScreens) {
- ErrorF("Number of created screens does not match number of detected"
- " devices.\n Configuration failed.\n");
- goto bail;
- }
-
- xf86PostProbe();
- xf86EntityInit();
-
- for (j = 0; j < xf86NumScreens; j++) {
- xf86Screens[j]->scrnIndex = j;
- }
-
- xf86freeMonitorList(xf86config->conf_monitor_lst);
- xf86config->conf_monitor_lst = NULL;
- xf86freeScreenList(xf86config->conf_screen_lst);
- xf86config->conf_screen_lst = NULL;
- for (j = 0; j < xf86NumScreens; j++) {
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- ConfiguredMonitor = NULL;
-
- xf86EnableAccess(xf86Screens[dev2screen[j]]);
- if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
- PROBE_DETECT) &&
- ConfiguredMonitor) {
- MonitorPtr = configureDDCMonitorSection(j);
- } else {
- MonitorPtr = configureMonitorSection(j);
- }
- ScreenPtr = configureScreenSection(j);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- ErrorF("\n");
-
-#ifdef __SCO__
- ErrorF("\n"__XSERVERNAME__
- " is using the kernel event driver to access the mouse.\n"
- "If you wish to use the internal "__XSERVERNAME__
- " mouse drivers, please\n"
- "edit the file and correct the Device.\n");
-#else /* !__SCO__ */
- if (!foundMouse) {
- ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
- "Edit the file and correct the Device.\n");
- } else {
- ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
- "Please check your config if the mouse is still not\n"
- "operational, as by default "__XSERVERNAME__
- " tries to autodetect\n"
- "the protocol.\n",DFLT_MOUSE_DEV);
- }
-#endif /* !__SCO__ */
-
- if (xf86NumScreens > 1) {
- ErrorF("\n"__XSERVERNAME__
- " has configured a multihead system, please check your config.\n");
- }
-
- ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
- ErrorF("To test the server, run 'X -config %s'\n\n", filename);
-
-bail:
- OsCleanup(TRUE);
- AbortDDX();
- fflush(stderr);
- exit(0);
-}
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+#define IN_XSERVER
+#include "Configint.h"
+#include "xf86DDC.h"
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+
+typedef struct _DevToConfig {
+ GDevRec GDev;
+ struct pci_device * pVideo;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ sbusDevicePtr sVideo;
+#endif
+ int iDriver;
+} DevToConfigRec, *DevToConfigPtr;
+
+static DevToConfigPtr DevToConfig = NULL;
+static int nDevToConfig = 0, CurrentDriver;
+
+xf86MonPtr ConfiguredMonitor;
+Bool xf86DoConfigurePass1 = TRUE;
+static Bool foundMouse = FALSE;
+
+#if defined(__SCO__)
+static char *DFLT_MOUSE_PROTO = "OSMouse";
+#elif defined(__UNIXWARE__)
+static char *DFLT_MOUSE_PROTO = "OSMouse";
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#elif defined(linux)
+static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
+static char DFLT_MOUSE_PROTO[] = "auto";
+#else
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#endif
+
+static Bool
+bus_pci_configure(void *busData)
+{
+ int i;
+ struct pci_device * pVideo = NULL;
+
+ pVideo = (struct pci_device *) busData;
+ for (i = 0; i < nDevToConfig; i++)
+ if (DevToConfig[i].pVideo &&
+ (DevToConfig[i].pVideo->domain == pVideo->domain) &&
+ (DevToConfig[i].pVideo->bus == pVideo->bus) &&
+ (DevToConfig[i].pVideo->dev == pVideo->dev) &&
+ (DevToConfig[i].pVideo->func == pVideo->func))
+ return 0;
+
+ return 1;
+}
+
+static Bool
+bus_sbus_configure(void *busData)
+{
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ int i;
+
+ for (i = 0; i < nDevToConfig; i++)
+ if (DevToConfig[i].sVideo &&
+ DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
+ return 0;
+
+#endif
+ return 1;
+}
+
+static void
+bus_pci_newdev_configure(void *busData, int i, int *chipset)
+{
+ const char *VendorName;
+ const char *CardName;
+ char busnum[8];
+ struct pci_device * pVideo = NULL;
+
+ pVideo = (struct pci_device *) busData;
+
+ DevToConfig[i].pVideo = pVideo;
+
+ VendorName = pci_device_get_vendor_name( pVideo );
+ CardName = pci_device_get_device_name( pVideo );
+
+ if (!VendorName) {
+ VendorName = xnfalloc(15);
+ sprintf((char*)VendorName, "Unknown Vendor");
+ }
+
+ if (!CardName) {
+ CardName = xnfalloc(14);
+ sprintf((char*)CardName, "Unknown Board");
+ }
+
+ DevToConfig[i].GDev.identifier =
+ xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
+ sprintf(DevToConfig[i].GDev.identifier, "%s %s", VendorName, CardName);
+
+ DevToConfig[i].GDev.vendor = (char *)VendorName;
+ DevToConfig[i].GDev.board = (char *)CardName;
+
+ DevToConfig[i].GDev.busID = xnfalloc(16);
+ xf86FormatPciBusNumber(pVideo->bus, busnum);
+ sprintf(DevToConfig[i].GDev.busID, "PCI:%s:%d:%d",
+ busnum, pVideo->dev, pVideo->func);
+
+ DevToConfig[i].GDev.chipID = pVideo->device_id;
+ DevToConfig[i].GDev.chipRev = pVideo->revision;
+
+ if (*chipset < 0) {
+ *chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
+ }
+}
+
+static void
+bus_sbus_newdev_configure(void *busData, int i)
+{
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ char *promPath = NULL;
+ DevToConfig[i].sVideo = (sbusDevicePtr) busData;
+ DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr;
+ if (sparcPromInit() >= 0) {
+ promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node);
+ sparcPromClose();
+ }
+ if (promPath) {
+ DevToConfig[i].GDev.busID = xnfalloc(strlen(promPath) + 6);
+ sprintf(DevToConfig[i].GDev.busID, "SBUS:%s", promPath);
+ free(promPath);
+ } else {
+ DevToConfig[i].GDev.busID = xnfalloc(12);
+ sprintf(DevToConfig[i].GDev.busID, "SBUS:fb%d",
+ DevToConfig[i].sVideo->fbNum);
+ }
+#endif
+}
+
+/*
+ * This is called by the driver, either through xf86Match???Instances() or
+ * directly. We allocate a GDevRec and fill it in as much as we can, letting
+ * the caller fill in the rest and/or change it as it sees fit.
+ */
+GDevPtr
+xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
+{
+ int ret, i, j;
+
+ if (!xf86DoConfigure || !xf86DoConfigurePass1)
+ return NULL;
+
+ /* Check for duplicates */
+ switch (bus) {
+ case BUS_PCI:
+ ret = bus_pci_configure(busData);
+ break;
+ case BUS_SBUS:
+ ret = bus_sbus_configure(busData);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (ret == 0)
+ goto out;
+
+ /* Allocate new structure occurrence */
+ i = nDevToConfig++;
+ DevToConfig =
+ xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
+ memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
+
+ DevToConfig[i].GDev.chipID =
+ DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
+
+ DevToConfig[i].iDriver = CurrentDriver;
+
+ /* Fill in what we know, converting the driver name to lower case */
+ DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
+ for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
+
+ switch (bus) {
+ case BUS_PCI:
+ bus_pci_newdev_configure(busData, i, &chipset);
+ break;
+ case BUS_SBUS:
+ bus_sbus_newdev_configure(busData, i);
+ break;
+ default:
+ break;
+ }
+
+ /* Get driver's available options */
+ if (xf86DriverList[CurrentDriver]->AvailableOptions)
+ DevToConfig[i].GDev.options = (OptionInfoPtr)
+ (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
+ bus);
+
+ return &DevToConfig[i].GDev;
+
+out:
+ return NULL;
+}
+
+static XF86ConfInputPtr
+configureInputSection (void)
+{
+ XF86ConfInputPtr mouse = NULL;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ ptr->inp_identifier = "Keyboard0";
+ ptr->inp_driver = "kbd";
+ ptr->list.next = NULL;
+
+ /* Crude mechanism to auto-detect mouse (os dependent) */
+ {
+ int fd;
+#ifdef WSCONS_SUPPORT
+ fd = open("/dev/wsmouse", 0);
+ if (fd >= 0) {
+ DFLT_MOUSE_DEV = "/dev/wsmouse";
+ DFLT_MOUSE_PROTO = "wsmouse";
+ close(fd);
+ } else {
+ ErrorF("cannot open /dev/wsmouse\n");
+ }
+#endif
+
+#ifndef __SCO__
+ fd = open(DFLT_MOUSE_DEV, 0);
+ if (fd != -1) {
+ foundMouse = TRUE;
+ close(fd);
+ }
+#else
+ foundMouse = TRUE;
+#endif
+ }
+
+ mouse = calloc(1, sizeof(XF86ConfInputRec));
+ mouse->inp_identifier = "Mouse0";
+ mouse->inp_driver = "mouse";
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("Protocol"),
+ xstrdup(DFLT_MOUSE_PROTO));
+#ifndef __SCO__
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("Device"),
+ xstrdup(DFLT_MOUSE_DEV));
+#endif
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("ZAxisMapping"),
+ xstrdup("4 5 6 7"));
+ ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
+ return ptr;
+}
+
+static XF86ConfScreenPtr
+configureScreenSection (int screennum)
+{
+ int i;
+ int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
+ parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
+
+ ptr->scrn_identifier = malloc(18);
+ sprintf(ptr->scrn_identifier, "Screen%d", screennum);
+ ptr->scrn_monitor_str = malloc(19);
+ sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
+ ptr->scrn_device_str = malloc(16);
+ sprintf(ptr->scrn_device_str, "Card%d", screennum);
+
+ for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
+ {
+ XF86ConfDisplayPtr display;
+
+ display = calloc(1, sizeof(XF86ConfDisplayRec));
+ display->disp_depth = depths[i];
+ display->disp_black.red = display->disp_white.red = -1;
+ display->disp_black.green = display->disp_white.green = -1;
+ display->disp_black.blue = display->disp_white.blue = -1;
+ ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
+ (glp)ptr->scrn_display_lst, (glp)display);
+ }
+
+ return ptr;
+}
+
+static const char*
+optionTypeToSting(OptionValueType type)
+{
+ switch (type) {
+ case OPTV_NONE:
+ return "";
+ case OPTV_INTEGER:
+ return "<i>";
+ case OPTV_STRING:
+ return "<str>";
+ case OPTV_ANYSTR:
+ return "[<str>]";
+ case OPTV_REAL:
+ return "<f>";
+ case OPTV_BOOLEAN:
+ return "[<bool>]";
+ case OPTV_FREQ:
+ return "<freq>";
+ default:
+ return "";
+ }
+}
+
+static XF86ConfDevicePtr
+configureDeviceSection (int screennum)
+{
+ char identifier[16];
+ OptionInfoPtr p;
+ int i = 0;
+ parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
+
+ /* Move device info to parser structure */
+ sprintf(identifier, "Card%d", screennum);
+ ptr->dev_identifier = strdup(identifier);
+/* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
+ ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
+ ptr->dev_board = DevToConfig[screennum].GDev.board;
+ ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
+ ptr->dev_busid = DevToConfig[screennum].GDev.busID;
+ ptr->dev_driver = DevToConfig[screennum].GDev.driver;
+ ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
+ for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
+ ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
+ ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
+ ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
+ ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
+ ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
+ ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
+ ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
+ for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
+ ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
+ ptr->dev_clocks = i;
+ ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
+ ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
+ ptr->dev_irq = DevToConfig[screennum].GDev.irq;
+
+ /* Make sure older drivers don't segv */
+ if (DevToConfig[screennum].GDev.options) {
+ /* Fill in the available driver options for people to use */
+ const char *descrip =
+ " ### Available Driver options are:-\n"
+ " ### Values: <i>: integer, <f>: float, "
+ "<bool>: \"True\"/\"False\",\n"
+ " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n"
+ " ### [arg]: arg optional\n";
+ ptr->dev_comment = xstrdup(descrip);
+ if (ptr->dev_comment) {
+ for (p = DevToConfig[screennum].GDev.options;
+ p->name != NULL; p++) {
+ char *p_e;
+ const char *prefix = " #Option ";
+ const char *middle = " \t# ";
+ const char *suffix = "\n";
+ const char *opttype = optionTypeToSting(p->type);
+ char *optname;
+ int len = strlen(ptr->dev_comment) + strlen(prefix) +
+ strlen(middle) + strlen(suffix) + 1;
+
+ optname = malloc(strlen(p->name) + 2 + 1);
+ if (!optname)
+ break;
+ sprintf(optname, "\"%s\"", p->name);
+
+ len += max(20, strlen(optname));
+ len += strlen(opttype);
+
+ ptr->dev_comment = realloc(ptr->dev_comment, len);
+ if (!ptr->dev_comment)
+ break;
+ p_e = ptr->dev_comment + strlen(ptr->dev_comment);
+ sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
+ opttype, suffix);
+ free(optname);
+ }
+ }
+ }
+
+ return ptr;
+}
+
+static XF86ConfLayoutPtr
+configureLayoutSection (void)
+{
+ int scrnum = 0;
+ parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+ ptr->lay_identifier = "X.org Configured";
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Mouse0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, xstrdup("CorePointer"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Keyboard0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, xstrdup("CoreKeyboard"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
+ XF86ConfAdjacencyPtr aptr;
+
+ aptr = malloc (sizeof (XF86ConfAdjacencyRec));
+ aptr->list.next = NULL;
+ aptr->adj_x = 0;
+ aptr->adj_y = 0;
+ aptr->adj_scrnum = scrnum;
+ aptr->adj_screen_str = xnfalloc(18);
+ sprintf(aptr->adj_screen_str, "Screen%d", scrnum);
+ if (scrnum == 0) {
+ aptr->adj_where = CONF_ADJ_ABSOLUTE;
+ aptr->adj_refscreen = NULL;
+ }
+ else {
+ aptr->adj_where = CONF_ADJ_RIGHTOF;
+ aptr->adj_refscreen = xnfalloc(18);
+ sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
+ }
+ ptr->lay_adjacency_lst =
+ (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
+ (glp)aptr);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFlagsPtr
+configureFlagsSection (void)
+{
+ parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+ return ptr;
+}
+
+static XF86ConfModulePtr
+configureModuleSection (void)
+{
+ char **elist, **el;
+ /* Find the list of extension & font modules. */
+ const char *esubdirs[] = {
+ "extensions",
+ "fonts",
+ NULL
+ };
+ parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
+
+ elist = LoaderListDirs(esubdirs, NULL);
+ if (elist) {
+ for (el = elist; *el; el++) {
+ XF86LoadPtr module;
+
+ module = calloc(1, sizeof(XF86LoadRec));
+ module->load_name = *el;
+ ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
+ (glp)ptr->mod_load_lst, (glp)module);
+ }
+ free(elist);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFilesPtr
+configureFilesSection (void)
+{
+ parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
+
+ if (xf86ModulePath)
+ ptr->file_modulepath = strdup(xf86ModulePath);
+ if (defaultFontPath)
+ ptr->file_fontpath = strdup(defaultFontPath);
+
+ return ptr;
+}
+
+static XF86ConfMonitorPtr
+configureMonitorSection (int screennum)
+{
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ ptr->mon_identifier = malloc(19);
+ sprintf(ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup("Monitor Vendor");
+ ptr->mon_modelname = strdup("Monitor Model");
+
+ return ptr;
+}
+
+/* Initialize Configure Monitor from Detailed Timing Block */
+static void handle_detailed_input(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
+
+ switch (det_mon->type) {
+ case DS_NAME:
+ ptr->mon_modelname = realloc(ptr->mon_modelname,
+ strlen((char*)(det_mon->section.name)) +
+ 1);
+ strcpy(ptr->mon_modelname,
+ (char*)(det_mon->section.name));
+ break;
+ case DS_RANGES:
+ ptr->mon_hsync[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_h;
+ ptr->mon_hsync[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_h;
+ ptr->mon_n_vrefresh = 1;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_v;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_v;
+ ptr->mon_n_hsync++;
+ default:
+ break;
+ }
+}
+
+static XF86ConfMonitorPtr
+configureDDCMonitorSection (int screennum)
+{
+ int len, mon_width, mon_height;
+#define displaySizeMaxLen 80
+ char displaySize_string[displaySizeMaxLen];
+ int displaySizeLen;
+
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ ptr->mon_identifier = malloc(19);
+ sprintf(ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
+ ptr->mon_modelname = malloc(12);
+ sprintf(ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
+
+ /* features in centimetres, we want millimetres */
+ mon_width = 10 * ConfiguredMonitor->features.hsize ;
+ mon_height = 10 * ConfiguredMonitor->features.vsize ;
+
+#ifdef CONFIGURE_DISPLAYSIZE
+ ptr->mon_width = mon_width;
+ ptr->mon_height = mon_height;
+#else
+ if (mon_width && mon_height) {
+ /* when values available add DisplaySize option AS A COMMENT */
+
+ displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
+ "\t#DisplaySize\t%5d %5d\t# mm\n",
+ mon_width, mon_height);
+
+ if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
+ if (ptr->mon_comment) {
+ len = strlen(ptr->mon_comment);
+ } else {
+ len = 0;
+ }
+ if ((ptr->mon_comment =
+ realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
+ strcpy(ptr->mon_comment + len, displaySize_string);
+ }
+ }
+ }
+#endif /* def CONFIGURE_DISPLAYSIZE */
+
+ xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
+ ptr);
+
+ if (ConfiguredMonitor->features.dpms) {
+ ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, xstrdup("DPMS"), NULL);
+ }
+
+ return ptr;
+}
+
+#if !defined(PATH_MAX)
+# define PATH_MAX 1024
+#endif
+
+void
+DoConfigure(void)
+{
+ int i,j, screennum = -1;
+ char *home = NULL;
+ char filename[PATH_MAX];
+ char *addslash = "";
+ XF86ConfigPtr xf86config = NULL;
+ char **vlist, **vl;
+ int *dev2screen;
+
+ vlist = xf86DriverlistFromCompile();
+
+ if (!vlist) {
+ ErrorF("Missing output drivers. Configuration failed.\n");
+ goto bail;
+ }
+
+ ErrorF("List of video drivers:\n");
+ for (vl = vlist; *vl; vl++)
+ ErrorF("\t%s\n", *vl);
+
+ /* Load all the drivers that were found. */
+ xf86LoadModules(vlist, NULL);
+
+ free(vlist);
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ xorgHWFlags flags;
+ if (!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags)
+ || NEED_IO_ENABLED(flags)) {
+ xorgHWAccess = TRUE;
+ break;
+ }
+ }
+ /* Enable full I/O access */
+ if (xorgHWAccess) {
+ if(!xf86EnableIO())
+ /* oops, we have failed */
+ xorgHWAccess = FALSE;
+ }
+
+ xf86FindPrimaryDevice();
+
+ /* Create XF86Config file structure */
+ xf86config = calloc(1, sizeof(XF86ConfigRec));
+
+ /* Call all of the probe functions, reporting the results. */
+ for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
+ xorgHWFlags flags;
+ Bool found_screen;
+ DriverRec * const drv = xf86DriverList[CurrentDriver];
+
+ if (!xorgHWAccess) {
+ if (!drv->driverFunc
+ || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
+ || NEED_IO_ENABLED(flags))
+ continue;
+ }
+
+ found_screen = xf86CallDriverProbe( drv, TRUE );
+ if ( found_screen && drv->Identify ) {
+ (*drv->Identify)(0);
+ }
+ }
+
+ if (nDevToConfig <= 0) {
+ ErrorF("No devices to configure. Configuration failed.\n");
+ goto bail;
+ }
+
+ /* Add device, monitor and screen sections for detected devices */
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ XF86ConfDevicePtr DevicePtr;
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ DevicePtr = configureDeviceSection(screennum);
+ xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
+ (glp)xf86config->conf_device_lst, (glp)DevicePtr);
+ MonitorPtr = configureMonitorSection(screennum);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ ScreenPtr = configureScreenSection(screennum);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ xf86config->conf_files = configureFilesSection();
+ xf86config->conf_modules = configureModuleSection();
+ xf86config->conf_flags = configureFlagsSection();
+ xf86config->conf_videoadaptor_lst = NULL;
+ xf86config->conf_modes_lst = NULL;
+ xf86config->conf_vendor_lst = NULL;
+ xf86config->conf_dri = NULL;
+ xf86config->conf_input_lst = configureInputSection();
+ xf86config->conf_layout_lst = configureLayoutSection();
+
+ home = getenv("HOME");
+ if ((home == NULL) || (home[0] == '\0')) {
+ home = "/";
+ } else {
+ /* Determine if trailing slash is present or needed */
+ int l = strlen(home);
+
+ if (home[l-1] != '/') {
+ addslash = "/";
+ }
+ }
+
+ snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
+ home, addslash);
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+ /* Try to get DDC information filled in */
+ xf86ConfigFile = filename;
+ if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+
+ dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
+
+ {
+ Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ int k,l,n,oldNumScreens;
+
+ i = DevToConfig[screennum].iDriver;
+
+ if (driverProbed[i]) continue;
+ driverProbed[i] = TRUE;
+
+ oldNumScreens = xf86NumScreens;
+
+ xf86CallDriverProbe( xf86DriverList[i], FALSE );
+
+ /* reorder */
+ k = screennum > 0 ? screennum : 1;
+ for (l = oldNumScreens; l < xf86NumScreens; l++) {
+ /* is screen primary? */
+ Bool primary = FALSE;
+ for (n = 0; n<xf86Screens[l]->numEntities; n++) {
+ if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
+ dev2screen[0] = l;
+ primary = TRUE;
+ break;
+ }
+ }
+ if (primary) continue;
+ /* not primary: assign it to next device of same driver */
+ /*
+ * NOTE: we assume that devices in DevToConfig
+ * and xf86Screens[] have the same order except
+ * for the primary device which always comes first.
+ */
+ for (; k < nDevToConfig; k++) {
+ if (DevToConfig[k].iDriver == i) {
+ dev2screen[k++] = l;
+ break;
+ }
+ }
+ }
+ }
+ free(driverProbed);
+ }
+
+
+ if (nDevToConfig != xf86NumScreens) {
+ ErrorF("Number of created screens does not match number of detected"
+ " devices.\n Configuration failed.\n");
+ goto bail;
+ }
+
+ xf86PostProbe();
+ xf86EntityInit();
+
+ for (j = 0; j < xf86NumScreens; j++) {
+ xf86Screens[j]->scrnIndex = j;
+ }
+
+ xf86freeMonitorList(xf86config->conf_monitor_lst);
+ xf86config->conf_monitor_lst = NULL;
+ xf86freeScreenList(xf86config->conf_screen_lst);
+ xf86config->conf_screen_lst = NULL;
+ for (j = 0; j < xf86NumScreens; j++) {
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ ConfiguredMonitor = NULL;
+
+ xf86EnableAccess(xf86Screens[dev2screen[j]]);
+ if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
+ PROBE_DETECT) &&
+ ConfiguredMonitor) {
+ MonitorPtr = configureDDCMonitorSection(j);
+ } else {
+ MonitorPtr = configureMonitorSection(j);
+ }
+ ScreenPtr = configureScreenSection(j);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ ErrorF("\n");
+
+#ifdef __SCO__
+ ErrorF("\n"__XSERVERNAME__
+ " is using the kernel event driver to access the mouse.\n"
+ "If you wish to use the internal "__XSERVERNAME__
+ " mouse drivers, please\n"
+ "edit the file and correct the Device.\n");
+#else /* !__SCO__ */
+ if (!foundMouse) {
+ ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
+ "Edit the file and correct the Device.\n");
+ } else {
+ ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
+ "Please check your config if the mouse is still not\n"
+ "operational, as by default "__XSERVERNAME__
+ " tries to autodetect\n"
+ "the protocol.\n",DFLT_MOUSE_DEV);
+ }
+#endif /* !__SCO__ */
+
+ if (xf86NumScreens > 1) {
+ ErrorF("\n"__XSERVERNAME__
+ " has configured a multihead system, please check your config.\n");
+ }
+
+ ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
+ ErrorF("To test the server, run 'X -config %s'\n\n", filename);
+
+bail:
+ OsCleanup(TRUE);
+ AbortDDX();
+ fflush(stderr);
+ exit(0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Cursor.c b/xorg-server/hw/xfree86/common/xf86Cursor.c
index 6740faf65..76490e52d 100644
--- a/xorg-server/hw/xfree86/common/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/common/xf86Cursor.c
@@ -1,862 +1,862 @@
-/*
- * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include "input.h"
-#include "cursor.h"
-#include "mipointer.h"
-#include "scrnintstr.h"
-#include "globals.h"
-
-#include "compiler.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSproc.h"
-
-#include <X11/extensions/XIproto.h>
-#include "xf86Xinput.h"
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-typedef struct _xf86EdgeRec {
- short screen;
- short start;
- short end;
- DDXPointRec offset;
- struct _xf86EdgeRec *next;
-} xf86EdgeRec, *xf86EdgePtr;
-
-typedef struct {
- xf86EdgePtr left, right, up, down;
-} xf86ScreenLayoutRec, *xf86ScreenLayoutPtr;
-
-static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y);
-static void xf86CrossScreen(ScreenPtr pScreen, Bool entering);
-static void xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
-
-static void xf86PointerMoved(int scrnIndex, int x, int y);
-
-static miPointerScreenFuncRec xf86PointerScreenFuncs = {
- xf86CursorOffScreen,
- xf86CrossScreen,
- xf86WarpCursor,
- /* let miPointerInitialize take care of these */
- NULL,
- NULL
-};
-
-static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS];
-
-static Bool HardEdges;
-
-/*
- * xf86InitViewport --
- * Initialize paning & zooming parameters, so that a driver must only
- * check what resolutions are possible and whether the virtual area
- * is valid if specified.
- */
-
-void
-xf86InitViewport(ScrnInfoPtr pScr)
-{
-
- pScr->PointerMoved = xf86PointerMoved;
-
- /*
- * Compute the initial Viewport if necessary
- */
- if (pScr->display) {
- if (pScr->display->frameX0 < 0) {
- pScr->frameX0 = (pScr->virtualX - pScr->modes->HDisplay) / 2;
- pScr->frameY0 = (pScr->virtualY - pScr->modes->VDisplay) / 2;
- } else {
- pScr->frameX0 = pScr->display->frameX0;
- pScr->frameY0 = pScr->display->frameY0;
- }
- }
-
- pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
- pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
-
- /*
- * Now adjust the initial Viewport, so it lies within the virtual area
- */
- if (pScr->frameX1 >= pScr->virtualX)
- {
- pScr->frameX0 = pScr->virtualX - pScr->modes->HDisplay;
- pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
- }
-
- if (pScr->frameY1 >= pScr->virtualY)
- {
- pScr->frameY0 = pScr->virtualY - pScr->modes->VDisplay;
- pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
- }
-}
-
-
-/*
- * xf86SetViewport --
- * Scroll the visual part of the screen so the pointer is visible.
- */
-
-void
-xf86SetViewport(ScreenPtr pScreen, int x, int y)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
-
- (*pScr->PointerMoved)(pScreen->myNum, x, y);
-}
-
-
-static void
-xf86PointerMoved(int scrnIndex, int x, int y)
-{
- Bool frameChanged = FALSE;
- ScrnInfoPtr pScr = xf86Screens[scrnIndex];
-
- /*
- * check wether (x,y) belongs to the visual part of the screen
- * if not, change the base of the displayed frame accoring
- */
- if ( pScr->frameX0 > x) {
- pScr->frameX0 = x;
- pScr->frameX1 = x + pScr->currentMode->HDisplay - 1;
- frameChanged = TRUE ;
- }
-
- if ( pScr->frameX1 < x) {
- pScr->frameX1 = x + 1;
- pScr->frameX0 = x - pScr->currentMode->HDisplay + 1;
- frameChanged = TRUE ;
- }
-
- if ( pScr->frameY0 > y) {
- pScr->frameY0 = y;
- pScr->frameY1 = y + pScr->currentMode->VDisplay - 1;
- frameChanged = TRUE;
- }
-
- if ( pScr->frameY1 < y) {
- pScr->frameY1 = y;
- pScr->frameY0 = y - pScr->currentMode->VDisplay + 1;
- frameChanged = TRUE;
- }
-
- if (frameChanged && pScr->AdjustFrame != NULL)
- pScr->AdjustFrame(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
-}
-
-/*
- * xf86LockZoom --
- * Enable/disable ZoomViewport
- */
-
-void
-xf86LockZoom(ScreenPtr pScreen, Bool lock)
-{
- XF86SCRNINFO(pScreen)->zoomLocked = lock;
-}
-
-/*
- * xf86SwitchMode --
- * This is called by both keyboard processing and the VidMode extension to
- * set a new mode.
- */
-
-Bool
-xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
- ScreenPtr pCursorScreen;
- Bool Switched;
- int px, py;
- DeviceIntPtr dev, it;
-
- if (!pScr->vtSema || !mode || !pScr->SwitchMode)
- return FALSE;
-
-#ifdef XFreeXDGA
- if (DGAActive(pScr->scrnIndex))
- return FALSE;
-#endif
-
- if (mode == pScr->currentMode)
- return TRUE;
-
- if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
- return FALSE;
-
- /* Let's take an educated guess for which pointer to take here. And about as
- educated as it gets is to take the first pointer we find.
- */
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
- break;
- }
-
- pCursorScreen = miPointerGetScreen(dev);
- if (pScreen == pCursorScreen)
- miPointerGetPosition(dev, &px, &py);
-
- xf86EnterServerState(SETUP);
- Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0);
- if (Switched) {
- pScr->currentMode = mode;
-
- /*
- * Adjust frame for new display size.
- * Frame is centered around cursor position if cursor is on same screen.
- */
- if (pScreen == pCursorScreen)
- pScr->frameX0 = px - (mode->HDisplay / 2) + 1;
- else
- pScr->frameX0 = (pScr->frameX0 + pScr->frameX1 + 1 - mode->HDisplay) / 2;
-
- if (pScr->frameX0 < 0)
- pScr->frameX0 = 0;
-
- pScr->frameX1 = pScr->frameX0 + mode->HDisplay - 1;
- if (pScr->frameX1 >= pScr->virtualX) {
- pScr->frameX0 = pScr->virtualX - mode->HDisplay;
- pScr->frameX1 = pScr->virtualX - 1;
- }
-
- if (pScreen == pCursorScreen)
- pScr->frameY0 = py - (mode->VDisplay / 2) + 1;
- else
- pScr->frameY0 = (pScr->frameY0 + pScr->frameY1 + 1 - mode->VDisplay) / 2;
-
- if (pScr->frameY0 < 0)
- pScr->frameY0 = 0;
-
- pScr->frameY1 = pScr->frameY0 + mode->VDisplay - 1;
- if (pScr->frameY1 >= pScr->virtualY) {
- pScr->frameY0 = pScr->virtualY - mode->VDisplay;
- pScr->frameY1 = pScr->virtualY - 1;
- }
- }
- xf86EnterServerState(OPERATING);
-
- if (pScr->AdjustFrame)
- (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
-
- /* The original code centered the frame around the cursor if possible.
- * Since this is hard to achieve with multiple cursors, we do the following:
- * - center around the first pointer
- * - move all other pointers to the nearest edge on the screen (or leave
- * them unmodified if they are within the boundaries).
- */
- if (pScreen == pCursorScreen)
- {
- xf86WarpCursor(dev, pScreen, px, py);
- }
-
- for (it = inputInfo.devices; it; it = it->next)
- {
- if (it == dev)
- continue;
-
- if (IsPointerDevice(it) && it->spriteInfo->spriteOwner)
- {
- pCursorScreen = miPointerGetScreen(it);
- if (pScreen == pCursorScreen)
- {
- miPointerGetPosition(it, &px, &py);
- if (px < pScr->frameX0)
- px = pScr->frameX0;
- else if (px > pScr->frameX1)
- px = pScr->frameX1;
-
- if(py < pScr->frameY0)
- py = pScr->frameY0;
- else if(py > pScr->frameY1)
- py = pScr->frameY1;
-
- xf86WarpCursor(it, pScreen, px, py);
- }
- }
- }
-
- return Switched;
-}
-
-/*
- * xf86ZoomViewport --
- * Reinitialize the visual part of the screen for another mode.
- */
-
-void
-xf86ZoomViewport(ScreenPtr pScreen, int zoom)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
- DisplayModePtr mode;
-
- if (pScr->zoomLocked || !(mode = pScr->currentMode))
- return;
-
- do {
- if (zoom > 0)
- mode = mode->next;
- else
- mode = mode->prev;
- } while (mode != pScr->currentMode && !(mode->type & M_T_USERDEF));
-
- (void)xf86SwitchMode(pScreen, mode);
-}
-
-
-static xf86EdgePtr
-FindEdge(xf86EdgePtr edge, int val)
-{
- while(edge && (edge->end <= val))
- edge = edge->next;
-
- if(edge && (edge->start <= val))
- return edge;
-
- return NULL;
-}
-
-/*
- * xf86CursorOffScreen --
- * Check whether it is necessary to switch to another screen
- */
-
-static Bool
-xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
-{
- xf86EdgePtr edge;
- int tmp;
-
- if(screenInfo.numScreens == 1)
- return FALSE;
-
- if(*x < 0) {
- tmp = *y;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].left))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *x = 0;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*x >= (*pScreen)->width) {
- tmp = *y;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].right))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *x = (*pScreen)->width - 1;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*y < 0) {
- tmp = *x;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].up))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *y = 0;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*y >= (*pScreen)->height) {
- tmp = *x;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].down))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *y = (*pScreen)->height - 1;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- (*pScreen) = xf86Screens[edge->screen]->pScreen;
- }
- }
-
-
-#if 0
- /* This presents problems for overlapping screens when
- HardEdges is used. Have to think about the logic more */
- if((*x < 0) || (*x >= (*pScreen)->width) ||
- (*y < 0) || (*y >= (*pScreen)->height)) {
- /* We may have crossed more than one screen */
- xf86CursorOffScreen(pScreen, x, y);
- }
-#endif
-
- return TRUE;
-}
-
-
-
-/*
- * xf86CrossScreen --
- * Switch to another screen
- *
- * Currently nothing special happens, but mi assumes the CrossScreen
- * method exists.
- */
-
-static void
-xf86CrossScreen (ScreenPtr pScreen, Bool entering)
-{
-}
-
-
-/*
- * xf86WarpCursor --
- * Warp possible to another screen
- */
-
-/* ARGSUSED */
-static void
-xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- int sigstate;
- sigstate = xf86BlockSIGIO ();
- miPointerWarpCursor(pDev, pScreen, x, y);
-
- xf86Info.currentScreen = pScreen;
- xf86UnblockSIGIO (sigstate);
-}
-
-
-void *
-xf86GetPointerScreenFuncs(void)
-{
- return (void *)&xf86PointerScreenFuncs;
-}
-
-
-static xf86EdgePtr
-AddEdge(
- xf86EdgePtr edge,
- short min,
- short max,
- short dx,
- short dy,
- short screen
-){
- xf86EdgePtr pEdge = edge, pPrev = NULL, pNew;
-
- while(1) {
- while(pEdge && (min >= pEdge->end)) {
- pPrev = pEdge;
- pEdge = pEdge->next;
- }
-
- if(!pEdge) {
- if(!(pNew = xalloc(sizeof(xf86EdgeRec))))
- break;
-
- pNew->screen = screen;
- pNew->start = min;
- pNew->end = max;
- pNew->offset.x = dx;
- pNew->offset.y = dy;
- pNew->next = NULL;
-
- if(pPrev)
- pPrev->next = pNew;
- else
- edge = pNew;
-
- break;
- } else if (min < pEdge->start) {
- if(!(pNew = xalloc(sizeof(xf86EdgeRec))))
- break;
-
- pNew->screen = screen;
- pNew->start = min;
- pNew->offset.x = dx;
- pNew->offset.y = dy;
- pNew->next = pEdge;
-
- if(pPrev) pPrev->next = pNew;
- else edge = pNew;
-
- if(max <= pEdge->start) {
- pNew->end = max;
- break;
- } else {
- pNew->end = pEdge->start;
- min = pEdge->end;
- }
- } else
- min = pEdge->end;
-
- pPrev = pEdge;
- pEdge = pEdge->next;
-
- if(max <= min) break;
- }
-
- return edge;
-}
-
-static void
-FillOutEdge(xf86EdgePtr pEdge, int limit)
-{
- xf86EdgePtr pNext;
- int diff;
-
- if(pEdge->start > 0) pEdge->start = 0;
-
- while((pNext = pEdge->next)) {
- diff = pNext->start - pEdge->end;
- if(diff > 0) {
- pEdge->end += diff >> 1;
- pNext->start -= diff - (diff >> 1);
- }
- pEdge = pNext;
- }
-
- if(pEdge->end < limit)
- pEdge->end = limit;
-}
-
-/*
- * xf86InitOrigins() can deal with a maximum of 32 screens
- * on 32 bit architectures, 64 on 64 bit architectures.
- */
-
-void
-xf86InitOrigins(void)
-{
- unsigned long screensLeft, prevScreensLeft, mask;
- screenLayoutPtr screen;
- ScreenPtr pScreen;
- int x1, x2, y1, y2, left, right, top, bottom;
- int i, j, ref, minX, minY, min, max;
- xf86ScreenLayoutPtr pLayout;
- Bool OldStyleConfig = FALSE;
-
- /* need to have this set up with a config file option */
- HardEdges = FALSE;
-
- bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
-
- screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
-
- while(1) {
- for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) {
- if(!(mask & 1L)) continue;
-
- screen = &xf86ConfigLayout.screens[i];
-
- if (screen->refscreen != NULL &&
- screen->refscreen->screennum >= xf86NumScreens) {
- screensLeft &= ~(1 << i);
- xf86Msg(X_WARNING, "Not including screen \"%s\" in origins calculation.\n",
- screen->screen->id);
- continue;
- }
-
- switch(screen->where) {
- case PosObsolete:
- OldStyleConfig = TRUE;
- pLayout = &xf86ScreenLayout[i];
- /* force edge lists */
- if(screen->left) {
- ref = screen->left->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pLayout->left = AddEdge(pLayout->left,
- 0, xf86Screens[i]->pScreen->height,
- xf86Screens[ref]->pScreen->width, 0, ref);
- }
- if(screen->right) {
- ref = screen->right->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pScreen = xf86Screens[i]->pScreen;
- pLayout->right = AddEdge(pLayout->right,
- 0, pScreen->height, -pScreen->width, 0, ref);
- }
- if(screen->top) {
- ref = screen->top->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pLayout->up = AddEdge(pLayout->up,
- 0, xf86Screens[i]->pScreen->width,
- 0, xf86Screens[ref]->pScreen->height, ref);
- }
- if(screen->bottom) {
- ref = screen->bottom->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pScreen = xf86Screens[i]->pScreen;
- pLayout->down = AddEdge(pLayout->down,
- 0, pScreen->width, 0, -pScreen->height, ref);
- }
- /* we could also try to place it based on those
- relative locations if we wanted to */
- screen->x = screen->y = 0;
- /* FALLTHROUGH */
- case PosAbsolute:
- dixScreenOrigins[i].x = screen->x;
- dixScreenOrigins[i].y = screen->y;
- screensLeft &= ~(1 << i);
- break;
- case PosRelative:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y;
- screensLeft &= ~(1 << i);
- break;
- case PosRightOf:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[ref]->pScreen;
- dixScreenOrigins[i].x =
- dixScreenOrigins[ref].x + pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- screensLeft &= ~(1 << i);
- break;
- case PosLeftOf:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[i]->pScreen;
- dixScreenOrigins[i].x =
- dixScreenOrigins[ref].x - pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- screensLeft &= ~(1 << i);
- break;
- case PosBelow:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[ref]->pScreen;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y =
- dixScreenOrigins[ref].y + pScreen->height;
- screensLeft &= ~(1 << i);
- break;
- case PosAbove:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[i]->pScreen;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y =
- dixScreenOrigins[ref].y - pScreen->height;
- screensLeft &= ~(1 << i);
- break;
- default:
- ErrorF("Illegal placement keyword in Layout!\n");
- break;
- }
-
- }
-
- if(!screensLeft) break;
-
- if(screensLeft == prevScreensLeft) {
- /* All the remaining screens are referencing each other.
- Assign a value to one of them and go through again */
- i = 0;
- while(!((1 << i) & screensLeft)){ i++; }
-
- ref = xf86ConfigLayout.screens[i].refscreen->screennum;
- dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
- screensLeft &= ~(1 << ref);
- }
-
- prevScreensLeft = screensLeft;
- }
-
- /* justify the topmost and leftmost to (0,0) */
- minX = dixScreenOrigins[0].x;
- minY = dixScreenOrigins[0].y;
-
- for(i = 1; i < xf86NumScreens; i++) {
- if(dixScreenOrigins[i].x < minX)
- minX = dixScreenOrigins[i].x;
- if(dixScreenOrigins[i].y < minY)
- minY = dixScreenOrigins[i].y;
- }
-
- if (minX || minY) {
- for(i = 0; i < xf86NumScreens; i++) {
- dixScreenOrigins[i].x -= minX;
- dixScreenOrigins[i].y -= minY;
- }
- }
-
-
- /* Create the edge lists */
-
- if(!OldStyleConfig) {
- for(i = 0; i < xf86NumScreens; i++) {
- pLayout = &xf86ScreenLayout[i];
-
- pScreen = xf86Screens[i]->pScreen;
-
- left = dixScreenOrigins[i].x;
- right = left + pScreen->width;
- top = dixScreenOrigins[i].y;
- bottom = top + pScreen->height;
-
- for(j = 0; j < xf86NumScreens; j++) {
- if(i == j) continue;
-
- x1 = dixScreenOrigins[j].x;
- x2 = x1 + xf86Screens[j]->pScreen->width;
- y1 = dixScreenOrigins[j].y;
- y2 = y1 + xf86Screens[j]->pScreen->height;
-
- if((bottom > y1) && (top < y2)) {
- min = y1 - top;
- if(min < 0) min = 0;
- max = pScreen->height - (bottom - y2);
- if(max > pScreen->height) max = pScreen->height;
-
- if(((left - 1) >= x1) && ((left - 1) < x2))
- pLayout->left = AddEdge(pLayout->left, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
-
- if((right >= x1) && (right < x2))
- pLayout->right = AddEdge(pLayout->right, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
- }
-
-
- if((left < x2) && (right > x1)) {
- min = x1 - left;
- if(min < 0) min = 0;
- max = pScreen->width - (right - x2);
- if(max > pScreen->width) max = pScreen->width;
-
- if(((top - 1) >= y1) && ((top - 1) < y2))
- pLayout->up = AddEdge(pLayout->up, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
-
- if((bottom >= y1) && (bottom < y2))
- pLayout->down = AddEdge(pLayout->down, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
- }
- }
- }
- }
-
- if(!HardEdges && !OldStyleConfig) {
- for(i = 0; i < xf86NumScreens; i++) {
- pLayout = &xf86ScreenLayout[i];
- pScreen = xf86Screens[i]->pScreen;
- if(pLayout->left)
- FillOutEdge(pLayout->left, pScreen->height);
- if(pLayout->right)
- FillOutEdge(pLayout->right, pScreen->height);
- if(pLayout->up)
- FillOutEdge(pLayout->up, pScreen->width);
- if(pLayout->down)
- FillOutEdge(pLayout->down, pScreen->width);
- }
- }
-}
-
-void
-xf86ReconfigureLayout(void)
-{
- int i;
-
- for (i = 0; i < MAXSCREENS; i++) {
- xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i];
- /* we don't have to zero these, xf86InitOrigins() takes care of that */
- if (sl->left) xfree(sl->left);
- if (sl->right) xfree(sl->right);
- if (sl->up) xfree(sl->up);
- if (sl->down) xfree(sl->down);
- }
-
- xf86InitOrigins();
-}
-
-
+/*
+ * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "input.h"
+#include "cursor.h"
+#include "mipointer.h"
+#include "scrnintstr.h"
+#include "globals.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+
+#include <X11/extensions/XIproto.h>
+#include "xf86Xinput.h"
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+typedef struct _xf86EdgeRec {
+ short screen;
+ short start;
+ short end;
+ DDXPointRec offset;
+ struct _xf86EdgeRec *next;
+} xf86EdgeRec, *xf86EdgePtr;
+
+typedef struct {
+ xf86EdgePtr left, right, up, down;
+} xf86ScreenLayoutRec, *xf86ScreenLayoutPtr;
+
+static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y);
+static void xf86CrossScreen(ScreenPtr pScreen, Bool entering);
+static void xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+
+static void xf86PointerMoved(int scrnIndex, int x, int y);
+
+static miPointerScreenFuncRec xf86PointerScreenFuncs = {
+ xf86CursorOffScreen,
+ xf86CrossScreen,
+ xf86WarpCursor,
+ /* let miPointerInitialize take care of these */
+ NULL,
+ NULL
+};
+
+static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS];
+
+static Bool HardEdges;
+
+/*
+ * xf86InitViewport --
+ * Initialize paning & zooming parameters, so that a driver must only
+ * check what resolutions are possible and whether the virtual area
+ * is valid if specified.
+ */
+
+void
+xf86InitViewport(ScrnInfoPtr pScr)
+{
+
+ pScr->PointerMoved = xf86PointerMoved;
+
+ /*
+ * Compute the initial Viewport if necessary
+ */
+ if (pScr->display) {
+ if (pScr->display->frameX0 < 0) {
+ pScr->frameX0 = (pScr->virtualX - pScr->modes->HDisplay) / 2;
+ pScr->frameY0 = (pScr->virtualY - pScr->modes->VDisplay) / 2;
+ } else {
+ pScr->frameX0 = pScr->display->frameX0;
+ pScr->frameY0 = pScr->display->frameY0;
+ }
+ }
+
+ pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
+ pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
+
+ /*
+ * Now adjust the initial Viewport, so it lies within the virtual area
+ */
+ if (pScr->frameX1 >= pScr->virtualX)
+ {
+ pScr->frameX0 = pScr->virtualX - pScr->modes->HDisplay;
+ pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
+ }
+
+ if (pScr->frameY1 >= pScr->virtualY)
+ {
+ pScr->frameY0 = pScr->virtualY - pScr->modes->VDisplay;
+ pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
+ }
+}
+
+
+/*
+ * xf86SetViewport --
+ * Scroll the visual part of the screen so the pointer is visible.
+ */
+
+void
+xf86SetViewport(ScreenPtr pScreen, int x, int y)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+
+ (*pScr->PointerMoved)(pScreen->myNum, x, y);
+}
+
+
+static void
+xf86PointerMoved(int scrnIndex, int x, int y)
+{
+ Bool frameChanged = FALSE;
+ ScrnInfoPtr pScr = xf86Screens[scrnIndex];
+
+ /*
+ * check wether (x,y) belongs to the visual part of the screen
+ * if not, change the base of the displayed frame accoring
+ */
+ if ( pScr->frameX0 > x) {
+ pScr->frameX0 = x;
+ pScr->frameX1 = x + pScr->currentMode->HDisplay - 1;
+ frameChanged = TRUE ;
+ }
+
+ if ( pScr->frameX1 < x) {
+ pScr->frameX1 = x + 1;
+ pScr->frameX0 = x - pScr->currentMode->HDisplay + 1;
+ frameChanged = TRUE ;
+ }
+
+ if ( pScr->frameY0 > y) {
+ pScr->frameY0 = y;
+ pScr->frameY1 = y + pScr->currentMode->VDisplay - 1;
+ frameChanged = TRUE;
+ }
+
+ if ( pScr->frameY1 < y) {
+ pScr->frameY1 = y;
+ pScr->frameY0 = y - pScr->currentMode->VDisplay + 1;
+ frameChanged = TRUE;
+ }
+
+ if (frameChanged && pScr->AdjustFrame != NULL)
+ pScr->AdjustFrame(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
+}
+
+/*
+ * xf86LockZoom --
+ * Enable/disable ZoomViewport
+ */
+
+void
+xf86LockZoom(ScreenPtr pScreen, Bool lock)
+{
+ XF86SCRNINFO(pScreen)->zoomLocked = lock;
+}
+
+/*
+ * xf86SwitchMode --
+ * This is called by both keyboard processing and the VidMode extension to
+ * set a new mode.
+ */
+
+Bool
+xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+ ScreenPtr pCursorScreen;
+ Bool Switched;
+ int px, py;
+ DeviceIntPtr dev, it;
+
+ if (!pScr->vtSema || !mode || !pScr->SwitchMode)
+ return FALSE;
+
+#ifdef XFreeXDGA
+ if (DGAActive(pScr->scrnIndex))
+ return FALSE;
+#endif
+
+ if (mode == pScr->currentMode)
+ return TRUE;
+
+ if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
+ return FALSE;
+
+ /* Let's take an educated guess for which pointer to take here. And about as
+ educated as it gets is to take the first pointer we find.
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
+ break;
+ }
+
+ pCursorScreen = miPointerGetScreen(dev);
+ if (pScreen == pCursorScreen)
+ miPointerGetPosition(dev, &px, &py);
+
+ xf86EnterServerState(SETUP);
+ Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0);
+ if (Switched) {
+ pScr->currentMode = mode;
+
+ /*
+ * Adjust frame for new display size.
+ * Frame is centered around cursor position if cursor is on same screen.
+ */
+ if (pScreen == pCursorScreen)
+ pScr->frameX0 = px - (mode->HDisplay / 2) + 1;
+ else
+ pScr->frameX0 = (pScr->frameX0 + pScr->frameX1 + 1 - mode->HDisplay) / 2;
+
+ if (pScr->frameX0 < 0)
+ pScr->frameX0 = 0;
+
+ pScr->frameX1 = pScr->frameX0 + mode->HDisplay - 1;
+ if (pScr->frameX1 >= pScr->virtualX) {
+ pScr->frameX0 = pScr->virtualX - mode->HDisplay;
+ pScr->frameX1 = pScr->virtualX - 1;
+ }
+
+ if (pScreen == pCursorScreen)
+ pScr->frameY0 = py - (mode->VDisplay / 2) + 1;
+ else
+ pScr->frameY0 = (pScr->frameY0 + pScr->frameY1 + 1 - mode->VDisplay) / 2;
+
+ if (pScr->frameY0 < 0)
+ pScr->frameY0 = 0;
+
+ pScr->frameY1 = pScr->frameY0 + mode->VDisplay - 1;
+ if (pScr->frameY1 >= pScr->virtualY) {
+ pScr->frameY0 = pScr->virtualY - mode->VDisplay;
+ pScr->frameY1 = pScr->virtualY - 1;
+ }
+ }
+ xf86EnterServerState(OPERATING);
+
+ if (pScr->AdjustFrame)
+ (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
+
+ /* The original code centered the frame around the cursor if possible.
+ * Since this is hard to achieve with multiple cursors, we do the following:
+ * - center around the first pointer
+ * - move all other pointers to the nearest edge on the screen (or leave
+ * them unmodified if they are within the boundaries).
+ */
+ if (pScreen == pCursorScreen)
+ {
+ xf86WarpCursor(dev, pScreen, px, py);
+ }
+
+ for (it = inputInfo.devices; it; it = it->next)
+ {
+ if (it == dev)
+ continue;
+
+ if (IsPointerDevice(it) && it->spriteInfo->spriteOwner)
+ {
+ pCursorScreen = miPointerGetScreen(it);
+ if (pScreen == pCursorScreen)
+ {
+ miPointerGetPosition(it, &px, &py);
+ if (px < pScr->frameX0)
+ px = pScr->frameX0;
+ else if (px > pScr->frameX1)
+ px = pScr->frameX1;
+
+ if(py < pScr->frameY0)
+ py = pScr->frameY0;
+ else if(py > pScr->frameY1)
+ py = pScr->frameY1;
+
+ xf86WarpCursor(it, pScreen, px, py);
+ }
+ }
+ }
+
+ return Switched;
+}
+
+/*
+ * xf86ZoomViewport --
+ * Reinitialize the visual part of the screen for another mode.
+ */
+
+void
+xf86ZoomViewport(ScreenPtr pScreen, int zoom)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+ DisplayModePtr mode;
+
+ if (pScr->zoomLocked || !(mode = pScr->currentMode))
+ return;
+
+ do {
+ if (zoom > 0)
+ mode = mode->next;
+ else
+ mode = mode->prev;
+ } while (mode != pScr->currentMode && !(mode->type & M_T_USERDEF));
+
+ (void)xf86SwitchMode(pScreen, mode);
+}
+
+
+static xf86EdgePtr
+FindEdge(xf86EdgePtr edge, int val)
+{
+ while(edge && (edge->end <= val))
+ edge = edge->next;
+
+ if(edge && (edge->start <= val))
+ return edge;
+
+ return NULL;
+}
+
+/*
+ * xf86CursorOffScreen --
+ * Check whether it is necessary to switch to another screen
+ */
+
+static Bool
+xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
+{
+ xf86EdgePtr edge;
+ int tmp;
+
+ if(screenInfo.numScreens == 1)
+ return FALSE;
+
+ if(*x < 0) {
+ tmp = *y;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].left))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *x = 0;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*x >= (*pScreen)->width) {
+ tmp = *y;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].right))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *x = (*pScreen)->width - 1;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*y < 0) {
+ tmp = *x;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].up))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *y = 0;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*y >= (*pScreen)->height) {
+ tmp = *x;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].down))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *y = (*pScreen)->height - 1;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ (*pScreen) = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+
+#if 0
+ /* This presents problems for overlapping screens when
+ HardEdges is used. Have to think about the logic more */
+ if((*x < 0) || (*x >= (*pScreen)->width) ||
+ (*y < 0) || (*y >= (*pScreen)->height)) {
+ /* We may have crossed more than one screen */
+ xf86CursorOffScreen(pScreen, x, y);
+ }
+#endif
+
+ return TRUE;
+}
+
+
+
+/*
+ * xf86CrossScreen --
+ * Switch to another screen
+ *
+ * Currently nothing special happens, but mi assumes the CrossScreen
+ * method exists.
+ */
+
+static void
+xf86CrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+
+/*
+ * xf86WarpCursor --
+ * Warp possible to another screen
+ */
+
+/* ARGSUSED */
+static void
+xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ int sigstate;
+ sigstate = xf86BlockSIGIO ();
+ miPointerWarpCursor(pDev, pScreen, x, y);
+
+ xf86Info.currentScreen = pScreen;
+ xf86UnblockSIGIO (sigstate);
+}
+
+
+void *
+xf86GetPointerScreenFuncs(void)
+{
+ return (void *)&xf86PointerScreenFuncs;
+}
+
+
+static xf86EdgePtr
+AddEdge(
+ xf86EdgePtr edge,
+ short min,
+ short max,
+ short dx,
+ short dy,
+ short screen
+){
+ xf86EdgePtr pEdge = edge, pPrev = NULL, pNew;
+
+ while(1) {
+ while(pEdge && (min >= pEdge->end)) {
+ pPrev = pEdge;
+ pEdge = pEdge->next;
+ }
+
+ if(!pEdge) {
+ if(!(pNew = malloc(sizeof(xf86EdgeRec))))
+ break;
+
+ pNew->screen = screen;
+ pNew->start = min;
+ pNew->end = max;
+ pNew->offset.x = dx;
+ pNew->offset.y = dy;
+ pNew->next = NULL;
+
+ if(pPrev)
+ pPrev->next = pNew;
+ else
+ edge = pNew;
+
+ break;
+ } else if (min < pEdge->start) {
+ if(!(pNew = malloc(sizeof(xf86EdgeRec))))
+ break;
+
+ pNew->screen = screen;
+ pNew->start = min;
+ pNew->offset.x = dx;
+ pNew->offset.y = dy;
+ pNew->next = pEdge;
+
+ if(pPrev) pPrev->next = pNew;
+ else edge = pNew;
+
+ if(max <= pEdge->start) {
+ pNew->end = max;
+ break;
+ } else {
+ pNew->end = pEdge->start;
+ min = pEdge->end;
+ }
+ } else
+ min = pEdge->end;
+
+ pPrev = pEdge;
+ pEdge = pEdge->next;
+
+ if(max <= min) break;
+ }
+
+ return edge;
+}
+
+static void
+FillOutEdge(xf86EdgePtr pEdge, int limit)
+{
+ xf86EdgePtr pNext;
+ int diff;
+
+ if(pEdge->start > 0) pEdge->start = 0;
+
+ while((pNext = pEdge->next)) {
+ diff = pNext->start - pEdge->end;
+ if(diff > 0) {
+ pEdge->end += diff >> 1;
+ pNext->start -= diff - (diff >> 1);
+ }
+ pEdge = pNext;
+ }
+
+ if(pEdge->end < limit)
+ pEdge->end = limit;
+}
+
+/*
+ * xf86InitOrigins() can deal with a maximum of 32 screens
+ * on 32 bit architectures, 64 on 64 bit architectures.
+ */
+
+void
+xf86InitOrigins(void)
+{
+ unsigned long screensLeft, prevScreensLeft, mask;
+ screenLayoutPtr screen;
+ ScreenPtr pScreen;
+ int x1, x2, y1, y2, left, right, top, bottom;
+ int i, j, ref, minX, minY, min, max;
+ xf86ScreenLayoutPtr pLayout;
+ Bool OldStyleConfig = FALSE;
+
+ /* need to have this set up with a config file option */
+ HardEdges = FALSE;
+
+ bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
+
+ screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
+
+ while(1) {
+ for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) {
+ if(!(mask & 1L)) continue;
+
+ screen = &xf86ConfigLayout.screens[i];
+
+ if (screen->refscreen != NULL &&
+ screen->refscreen->screennum >= xf86NumScreens) {
+ screensLeft &= ~(1 << i);
+ xf86Msg(X_WARNING, "Not including screen \"%s\" in origins calculation.\n",
+ screen->screen->id);
+ continue;
+ }
+
+ switch(screen->where) {
+ case PosObsolete:
+ OldStyleConfig = TRUE;
+ pLayout = &xf86ScreenLayout[i];
+ /* force edge lists */
+ if(screen->left) {
+ ref = screen->left->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pLayout->left = AddEdge(pLayout->left,
+ 0, xf86Screens[i]->pScreen->height,
+ xf86Screens[ref]->pScreen->width, 0, ref);
+ }
+ if(screen->right) {
+ ref = screen->right->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pScreen = xf86Screens[i]->pScreen;
+ pLayout->right = AddEdge(pLayout->right,
+ 0, pScreen->height, -pScreen->width, 0, ref);
+ }
+ if(screen->top) {
+ ref = screen->top->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pLayout->up = AddEdge(pLayout->up,
+ 0, xf86Screens[i]->pScreen->width,
+ 0, xf86Screens[ref]->pScreen->height, ref);
+ }
+ if(screen->bottom) {
+ ref = screen->bottom->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pScreen = xf86Screens[i]->pScreen;
+ pLayout->down = AddEdge(pLayout->down,
+ 0, pScreen->width, 0, -pScreen->height, ref);
+ }
+ /* we could also try to place it based on those
+ relative locations if we wanted to */
+ screen->x = screen->y = 0;
+ /* FALLTHROUGH */
+ case PosAbsolute:
+ dixScreenOrigins[i].x = screen->x;
+ dixScreenOrigins[i].y = screen->y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosRelative:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosRightOf:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[ref]->pScreen;
+ dixScreenOrigins[i].x =
+ dixScreenOrigins[ref].x + pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosLeftOf:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[i]->pScreen;
+ dixScreenOrigins[i].x =
+ dixScreenOrigins[ref].x - pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosBelow:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[ref]->pScreen;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y =
+ dixScreenOrigins[ref].y + pScreen->height;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosAbove:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[i]->pScreen;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y =
+ dixScreenOrigins[ref].y - pScreen->height;
+ screensLeft &= ~(1 << i);
+ break;
+ default:
+ ErrorF("Illegal placement keyword in Layout!\n");
+ break;
+ }
+
+ }
+
+ if(!screensLeft) break;
+
+ if(screensLeft == prevScreensLeft) {
+ /* All the remaining screens are referencing each other.
+ Assign a value to one of them and go through again */
+ i = 0;
+ while(!((1 << i) & screensLeft)){ i++; }
+
+ ref = xf86ConfigLayout.screens[i].refscreen->screennum;
+ dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
+ screensLeft &= ~(1 << ref);
+ }
+
+ prevScreensLeft = screensLeft;
+ }
+
+ /* justify the topmost and leftmost to (0,0) */
+ minX = dixScreenOrigins[0].x;
+ minY = dixScreenOrigins[0].y;
+
+ for(i = 1; i < xf86NumScreens; i++) {
+ if(dixScreenOrigins[i].x < minX)
+ minX = dixScreenOrigins[i].x;
+ if(dixScreenOrigins[i].y < minY)
+ minY = dixScreenOrigins[i].y;
+ }
+
+ if (minX || minY) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ dixScreenOrigins[i].x -= minX;
+ dixScreenOrigins[i].y -= minY;
+ }
+ }
+
+
+ /* Create the edge lists */
+
+ if(!OldStyleConfig) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ pLayout = &xf86ScreenLayout[i];
+
+ pScreen = xf86Screens[i]->pScreen;
+
+ left = dixScreenOrigins[i].x;
+ right = left + pScreen->width;
+ top = dixScreenOrigins[i].y;
+ bottom = top + pScreen->height;
+
+ for(j = 0; j < xf86NumScreens; j++) {
+ if(i == j) continue;
+
+ x1 = dixScreenOrigins[j].x;
+ x2 = x1 + xf86Screens[j]->pScreen->width;
+ y1 = dixScreenOrigins[j].y;
+ y2 = y1 + xf86Screens[j]->pScreen->height;
+
+ if((bottom > y1) && (top < y2)) {
+ min = y1 - top;
+ if(min < 0) min = 0;
+ max = pScreen->height - (bottom - y2);
+ if(max > pScreen->height) max = pScreen->height;
+
+ if(((left - 1) >= x1) && ((left - 1) < x2))
+ pLayout->left = AddEdge(pLayout->left, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+
+ if((right >= x1) && (right < x2))
+ pLayout->right = AddEdge(pLayout->right, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+ }
+
+
+ if((left < x2) && (right > x1)) {
+ min = x1 - left;
+ if(min < 0) min = 0;
+ max = pScreen->width - (right - x2);
+ if(max > pScreen->width) max = pScreen->width;
+
+ if(((top - 1) >= y1) && ((top - 1) < y2))
+ pLayout->up = AddEdge(pLayout->up, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+
+ if((bottom >= y1) && (bottom < y2))
+ pLayout->down = AddEdge(pLayout->down, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+ }
+ }
+ }
+ }
+
+ if(!HardEdges && !OldStyleConfig) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ pLayout = &xf86ScreenLayout[i];
+ pScreen = xf86Screens[i]->pScreen;
+ if(pLayout->left)
+ FillOutEdge(pLayout->left, pScreen->height);
+ if(pLayout->right)
+ FillOutEdge(pLayout->right, pScreen->height);
+ if(pLayout->up)
+ FillOutEdge(pLayout->up, pScreen->width);
+ if(pLayout->down)
+ FillOutEdge(pLayout->down, pScreen->width);
+ }
+ }
+}
+
+void
+xf86ReconfigureLayout(void)
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++) {
+ xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i];
+ /* we don't have to zero these, xf86InitOrigins() takes care of that */
+ if (sl->left) free(sl->left);
+ if (sl->right) free(sl->right);
+ if (sl->up) free(sl->up);
+ if (sl->down) free(sl->down);
+ }
+
+ xf86InitOrigins();
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86DGA.c b/xorg-server/hw/xfree86/common/xf86DGA.c
index 794a13171..ac8302169 100644
--- a/xorg-server/hw/xfree86/common/xf86DGA.c
+++ b/xorg-server/hw/xfree86/common/xf86DGA.c
@@ -1,1227 +1,1227 @@
-/*
- * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- *
- * Written by Mark Vojkovich
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86str.h"
-#include "xf86Priv.h"
-#include "dgaproc.h"
-#include <X11/extensions/xf86dgaproto.h>
-#include "colormapst.h"
-#include "pixmapstr.h"
-#include "inputstr.h"
-#include "globals.h"
-#include "servermd.h"
-#include "micmap.h"
-#include "xkbsrv.h"
-#include "xf86Xinput.h"
-#include "exglobals.h"
-#include "exevents.h"
-#include "eventstr.h"
-#include "eventconvert.h"
-
-#include "mi.h"
-
-static int DGAScreenKeyIndex;
-static DevPrivateKey DGAScreenKey;
-static int mieq_installed = 0;
-
-static Bool DGACloseScreen(int i, ScreenPtr pScreen);
-static void DGADestroyColormap(ColormapPtr pmap);
-static void DGAInstallColormap(ColormapPtr pmap);
-static void DGAUninstallColormap(ColormapPtr pmap);
-static void DGAHandleEvent(int screen_num, InternalEvent *event,
- DeviceIntPtr device);
-
-static void
-DGACopyModeInfo(
- DGAModePtr mode,
- XDGAModePtr xmode
-);
-
-int *XDGAEventBase = NULL;
-
-#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, DGAScreenKey))
-
-
-typedef struct _FakedVisualList{
- Bool free;
- VisualPtr pVisual;
- struct _FakedVisualList *next;
-} FakedVisualList;
-
-
-typedef struct {
- ScrnInfoPtr pScrn;
- int numModes;
- DGAModePtr modes;
- CloseScreenProcPtr CloseScreen;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- UninstallColormapProcPtr UninstallColormap;
- DGADevicePtr current;
- DGAFunctionPtr funcs;
- int input;
- ClientPtr client;
- int pixmapMode;
- FakedVisualList *fakedVisuals;
- ColormapPtr dgaColormap;
- ColormapPtr savedColormap;
- Bool grabMouse;
- Bool grabKeyboard;
-} DGAScreenRec, *DGAScreenPtr;
-
-Bool
-DGAInit(
- ScreenPtr pScreen,
- DGAFunctionPtr funcs,
- DGAModePtr modes,
- int num
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DGAScreenPtr pScreenPriv;
- int i;
-
- if(!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
- return FALSE;
-
- if(!modes || num <= 0)
- return FALSE;
-
- DGAScreenKey = &DGAScreenKeyIndex;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (!pScreenPriv)
- {
- if(!(pScreenPriv = (DGAScreenPtr)xalloc(sizeof(DGAScreenRec))))
- return FALSE;
- dixSetPrivate(&pScreen->devPrivates, DGAScreenKey, pScreenPriv);
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = DGACloseScreen;
- pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
- pScreen->DestroyColormap = DGADestroyColormap;
- pScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreen->InstallColormap = DGAInstallColormap;
- pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
- pScreen->UninstallColormap = DGAUninstallColormap;
- }
-
- pScreenPriv->pScrn = pScrn;
- pScreenPriv->numModes = num;
- pScreenPriv->modes = modes;
- pScreenPriv->current = NULL;
-
- pScreenPriv->funcs = funcs;
- pScreenPriv->input = 0;
- pScreenPriv->client = NULL;
- pScreenPriv->fakedVisuals = NULL;
- pScreenPriv->dgaColormap = NULL;
- pScreenPriv->savedColormap = NULL;
- pScreenPriv->grabMouse = FALSE;
- pScreenPriv->grabKeyboard = FALSE;
-
- for(i = 0; i < num; i++)
- modes[i].num = i + 1;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension)
- for(i = 0; i < num; i++)
- modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
-#endif
-
- return TRUE;
-}
-
-/* DGAReInitModes allows the driver to re-initialize
- * the DGA mode list.
- */
-
-Bool
-DGAReInitModes(
- ScreenPtr pScreen,
- DGAModePtr modes,
- int num
-){
- DGAScreenPtr pScreenPriv;
- int i;
-
- /* No DGA? Ignore call (but don't make it look like it failed) */
- if(DGAScreenKey == NULL)
- return TRUE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* Same as above */
- if(!pScreenPriv)
- return TRUE;
-
- /* Can't do this while DGA is active */
- if(pScreenPriv->current)
- return FALSE;
-
- /* Quick sanity check */
- if(!num)
- modes = NULL;
- else if(!modes)
- num = 0;
-
- pScreenPriv->numModes = num;
- pScreenPriv->modes = modes;
-
- /* This practically disables DGA. So be it. */
- if(!num)
- return TRUE;
-
- for(i = 0; i < num; i++)
- modes[i].num = i + 1;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension)
- for(i = 0; i < num; i++)
- modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
-#endif
-
- return TRUE;
-}
-
-static void
-FreeMarkedVisuals(ScreenPtr pScreen)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- FakedVisualList *prev, *curr, *tmp;
-
- if(!pScreenPriv->fakedVisuals)
- return;
-
- prev = NULL;
- curr = pScreenPriv->fakedVisuals;
-
- while(curr) {
- if(curr->free) {
- tmp = curr;
- curr = curr->next;
- if(prev)
- prev->next = curr;
- else
- pScreenPriv->fakedVisuals = curr;
- xfree(tmp->pVisual);
- xfree(tmp);
- } else {
- prev = curr;
- curr = curr->next;
- }
- }
-}
-
-static Bool
-DGACloseScreen(int i, ScreenPtr pScreen)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (XDGAEventBase) {
- mieqSetHandler(ET_DGAEvent, NULL);
- }
-
- FreeMarkedVisuals(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
-
- /* DGAShutdown() should have ensured that no DGA
- screen were active by here */
-
- xfree(pScreenPriv);
-
- return((*pScreen->CloseScreen)(i, pScreen));
-}
-
-
-static void
-DGADestroyColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- VisualPtr pVisual = pmap->pVisual;
-
- if(pScreenPriv->fakedVisuals) {
- FakedVisualList *curr = pScreenPriv->fakedVisuals;
-
- while(curr) {
- if(curr->pVisual == pVisual) {
- /* We can't get rid of them yet since FreeColormap
- still needs the pVisual during the cleanup */
- curr->free = TRUE;
- break;
- }
- curr = curr->next;
- }
- }
-
- if(pScreenPriv->DestroyColormap) {
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- (*pScreen->DestroyColormap)(pmap);
- pScreen->DestroyColormap = DGADestroyColormap;
- }
-}
-
-
-static void
-DGAInstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv->current && pScreenPriv->dgaColormap) {
- if (pmap != pScreenPriv->dgaColormap) {
- pScreenPriv->savedColormap = pmap;
- pmap = pScreenPriv->dgaColormap;
- }
- }
-
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- (*pScreen->InstallColormap)(pmap);
- pScreen->InstallColormap = DGAInstallColormap;
-}
-
-static void
-DGAUninstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv->current && pScreenPriv->dgaColormap) {
- if (pmap == pScreenPriv->dgaColormap) {
- pScreenPriv->dgaColormap = NULL;
- }
- }
-
- pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
- (*pScreen->UninstallColormap)(pmap);
- pScreen->UninstallColormap = DGAUninstallColormap;
-}
-
-int
-xf86SetDGAMode(
- int index,
- int num,
- DGADevicePtr devRet
-){
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv;
- ScrnInfoPtr pScrn;
- DGADevicePtr device;
- PixmapPtr pPix = NULL;
- DGAModePtr pMode = NULL;
-
- /* First check if DGAInit was successful on this screen */
- if (DGAScreenKey == NULL)
- return BadValue;
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- if (!pScreenPriv)
- return BadValue;
- pScrn = pScreenPriv->pScrn;
-
- if(!num) {
- if(pScreenPriv->current) {
- PixmapPtr oldPix = pScreenPriv->current->pPix;
- if(oldPix) {
- if(oldPix->drawable.id)
- FreeResource(oldPix->drawable.id, RT_NONE);
- else
- (*pScreen->DestroyPixmap)(oldPix);
- }
- xfree(pScreenPriv->current);
- pScreenPriv->current = NULL;
- pScrn->vtSema = TRUE;
- (*pScreenPriv->funcs->SetMode)(pScrn, NULL);
- if(pScreenPriv->savedColormap) {
- (*pScreen->InstallColormap)(pScreenPriv->savedColormap);
- pScreenPriv->savedColormap = NULL;
- }
- pScreenPriv->dgaColormap = NULL;
- (*pScrn->EnableDisableFBAccess)(index, TRUE);
-
- FreeMarkedVisuals(pScreen);
- }
-
- pScreenPriv->grabMouse = FALSE;
- pScreenPriv->grabKeyboard = FALSE;
-
- return Success;
- }
-
- if(!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */
- return BadAlloc;
-
- if((num > 0) && (num <= pScreenPriv->numModes))
- pMode = &(pScreenPriv->modes[num - 1]);
- else
- return BadValue;
-
- if(!(device = (DGADevicePtr)xalloc(sizeof(DGADeviceRec))))
- return BadAlloc;
-
- if(!pScreenPriv->current) {
- Bool oldVTSema = pScrn->vtSema;
-
- pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */
- (*pScrn->EnableDisableFBAccess)(index, FALSE);
- pScrn->vtSema = oldVTSema;
- }
-
- if(!(*pScreenPriv->funcs->SetMode)(pScrn, pMode)) {
- xfree(device);
- return BadAlloc;
- }
-
- pScrn->currentMode = pMode->mode;
-
- if(!pScreenPriv->current && !pScreenPriv->input) {
- /* if it's multihead we need to warp the cursor off of
- our screen so it doesn't get trapped */
- }
-
- pScrn->vtSema = FALSE;
-
- if(pScreenPriv->current) {
- PixmapPtr oldPix = pScreenPriv->current->pPix;
- if(oldPix) {
- if(oldPix->drawable.id)
- FreeResource(oldPix->drawable.id, RT_NONE);
- else
- (*pScreen->DestroyPixmap)(oldPix);
- }
- xfree(pScreenPriv->current);
- pScreenPriv->current = NULL;
- }
-
- if(pMode->flags & DGA_PIXMAP_AVAILABLE) {
- if((pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pMode->depth, 0))) {
- (*pScreen->ModifyPixmapHeader)(pPix,
- pMode->pixmapWidth, pMode->pixmapHeight,
- pMode->depth, pMode->bitsPerPixel,
- pMode->bytesPerScanline,
- (pointer)(pMode->address));
- }
- }
-
- devRet->mode = device->mode = pMode;
- devRet->pPix = device->pPix = pPix;
- pScreenPriv->current = device;
- pScreenPriv->pixmapMode = FALSE;
- pScreenPriv->grabMouse = TRUE;
- pScreenPriv->grabKeyboard = TRUE;
-
- return Success;
-}
-
-
-
-/*********** exported ones ***************/
-
-void
-DGASetInputMode(int index, Bool keyboard, Bool mouse)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (pScreenPriv)
- {
- pScreenPriv->grabMouse = mouse;
- pScreenPriv->grabKeyboard = keyboard;
-
- if (!mieq_installed) {
- mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
- mieq_installed = 1;
- }
- }
-}
-
-Bool
-DGAChangePixmapMode(int index, int *x, int *y, int mode)
-{
- DGAScreenPtr pScreenPriv;
- DGADevicePtr pDev;
- DGAModePtr pMode;
- PixmapPtr pPix;
-
- if(DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
- return FALSE;
-
- pDev = pScreenPriv->current;
- pPix = pDev->pPix;
- pMode = pDev->mode;
-
- if(mode) {
- int shift = 2;
-
- if(*x > (pMode->pixmapWidth - pMode->viewportWidth))
- *x = pMode->pixmapWidth - pMode->viewportWidth;
- if(*y > (pMode->pixmapHeight - pMode->viewportHeight))
- *y = pMode->pixmapHeight - pMode->viewportHeight;
-
- switch(xf86Screens[index]->bitsPerPixel) {
- case 16: shift = 1; break;
- case 32: shift = 0; break;
- default: break;
- }
-
- if(BITMAP_SCANLINE_PAD == 64)
- shift++;
-
- *x = (*x >> shift) << shift;
-
- pPix->drawable.x = *x;
- pPix->drawable.y = *y;
- pPix->drawable.width = pMode->viewportWidth;
- pPix->drawable.height = pMode->viewportHeight;
- } else {
- pPix->drawable.x = 0;
- pPix->drawable.y = 0;
- pPix->drawable.width = pMode->pixmapWidth;
- pPix->drawable.height = pMode->pixmapHeight;
- }
- pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pScreenPriv->pixmapMode = mode;
-
- return TRUE;
-}
-
-Bool
-DGAAvailable(int index)
-{
- if(DGAScreenKey == NULL)
- return FALSE;
-
- if(DGA_GET_SCREEN_PRIV(screenInfo.screens[index]))
- return TRUE;
-
- return FALSE;
-}
-
-Bool
-DGAActive(int index)
-{
- DGAScreenPtr pScreenPriv;
-
- if(DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(pScreenPriv && pScreenPriv->current)
- return TRUE;
-
- return FALSE;
-}
-
-
-
-/* Called by the event code in case the server is abruptly terminated */
-
-void
-DGAShutdown(void)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- if(DGAScreenKey == NULL)
- return;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- pScrn = xf86Screens[i];
-
- (void)(*pScrn->SetDGAMode)(pScrn->scrnIndex, 0, NULL);
- }
-}
-
-/* Called by the extension to initialize a mode */
-
-int
-DGASetMode(
- int index,
- int num,
- XDGAModePtr mode,
- PixmapPtr *pPix
-){
- ScrnInfoPtr pScrn = xf86Screens[index];
- DGADeviceRec device;
- int ret;
-
- /* We rely on the extension to check that DGA is available */
-
- ret = (*pScrn->SetDGAMode)(index, num, &device);
- if((ret == Success) && num) {
- DGACopyModeInfo(device.mode, mode);
- *pPix = device.pPix;
- }
-
- return ret;
-}
-
-/* Called from the extension to let the DDX know which events are requested */
-
-void
-DGASelectInput(
- int index,
- ClientPtr client,
- long mask
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
- pScreenPriv->client = client;
- pScreenPriv->input = mask;
-}
-
-int
-DGAGetViewportStatus(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if (!pScreenPriv->funcs->GetViewport)
- return 0;
-
- return (*pScreenPriv->funcs->GetViewport)(pScreenPriv->pScrn);
-}
-
-int
-DGASetViewport(
- int index,
- int x, int y,
- int mode
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if (pScreenPriv->funcs->SetViewport)
- (*pScreenPriv->funcs->SetViewport)(pScreenPriv->pScrn, x, y, mode);
- return Success;
-}
-
-
-static int
-BitsClear(CARD32 data)
-{
- int bits = 0;
- CARD32 mask;
-
- for(mask = 1; mask; mask <<= 1) {
- if(!(data & mask)) bits++;
- else break;
- }
-
- return bits;
-}
-
-int
-DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- FakedVisualList *fvlp;
- VisualPtr pVisual;
- DGAModePtr pMode;
- ColormapPtr pmap;
-
- if(!mode || (mode > pScreenPriv->numModes))
- return BadValue;
-
- if((alloc != AllocNone) && (alloc != AllocAll))
- return BadValue;
-
- pMode = &(pScreenPriv->modes[mode - 1]);
-
- if(!(pVisual = xalloc(sizeof(VisualRec))))
- return BadAlloc;
-
- pVisual->vid = FakeClientID(0);
- pVisual->class = pMode->visualClass;
- pVisual->nplanes = pMode->depth;
- pVisual->ColormapEntries = 1 << pMode->depth;
- pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
-
- switch (pVisual->class) {
- case PseudoColor:
- case GrayScale:
- case StaticGray:
- pVisual->bitsPerRGBValue = 8; /* not quite */
- pVisual->redMask = 0;
- pVisual->greenMask = 0;
- pVisual->blueMask = 0;
- pVisual->offsetRed = 0;
- pVisual->offsetGreen = 0;
- pVisual->offsetBlue = 0;
- break;
- case DirectColor:
- case TrueColor:
- pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
- /* fall through */
- case StaticColor:
- pVisual->redMask = pMode->red_mask;
- pVisual->greenMask = pMode->green_mask;
- pVisual->blueMask = pMode->blue_mask;
- pVisual->offsetRed = BitsClear(pVisual->redMask);
- pVisual->offsetGreen = BitsClear(pVisual->greenMask);
- pVisual->offsetBlue = BitsClear(pVisual->blueMask);
- }
-
- if(!(fvlp = xalloc(sizeof(FakedVisualList)))) {
- xfree(pVisual);
- return BadAlloc;
- }
-
- fvlp->free = FALSE;
- fvlp->pVisual = pVisual;
- fvlp->next = pScreenPriv->fakedVisuals;
- pScreenPriv->fakedVisuals = fvlp;
-
- LEGAL_NEW_RESOURCE(id, client);
-
- return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
-}
-
-/* Called by the extension to install a colormap on DGA active screens */
-
-void
-DGAInstallCmap(ColormapPtr cmap)
-{
- ScreenPtr pScreen = cmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* We rely on the extension to check that DGA is active */
-
- if(!pScreenPriv->dgaColormap)
- pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
-
- pScreenPriv->dgaColormap = cmap;
-
- (*pScreen->InstallColormap)(cmap);
-}
-
-int
-DGASync(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if (pScreenPriv->funcs->Sync)
- (*pScreenPriv->funcs->Sync)(pScreenPriv->pScrn);
-
- return Success;
-}
-
-int
-DGAFillRect(
- int index,
- int x, int y, int w, int h,
- unsigned long color
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->FillRect &&
- (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
-
- (*pScreenPriv->funcs->FillRect)(pScreenPriv->pScrn, x, y, w, h, color);
- return Success;
- }
- return BadMatch;
-}
-
-int
-DGABlitRect(
- int index,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->BlitRect &&
- (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
-
- (*pScreenPriv->funcs->BlitRect)(pScreenPriv->pScrn,
- srcx, srcy, w, h, dstx, dsty);
- return Success;
- }
- return BadMatch;
-}
-
-int
-DGABlitTransRect(
- int index,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty,
- unsigned long color
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->BlitTransRect &&
- (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
-
- (*pScreenPriv->funcs->BlitTransRect)(pScreenPriv->pScrn,
- srcx, srcy, w, h, dstx, dsty, color);
- return Success;
- }
- return BadMatch;
-}
-
-
-int
-DGAGetModes(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- /* We rely on the extension to check that DGA is available */
-
- return pScreenPriv->numModes;
-}
-
-
-int
-DGAGetModeInfo(
- int index,
- XDGAModePtr mode,
- int num
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- /* We rely on the extension to check that DGA is available */
-
- if((num <= 0) || (num > pScreenPriv->numModes))
- return BadValue;
-
- DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
-
- return Success;
-}
-
-
-static void
-DGACopyModeInfo(
- DGAModePtr mode,
- XDGAModePtr xmode
-){
- DisplayModePtr dmode = mode->mode;
-
- xmode->num = mode->num;
- xmode->name = dmode->name;
- xmode->VSync_num = (int)(dmode->VRefresh * 1000.0);
- xmode->VSync_den = 1000;
- xmode->flags = mode->flags;
- xmode->imageWidth = mode->imageWidth;
- xmode->imageHeight = mode->imageHeight;
- xmode->pixmapWidth = mode->pixmapWidth;
- xmode->pixmapHeight = mode->pixmapHeight;
- xmode->bytesPerScanline = mode->bytesPerScanline;
- xmode->byteOrder = mode->byteOrder;
- xmode->depth = mode->depth;
- xmode->bitsPerPixel = mode->bitsPerPixel;
- xmode->red_mask = mode->red_mask;
- xmode->green_mask = mode->green_mask;
- xmode->blue_mask = mode->blue_mask;
- xmode->visualClass = mode->visualClass;
- xmode->viewportWidth = mode->viewportWidth;
- xmode->viewportHeight = mode->viewportHeight;
- xmode->xViewportStep = mode->xViewportStep;
- xmode->yViewportStep = mode->yViewportStep;
- xmode->maxViewportX = mode->maxViewportX;
- xmode->maxViewportY = mode->maxViewportY;
- xmode->viewportFlags = mode->viewportFlags;
- xmode->reserved1 = mode->reserved1;
- xmode->reserved2 = mode->reserved2;
- xmode->offset = mode->offset;
-
- if(dmode->Flags & V_INTERLACE) xmode->flags |= DGA_INTERLACED;
- if(dmode->Flags & V_DBLSCAN) xmode->flags |= DGA_DOUBLESCAN;
-}
-
-
-Bool
-DGAVTSwitch(void)
-{
- ScreenPtr pScreen;
- int i;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
-
- /* Alternatively, this could send events to DGA clients */
-
- if(DGAScreenKey) {
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv && pScreenPriv->current)
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-Bool
-DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if(DGAScreenKey == NULL) /* no DGA */
- return FALSE;
-
- if (key_code < 8 || key_code > 255)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
- return FALSE;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
- event.detail = key_code;
- event.dx = 0;
- event.dy = 0;
- mieqEnqueue (dev, (InternalEvent*)&event);
-
- return TRUE;
-}
-
-static int DGAMouseX, DGAMouseY;
-
-Bool
-DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if(DGAScreenKey == NULL) /* no DGA */
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */
- return FALSE;
-
- DGAMouseX += dx;
- if (DGAMouseX < 0)
- DGAMouseX = 0;
- else if (DGAMouseX > screenInfo.screens[index]->width)
- DGAMouseX = screenInfo.screens[index]->width;
- DGAMouseY += dy;
- if (DGAMouseY < 0)
- DGAMouseY = 0;
- else if (DGAMouseY > screenInfo.screens[index]->height)
- DGAMouseY = screenInfo.screens[index]->height;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = ET_Motion;
- event.detail = 0;
- event.dx = dx;
- event.dy = dy;
- mieqEnqueue (dev, (InternalEvent*)&event);
- return TRUE;
-}
-
-Bool
-DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if (DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if (!pScreenPriv || !pScreenPriv->grabMouse)
- return FALSE;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
- event.detail = button;
- event.dx = 0;
- event.dy = 0;
- mieqEnqueue (dev, (InternalEvent*)&event);
-
- return TRUE;
-}
-
-/* We have the power to steal or modify events that are about to get queued */
-
-Bool
-DGAIsDgaEvent (xEvent *e)
-{
- int coreEquiv;
- if (DGAScreenKey == NULL || XDGAEventBase == 0)
- return FALSE;
- coreEquiv = e->u.u.type - *XDGAEventBase;
- if (KeyPress <= coreEquiv && coreEquiv <= MotionNotify)
- return TRUE;
- return FALSE;
-}
-
-#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
-static Mask filters[] =
-{
- NoSuchEvent, /* 0 */
- NoSuchEvent, /* 1 */
- KeyPressMask, /* KeyPress */
- KeyReleaseMask, /* KeyRelease */
- ButtonPressMask, /* ButtonPress */
- ButtonReleaseMask, /* ButtonRelease */
- PointerMotionMask, /* MotionNotify (initial state) */
-};
-
-static void
-DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
-{
- KeyClassPtr keyc = keybd->key;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- DeviceIntPtr pointer = GetPairedDevice(keybd);
- DeviceEvent ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.length = sizeof(ev);
- ev.detail.key = event->detail;
- ev.type = event->subtype;
- ev.root_x = 0;
- ev.root_y = 0;
- ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
- ev.corestate |= pointer->button->state;
-
- UpdateDeviceState(keybd, &ev);
-
- /*
- * Deliver the DGA event
- */
- if (pScreenPriv->client)
- {
- dgaEvent de;
- de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
- de.u.u.detail = event->detail;
- de.u.event.time = event->time;
- de.u.event.dx = 0;
- de.u.event.dy = 0;
- de.u.event.screen = pScreen->myNum;
- de.u.event.state = ev.corestate;
-
- /* If the DGA client has selected input, then deliver based on the usual filter */
- TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
- filters[ev.type], pScreenPriv->input, 0);
- }
- else
- {
- /* If the keyboard is actively grabbed, deliver a grabbed core event */
- if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
- {
- ev.detail.key = event->detail;
- ev.time = event->time;
- ev.root_x = event->dx;
- ev.root_y = event->dy;
- ev.corestate = event->state;
- ev.deviceid = keybd->id;
- DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
- }
- }
-}
-
-static void
-DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
-{
- ButtonClassPtr butc = mouse->button;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- DeviceEvent ev;
- DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
-
- memset(&ev, 0, sizeof(ev));
- ev.header = ET_Internal;
- ev.length = sizeof(ev);
- ev.type = event->subtype;
- ev.corestate = butc->state;
- if (master && master->key)
- ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
-
- UpdateDeviceState(mouse, &ev);
-
- /*
- * Deliver the DGA event
- */
- if (pScreenPriv->client)
- {
- dgaEvent de;
- int coreEquiv;
-
- coreEquiv = GetCoreType((InternalEvent*)&ev);
-
- de.u.u.type = *XDGAEventBase + coreEquiv;
- de.u.u.detail = event->detail;
- de.u.event.time = event->time;
- de.u.event.dx = 0;
- de.u.event.dy = 0;
- de.u.event.screen = pScreen->myNum;
- de.u.event.state = ev.corestate;
-
- /* If the DGA client has selected input, then deliver based on the usual filter */
- TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
- filters[coreEquiv], pScreenPriv->input, 0);
- }
- else
- {
- /* If the pointer is actively grabbed, deliver a grabbed core event */
- if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
- {
- ev.detail.button = event->detail;
- ev.time = event->time;
- ev.root_x = event->dx;
- ev.root_y = event->dy;
- ev.corestate = event->state;
- DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
- }
- }
-}
-
-Bool
-DGAOpenFramebuffer(
- int index,
- char **name,
- unsigned char **mem,
- int *size,
- int *offset,
- int *flags
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
-
- return (*pScreenPriv->funcs->OpenFramebuffer)(pScreenPriv->pScrn,
- name, mem, size, offset, flags);
-}
-
-void
-DGACloseFramebuffer(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
- if(pScreenPriv->funcs->CloseFramebuffer)
- (*pScreenPriv->funcs->CloseFramebuffer)(pScreenPriv->pScrn);
-}
-
-/* For DGA 1.0 backwards compatibility only */
-
-int
-DGAGetOldDGAMode(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- ScrnInfoPtr pScrn = pScreenPriv->pScrn;
- DGAModePtr mode;
- int i, w, h, p;
-
- /* We rely on the extension to check that DGA is available */
-
- w = pScrn->currentMode->HDisplay;
- h = pScrn->currentMode->VDisplay;
- p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
-
- for(i = 0; i < pScreenPriv->numModes; i++) {
- mode = &(pScreenPriv->modes[i]);
-
- if((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
- (mode->bytesPerScanline == p) &&
- (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
- (mode->depth == pScrn->depth)) {
-
- return mode->num;
- }
- }
-
- return 0;
-}
-
-static void
-DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
- DGAEvent *event= &ev->dga_event;
- ScreenPtr pScreen = screenInfo.screens[screen_num];
- DGAScreenPtr pScreenPriv;
-
- /* no DGA */
- if (DGAScreenKey == NULL || XDGAEventBase == 0)
- return;
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* DGA not initialized on this screen */
- if (!pScreenPriv)
- return;
-
- switch (event->subtype) {
- case KeyPress:
- case KeyRelease:
- DGAProcessKeyboardEvent (pScreen, event, device);
- break;
- case MotionNotify:
- case ButtonPress:
- case ButtonRelease:
- DGAProcessPointerEvent (pScreen, event, device);
- break;
- default:
- break;
- }
-}
+/*
+ * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ *
+ * Written by Mark Vojkovich
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Priv.h"
+#include "dgaproc.h"
+#include <X11/extensions/xf86dgaproto.h>
+#include "colormapst.h"
+#include "pixmapstr.h"
+#include "inputstr.h"
+#include "globals.h"
+#include "servermd.h"
+#include "micmap.h"
+#include "xkbsrv.h"
+#include "xf86Xinput.h"
+#include "exglobals.h"
+#include "exevents.h"
+#include "eventstr.h"
+#include "eventconvert.h"
+
+#include "mi.h"
+
+static int DGAScreenKeyIndex;
+static DevPrivateKey DGAScreenKey;
+static int mieq_installed = 0;
+
+static Bool DGACloseScreen(int i, ScreenPtr pScreen);
+static void DGADestroyColormap(ColormapPtr pmap);
+static void DGAInstallColormap(ColormapPtr pmap);
+static void DGAUninstallColormap(ColormapPtr pmap);
+static void DGAHandleEvent(int screen_num, InternalEvent *event,
+ DeviceIntPtr device);
+
+static void
+DGACopyModeInfo(
+ DGAModePtr mode,
+ XDGAModePtr xmode
+);
+
+int *XDGAEventBase = NULL;
+
+#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, DGAScreenKey))
+
+
+typedef struct _FakedVisualList{
+ Bool free;
+ VisualPtr pVisual;
+ struct _FakedVisualList *next;
+} FakedVisualList;
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ int numModes;
+ DGAModePtr modes;
+ CloseScreenProcPtr CloseScreen;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ UninstallColormapProcPtr UninstallColormap;
+ DGADevicePtr current;
+ DGAFunctionPtr funcs;
+ int input;
+ ClientPtr client;
+ int pixmapMode;
+ FakedVisualList *fakedVisuals;
+ ColormapPtr dgaColormap;
+ ColormapPtr savedColormap;
+ Bool grabMouse;
+ Bool grabKeyboard;
+} DGAScreenRec, *DGAScreenPtr;
+
+Bool
+DGAInit(
+ ScreenPtr pScreen,
+ DGAFunctionPtr funcs,
+ DGAModePtr modes,
+ int num
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DGAScreenPtr pScreenPriv;
+ int i;
+
+ if(!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
+ return FALSE;
+
+ if(!modes || num <= 0)
+ return FALSE;
+
+ DGAScreenKey = &DGAScreenKeyIndex;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (!pScreenPriv)
+ {
+ if(!(pScreenPriv = (DGAScreenPtr)malloc(sizeof(DGAScreenRec))))
+ return FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DGAScreenKey, pScreenPriv);
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = DGACloseScreen;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreen->DestroyColormap = DGADestroyColormap;
+ pScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = DGAInstallColormap;
+ pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
+ pScreen->UninstallColormap = DGAUninstallColormap;
+ }
+
+ pScreenPriv->pScrn = pScrn;
+ pScreenPriv->numModes = num;
+ pScreenPriv->modes = modes;
+ pScreenPriv->current = NULL;
+
+ pScreenPriv->funcs = funcs;
+ pScreenPriv->input = 0;
+ pScreenPriv->client = NULL;
+ pScreenPriv->fakedVisuals = NULL;
+ pScreenPriv->dgaColormap = NULL;
+ pScreenPriv->savedColormap = NULL;
+ pScreenPriv->grabMouse = FALSE;
+ pScreenPriv->grabKeyboard = FALSE;
+
+ for(i = 0; i < num; i++)
+ modes[i].num = i + 1;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ for(i = 0; i < num; i++)
+ modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
+#endif
+
+ return TRUE;
+}
+
+/* DGAReInitModes allows the driver to re-initialize
+ * the DGA mode list.
+ */
+
+Bool
+DGAReInitModes(
+ ScreenPtr pScreen,
+ DGAModePtr modes,
+ int num
+){
+ DGAScreenPtr pScreenPriv;
+ int i;
+
+ /* No DGA? Ignore call (but don't make it look like it failed) */
+ if(DGAScreenKey == NULL)
+ return TRUE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* Same as above */
+ if(!pScreenPriv)
+ return TRUE;
+
+ /* Can't do this while DGA is active */
+ if(pScreenPriv->current)
+ return FALSE;
+
+ /* Quick sanity check */
+ if(!num)
+ modes = NULL;
+ else if(!modes)
+ num = 0;
+
+ pScreenPriv->numModes = num;
+ pScreenPriv->modes = modes;
+
+ /* This practically disables DGA. So be it. */
+ if(!num)
+ return TRUE;
+
+ for(i = 0; i < num; i++)
+ modes[i].num = i + 1;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ for(i = 0; i < num; i++)
+ modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
+#endif
+
+ return TRUE;
+}
+
+static void
+FreeMarkedVisuals(ScreenPtr pScreen)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ FakedVisualList *prev, *curr, *tmp;
+
+ if(!pScreenPriv->fakedVisuals)
+ return;
+
+ prev = NULL;
+ curr = pScreenPriv->fakedVisuals;
+
+ while(curr) {
+ if(curr->free) {
+ tmp = curr;
+ curr = curr->next;
+ if(prev)
+ prev->next = curr;
+ else
+ pScreenPriv->fakedVisuals = curr;
+ free(tmp->pVisual);
+ free(tmp);
+ } else {
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+}
+
+static Bool
+DGACloseScreen(int i, ScreenPtr pScreen)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (XDGAEventBase) {
+ mieqSetHandler(ET_DGAEvent, NULL);
+ }
+
+ FreeMarkedVisuals(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
+
+ /* DGAShutdown() should have ensured that no DGA
+ screen were active by here */
+
+ free(pScreenPriv);
+
+ return((*pScreen->CloseScreen)(i, pScreen));
+}
+
+
+static void
+DGADestroyColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ VisualPtr pVisual = pmap->pVisual;
+
+ if(pScreenPriv->fakedVisuals) {
+ FakedVisualList *curr = pScreenPriv->fakedVisuals;
+
+ while(curr) {
+ if(curr->pVisual == pVisual) {
+ /* We can't get rid of them yet since FreeColormap
+ still needs the pVisual during the cleanup */
+ curr->free = TRUE;
+ break;
+ }
+ curr = curr->next;
+ }
+ }
+
+ if(pScreenPriv->DestroyColormap) {
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ (*pScreen->DestroyColormap)(pmap);
+ pScreen->DestroyColormap = DGADestroyColormap;
+ }
+}
+
+
+static void
+DGAInstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv->current && pScreenPriv->dgaColormap) {
+ if (pmap != pScreenPriv->dgaColormap) {
+ pScreenPriv->savedColormap = pmap;
+ pmap = pScreenPriv->dgaColormap;
+ }
+ }
+
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ (*pScreen->InstallColormap)(pmap);
+ pScreen->InstallColormap = DGAInstallColormap;
+}
+
+static void
+DGAUninstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv->current && pScreenPriv->dgaColormap) {
+ if (pmap == pScreenPriv->dgaColormap) {
+ pScreenPriv->dgaColormap = NULL;
+ }
+ }
+
+ pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
+ (*pScreen->UninstallColormap)(pmap);
+ pScreen->UninstallColormap = DGAUninstallColormap;
+}
+
+int
+xf86SetDGAMode(
+ int index,
+ int num,
+ DGADevicePtr devRet
+){
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv;
+ ScrnInfoPtr pScrn;
+ DGADevicePtr device;
+ PixmapPtr pPix = NULL;
+ DGAModePtr pMode = NULL;
+
+ /* First check if DGAInit was successful on this screen */
+ if (DGAScreenKey == NULL)
+ return BadValue;
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ if (!pScreenPriv)
+ return BadValue;
+ pScrn = pScreenPriv->pScrn;
+
+ if(!num) {
+ if(pScreenPriv->current) {
+ PixmapPtr oldPix = pScreenPriv->current->pPix;
+ if(oldPix) {
+ if(oldPix->drawable.id)
+ FreeResource(oldPix->drawable.id, RT_NONE);
+ else
+ (*pScreen->DestroyPixmap)(oldPix);
+ }
+ free(pScreenPriv->current);
+ pScreenPriv->current = NULL;
+ pScrn->vtSema = TRUE;
+ (*pScreenPriv->funcs->SetMode)(pScrn, NULL);
+ if(pScreenPriv->savedColormap) {
+ (*pScreen->InstallColormap)(pScreenPriv->savedColormap);
+ pScreenPriv->savedColormap = NULL;
+ }
+ pScreenPriv->dgaColormap = NULL;
+ (*pScrn->EnableDisableFBAccess)(index, TRUE);
+
+ FreeMarkedVisuals(pScreen);
+ }
+
+ pScreenPriv->grabMouse = FALSE;
+ pScreenPriv->grabKeyboard = FALSE;
+
+ return Success;
+ }
+
+ if(!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */
+ return BadAlloc;
+
+ if((num > 0) && (num <= pScreenPriv->numModes))
+ pMode = &(pScreenPriv->modes[num - 1]);
+ else
+ return BadValue;
+
+ if(!(device = (DGADevicePtr)malloc(sizeof(DGADeviceRec))))
+ return BadAlloc;
+
+ if(!pScreenPriv->current) {
+ Bool oldVTSema = pScrn->vtSema;
+
+ pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */
+ (*pScrn->EnableDisableFBAccess)(index, FALSE);
+ pScrn->vtSema = oldVTSema;
+ }
+
+ if(!(*pScreenPriv->funcs->SetMode)(pScrn, pMode)) {
+ free(device);
+ return BadAlloc;
+ }
+
+ pScrn->currentMode = pMode->mode;
+
+ if(!pScreenPriv->current && !pScreenPriv->input) {
+ /* if it's multihead we need to warp the cursor off of
+ our screen so it doesn't get trapped */
+ }
+
+ pScrn->vtSema = FALSE;
+
+ if(pScreenPriv->current) {
+ PixmapPtr oldPix = pScreenPriv->current->pPix;
+ if(oldPix) {
+ if(oldPix->drawable.id)
+ FreeResource(oldPix->drawable.id, RT_NONE);
+ else
+ (*pScreen->DestroyPixmap)(oldPix);
+ }
+ free(pScreenPriv->current);
+ pScreenPriv->current = NULL;
+ }
+
+ if(pMode->flags & DGA_PIXMAP_AVAILABLE) {
+ if((pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pMode->depth, 0))) {
+ (*pScreen->ModifyPixmapHeader)(pPix,
+ pMode->pixmapWidth, pMode->pixmapHeight,
+ pMode->depth, pMode->bitsPerPixel,
+ pMode->bytesPerScanline,
+ (pointer)(pMode->address));
+ }
+ }
+
+ devRet->mode = device->mode = pMode;
+ devRet->pPix = device->pPix = pPix;
+ pScreenPriv->current = device;
+ pScreenPriv->pixmapMode = FALSE;
+ pScreenPriv->grabMouse = TRUE;
+ pScreenPriv->grabKeyboard = TRUE;
+
+ return Success;
+}
+
+
+
+/*********** exported ones ***************/
+
+void
+DGASetInputMode(int index, Bool keyboard, Bool mouse)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (pScreenPriv)
+ {
+ pScreenPriv->grabMouse = mouse;
+ pScreenPriv->grabKeyboard = keyboard;
+
+ if (!mieq_installed) {
+ mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
+ mieq_installed = 1;
+ }
+ }
+}
+
+Bool
+DGAChangePixmapMode(int index, int *x, int *y, int mode)
+{
+ DGAScreenPtr pScreenPriv;
+ DGADevicePtr pDev;
+ DGAModePtr pMode;
+ PixmapPtr pPix;
+
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
+ return FALSE;
+
+ pDev = pScreenPriv->current;
+ pPix = pDev->pPix;
+ pMode = pDev->mode;
+
+ if(mode) {
+ int shift = 2;
+
+ if(*x > (pMode->pixmapWidth - pMode->viewportWidth))
+ *x = pMode->pixmapWidth - pMode->viewportWidth;
+ if(*y > (pMode->pixmapHeight - pMode->viewportHeight))
+ *y = pMode->pixmapHeight - pMode->viewportHeight;
+
+ switch(xf86Screens[index]->bitsPerPixel) {
+ case 16: shift = 1; break;
+ case 32: shift = 0; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ shift++;
+
+ *x = (*x >> shift) << shift;
+
+ pPix->drawable.x = *x;
+ pPix->drawable.y = *y;
+ pPix->drawable.width = pMode->viewportWidth;
+ pPix->drawable.height = pMode->viewportHeight;
+ } else {
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->drawable.width = pMode->pixmapWidth;
+ pPix->drawable.height = pMode->pixmapHeight;
+ }
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pScreenPriv->pixmapMode = mode;
+
+ return TRUE;
+}
+
+Bool
+DGAAvailable(int index)
+{
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ if(DGA_GET_SCREEN_PRIV(screenInfo.screens[index]))
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+DGAActive(int index)
+{
+ DGAScreenPtr pScreenPriv;
+
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(pScreenPriv && pScreenPriv->current)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+/* Called by the event code in case the server is abruptly terminated */
+
+void
+DGAShutdown(void)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ if(DGAScreenKey == NULL)
+ return;
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScrn = xf86Screens[i];
+
+ (void)(*pScrn->SetDGAMode)(pScrn->scrnIndex, 0, NULL);
+ }
+}
+
+/* Called by the extension to initialize a mode */
+
+int
+DGASetMode(
+ int index,
+ int num,
+ XDGAModePtr mode,
+ PixmapPtr *pPix
+){
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ DGADeviceRec device;
+ int ret;
+
+ /* We rely on the extension to check that DGA is available */
+
+ ret = (*pScrn->SetDGAMode)(index, num, &device);
+ if((ret == Success) && num) {
+ DGACopyModeInfo(device.mode, mode);
+ *pPix = device.pPix;
+ }
+
+ return ret;
+}
+
+/* Called from the extension to let the DDX know which events are requested */
+
+void
+DGASelectInput(
+ int index,
+ ClientPtr client,
+ long mask
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+ pScreenPriv->client = client;
+ pScreenPriv->input = mask;
+}
+
+int
+DGAGetViewportStatus(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if (!pScreenPriv->funcs->GetViewport)
+ return 0;
+
+ return (*pScreenPriv->funcs->GetViewport)(pScreenPriv->pScrn);
+}
+
+int
+DGASetViewport(
+ int index,
+ int x, int y,
+ int mode
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if (pScreenPriv->funcs->SetViewport)
+ (*pScreenPriv->funcs->SetViewport)(pScreenPriv->pScrn, x, y, mode);
+ return Success;
+}
+
+
+static int
+BitsClear(CARD32 data)
+{
+ int bits = 0;
+ CARD32 mask;
+
+ for(mask = 1; mask; mask <<= 1) {
+ if(!(data & mask)) bits++;
+ else break;
+ }
+
+ return bits;
+}
+
+int
+DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ FakedVisualList *fvlp;
+ VisualPtr pVisual;
+ DGAModePtr pMode;
+ ColormapPtr pmap;
+
+ if(!mode || (mode > pScreenPriv->numModes))
+ return BadValue;
+
+ if((alloc != AllocNone) && (alloc != AllocAll))
+ return BadValue;
+
+ pMode = &(pScreenPriv->modes[mode - 1]);
+
+ if(!(pVisual = malloc(sizeof(VisualRec))))
+ return BadAlloc;
+
+ pVisual->vid = FakeClientID(0);
+ pVisual->class = pMode->visualClass;
+ pVisual->nplanes = pMode->depth;
+ pVisual->ColormapEntries = 1 << pMode->depth;
+ pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
+
+ switch (pVisual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ pVisual->bitsPerRGBValue = 8; /* not quite */
+ pVisual->redMask = 0;
+ pVisual->greenMask = 0;
+ pVisual->blueMask = 0;
+ pVisual->offsetRed = 0;
+ pVisual->offsetGreen = 0;
+ pVisual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
+ /* fall through */
+ case StaticColor:
+ pVisual->redMask = pMode->red_mask;
+ pVisual->greenMask = pMode->green_mask;
+ pVisual->blueMask = pMode->blue_mask;
+ pVisual->offsetRed = BitsClear(pVisual->redMask);
+ pVisual->offsetGreen = BitsClear(pVisual->greenMask);
+ pVisual->offsetBlue = BitsClear(pVisual->blueMask);
+ }
+
+ if(!(fvlp = malloc(sizeof(FakedVisualList)))) {
+ free(pVisual);
+ return BadAlloc;
+ }
+
+ fvlp->free = FALSE;
+ fvlp->pVisual = pVisual;
+ fvlp->next = pScreenPriv->fakedVisuals;
+ pScreenPriv->fakedVisuals = fvlp;
+
+ LEGAL_NEW_RESOURCE(id, client);
+
+ return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
+}
+
+/* Called by the extension to install a colormap on DGA active screens */
+
+void
+DGAInstallCmap(ColormapPtr cmap)
+{
+ ScreenPtr pScreen = cmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(!pScreenPriv->dgaColormap)
+ pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
+
+ pScreenPriv->dgaColormap = cmap;
+
+ (*pScreen->InstallColormap)(cmap);
+}
+
+int
+DGASync(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if (pScreenPriv->funcs->Sync)
+ (*pScreenPriv->funcs->Sync)(pScreenPriv->pScrn);
+
+ return Success;
+}
+
+int
+DGAFillRect(
+ int index,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->FillRect &&
+ (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
+
+ (*pScreenPriv->funcs->FillRect)(pScreenPriv->pScrn, x, y, w, h, color);
+ return Success;
+ }
+ return BadMatch;
+}
+
+int
+DGABlitRect(
+ int index,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->BlitRect &&
+ (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
+
+ (*pScreenPriv->funcs->BlitRect)(pScreenPriv->pScrn,
+ srcx, srcy, w, h, dstx, dsty);
+ return Success;
+ }
+ return BadMatch;
+}
+
+int
+DGABlitTransRect(
+ int index,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->BlitTransRect &&
+ (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
+
+ (*pScreenPriv->funcs->BlitTransRect)(pScreenPriv->pScrn,
+ srcx, srcy, w, h, dstx, dsty, color);
+ return Success;
+ }
+ return BadMatch;
+}
+
+
+int
+DGAGetModes(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ /* We rely on the extension to check that DGA is available */
+
+ return pScreenPriv->numModes;
+}
+
+
+int
+DGAGetModeInfo(
+ int index,
+ XDGAModePtr mode,
+ int num
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ /* We rely on the extension to check that DGA is available */
+
+ if((num <= 0) || (num > pScreenPriv->numModes))
+ return BadValue;
+
+ DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
+
+ return Success;
+}
+
+
+static void
+DGACopyModeInfo(
+ DGAModePtr mode,
+ XDGAModePtr xmode
+){
+ DisplayModePtr dmode = mode->mode;
+
+ xmode->num = mode->num;
+ xmode->name = dmode->name;
+ xmode->VSync_num = (int)(dmode->VRefresh * 1000.0);
+ xmode->VSync_den = 1000;
+ xmode->flags = mode->flags;
+ xmode->imageWidth = mode->imageWidth;
+ xmode->imageHeight = mode->imageHeight;
+ xmode->pixmapWidth = mode->pixmapWidth;
+ xmode->pixmapHeight = mode->pixmapHeight;
+ xmode->bytesPerScanline = mode->bytesPerScanline;
+ xmode->byteOrder = mode->byteOrder;
+ xmode->depth = mode->depth;
+ xmode->bitsPerPixel = mode->bitsPerPixel;
+ xmode->red_mask = mode->red_mask;
+ xmode->green_mask = mode->green_mask;
+ xmode->blue_mask = mode->blue_mask;
+ xmode->visualClass = mode->visualClass;
+ xmode->viewportWidth = mode->viewportWidth;
+ xmode->viewportHeight = mode->viewportHeight;
+ xmode->xViewportStep = mode->xViewportStep;
+ xmode->yViewportStep = mode->yViewportStep;
+ xmode->maxViewportX = mode->maxViewportX;
+ xmode->maxViewportY = mode->maxViewportY;
+ xmode->viewportFlags = mode->viewportFlags;
+ xmode->reserved1 = mode->reserved1;
+ xmode->reserved2 = mode->reserved2;
+ xmode->offset = mode->offset;
+
+ if(dmode->Flags & V_INTERLACE) xmode->flags |= DGA_INTERLACED;
+ if(dmode->Flags & V_DBLSCAN) xmode->flags |= DGA_DOUBLESCAN;
+}
+
+
+Bool
+DGAVTSwitch(void)
+{
+ ScreenPtr pScreen;
+ int i;
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+
+ /* Alternatively, this could send events to DGA clients */
+
+ if(DGAScreenKey) {
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv && pScreenPriv->current)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+Bool
+DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if(DGAScreenKey == NULL) /* no DGA */
+ return FALSE;
+
+ if (key_code < 8 || key_code > 255)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
+ return FALSE;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
+ event.detail = key_code;
+ event.dx = 0;
+ event.dy = 0;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+
+ return TRUE;
+}
+
+static int DGAMouseX, DGAMouseY;
+
+Bool
+DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if(DGAScreenKey == NULL) /* no DGA */
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */
+ return FALSE;
+
+ DGAMouseX += dx;
+ if (DGAMouseX < 0)
+ DGAMouseX = 0;
+ else if (DGAMouseX > screenInfo.screens[index]->width)
+ DGAMouseX = screenInfo.screens[index]->width;
+ DGAMouseY += dy;
+ if (DGAMouseY < 0)
+ DGAMouseY = 0;
+ else if (DGAMouseY > screenInfo.screens[index]->height)
+ DGAMouseY = screenInfo.screens[index]->height;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = ET_Motion;
+ event.detail = 0;
+ event.dx = dx;
+ event.dy = dy;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+ return TRUE;
+}
+
+Bool
+DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if (DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if (!pScreenPriv || !pScreenPriv->grabMouse)
+ return FALSE;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
+ event.detail = button;
+ event.dx = 0;
+ event.dy = 0;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+
+ return TRUE;
+}
+
+/* We have the power to steal or modify events that are about to get queued */
+
+Bool
+DGAIsDgaEvent (xEvent *e)
+{
+ int coreEquiv;
+ if (DGAScreenKey == NULL || XDGAEventBase == 0)
+ return FALSE;
+ coreEquiv = e->u.u.type - *XDGAEventBase;
+ if (KeyPress <= coreEquiv && coreEquiv <= MotionNotify)
+ return TRUE;
+ return FALSE;
+}
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+static Mask filters[] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+};
+
+static void
+DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
+{
+ KeyClassPtr keyc = keybd->key;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ DeviceIntPtr pointer = GetPairedDevice(keybd);
+ DeviceEvent ev;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.length = sizeof(ev);
+ ev.detail.key = event->detail;
+ ev.type = event->subtype;
+ ev.root_x = 0;
+ ev.root_y = 0;
+ ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+ ev.corestate |= pointer->button->state;
+
+ UpdateDeviceState(keybd, &ev);
+
+ /*
+ * Deliver the DGA event
+ */
+ if (pScreenPriv->client)
+ {
+ dgaEvent de;
+ de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
+ de.u.u.detail = event->detail;
+ de.u.event.time = event->time;
+ de.u.event.dx = 0;
+ de.u.event.dy = 0;
+ de.u.event.screen = pScreen->myNum;
+ de.u.event.state = ev.corestate;
+
+ /* If the DGA client has selected input, then deliver based on the usual filter */
+ TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
+ filters[ev.type], pScreenPriv->input, 0);
+ }
+ else
+ {
+ /* If the keyboard is actively grabbed, deliver a grabbed core event */
+ if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
+ {
+ ev.detail.key = event->detail;
+ ev.time = event->time;
+ ev.root_x = event->dx;
+ ev.root_y = event->dy;
+ ev.corestate = event->state;
+ ev.deviceid = keybd->id;
+ DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
+ }
+ }
+}
+
+static void
+DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
+{
+ ButtonClassPtr butc = mouse->button;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ DeviceEvent ev;
+ DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
+
+ memset(&ev, 0, sizeof(ev));
+ ev.header = ET_Internal;
+ ev.length = sizeof(ev);
+ ev.type = event->subtype;
+ ev.corestate = butc->state;
+ if (master && master->key)
+ ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
+
+ UpdateDeviceState(mouse, &ev);
+
+ /*
+ * Deliver the DGA event
+ */
+ if (pScreenPriv->client)
+ {
+ dgaEvent de;
+ int coreEquiv;
+
+ coreEquiv = GetCoreType((InternalEvent*)&ev);
+
+ de.u.u.type = *XDGAEventBase + coreEquiv;
+ de.u.u.detail = event->detail;
+ de.u.event.time = event->time;
+ de.u.event.dx = 0;
+ de.u.event.dy = 0;
+ de.u.event.screen = pScreen->myNum;
+ de.u.event.state = ev.corestate;
+
+ /* If the DGA client has selected input, then deliver based on the usual filter */
+ TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
+ filters[coreEquiv], pScreenPriv->input, 0);
+ }
+ else
+ {
+ /* If the pointer is actively grabbed, deliver a grabbed core event */
+ if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
+ {
+ ev.detail.button = event->detail;
+ ev.time = event->time;
+ ev.root_x = event->dx;
+ ev.root_y = event->dy;
+ ev.corestate = event->state;
+ DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
+ }
+ }
+}
+
+Bool
+DGAOpenFramebuffer(
+ int index,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+
+ return (*pScreenPriv->funcs->OpenFramebuffer)(pScreenPriv->pScrn,
+ name, mem, size, offset, flags);
+}
+
+void
+DGACloseFramebuffer(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+ if(pScreenPriv->funcs->CloseFramebuffer)
+ (*pScreenPriv->funcs->CloseFramebuffer)(pScreenPriv->pScrn);
+}
+
+/* For DGA 1.0 backwards compatibility only */
+
+int
+DGAGetOldDGAMode(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ ScrnInfoPtr pScrn = pScreenPriv->pScrn;
+ DGAModePtr mode;
+ int i, w, h, p;
+
+ /* We rely on the extension to check that DGA is available */
+
+ w = pScrn->currentMode->HDisplay;
+ h = pScrn->currentMode->VDisplay;
+ p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
+
+ for(i = 0; i < pScreenPriv->numModes; i++) {
+ mode = &(pScreenPriv->modes[i]);
+
+ if((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
+ (mode->bytesPerScanline == p) &&
+ (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
+ (mode->depth == pScrn->depth)) {
+
+ return mode->num;
+ }
+ }
+
+ return 0;
+}
+
+static void
+DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+ DGAEvent *event= &ev->dga_event;
+ ScreenPtr pScreen = screenInfo.screens[screen_num];
+ DGAScreenPtr pScreenPriv;
+
+ /* no DGA */
+ if (DGAScreenKey == NULL || XDGAEventBase == 0)
+ return;
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* DGA not initialized on this screen */
+ if (!pScreenPriv)
+ return;
+
+ switch (event->subtype) {
+ case KeyPress:
+ case KeyRelease:
+ DGAProcessKeyboardEvent (pScreen, event, device);
+ break;
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ DGAProcessPointerEvent (pScreen, event, device);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/xorg-server/hw/xfree86/common/xf86DPMS.c b/xorg-server/hw/xfree86/common/xf86DPMS.c
index 22174c74e..3040cb294 100644
--- a/xorg-server/hw/xfree86/common/xf86DPMS.c
+++ b/xorg-server/hw/xfree86/common/xf86DPMS.c
@@ -1,200 +1,200 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the DPMS functions required by the extension.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-#include "xf86VGAarbiter.h"
-
-
-#ifdef DPMSExtension
-static int DPMSKeyIndex;
-static DevPrivateKey DPMSKey;
-static Bool DPMSClose(int i, ScreenPtr pScreen);
-static int DPMSCount = 0;
-#endif
-
-
-Bool
-xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
-{
-#ifdef DPMSExtension
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DPMSPtr pDPMS;
- pointer DPMSOpt;
- MessageType enabled_from;
-
- DPMSKey = &DPMSKeyIndex;
-
- if (!dixSetPrivate(&pScreen->devPrivates, DPMSKey,
- xcalloc(sizeof(DPMSRec), 1)))
- return FALSE;
-
- pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
- pScrn->DPMSSet = set;
- pDPMS->Flags = flags;
- DPMSOpt = xf86FindOption(pScrn->options, "dpms");
- if (DPMSDisabledSwitch) {
- enabled_from = X_CMDLINE;
- DPMSEnabled = FALSE;
- }
- else if (DPMSOpt) {
- enabled_from = X_CONFIG;
- DPMSEnabled = xf86CheckBoolOption(pScrn->options, "dpms", FALSE);
- xf86MarkOptionUsed(DPMSOpt);
- }
- else {
- enabled_from = X_DEFAULT;
- DPMSEnabled = TRUE;
- }
- if (DPMSEnabled)
- xf86DrvMsg(pScreen->myNum, enabled_from, "DPMS enabled\n");
- pDPMS->Enabled = DPMSEnabled;
- pDPMS->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = DPMSClose;
- DPMSCount++;
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-
-#ifdef DPMSExtension
-
-static Bool
-DPMSClose(int i, ScreenPtr pScreen)
-{
- DPMSPtr pDPMS;
-
- /* This shouldn't happen */
- if (DPMSKey == NULL)
- return FALSE;
-
- pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
-
- /* This shouldn't happen */
- if (!pDPMS)
- return FALSE;
-
- pScreen->CloseScreen = pDPMS->CloseScreen;
-
- /*
- * Turn on DPMS when shutting down. If this function can be used
- * depends on the order the driver wraps things. If this is called
- * after the driver has shut down everything the driver will have
- * to deal with this internally.
- */
- if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
- xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
- }
-
- xfree(pDPMS);
- dixSetPrivate(&pScreen->devPrivates, DPMSKey, NULL);
- if (--DPMSCount == 0)
- DPMSKey = NULL;
- return pScreen->CloseScreen(i, pScreen);
-}
-
-
-/*
- * DPMSSet --
- * Device dependent DPMS mode setting hook. This is called whenever
- * the DPMS mode is to be changed.
- */
-int
-DPMSSet(ClientPtr client, int level)
-{
- int rc, i;
- DPMSPtr pDPMS;
- ScrnInfoPtr pScrn;
-
- DPMSPowerLevel = level;
-
- if (DPMSKey == NULL)
- return Success;
-
- if (level != DPMSModeOn) {
- rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
- if (rc != Success)
- return rc;
- }
-
- /* For each screen, set the DPMS level */
- for (i = 0; i < xf86NumScreens; i++) {
- pScrn = xf86Screens[i];
- pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
- if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
- xf86VGAarbiterLock(pScrn);
- pScrn->DPMSSet(pScrn, level, 0);
- xf86VGAarbiterUnlock(pScrn);
- }
- }
- return Success;
-}
-
-
-/*
- * DPMSSupported --
- * Return TRUE if any screen supports DPMS.
- */
-Bool
-DPMSSupported(void)
-{
- int i;
- DPMSPtr pDPMS;
- ScrnInfoPtr pScrn;
-
- if (DPMSKey == NULL) {
- return FALSE;
- }
-
- /* For each screen, check if DPMS is supported */
- for (i = 0; i < xf86NumScreens; i++) {
- pScrn = xf86Screens[i];
- pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
- if (pDPMS && pScrn->DPMSSet)
- return TRUE;
- }
- return FALSE;
-}
-
-#endif /* DPMSExtension */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the DPMS functions required by the extension.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+#include "xf86VGAarbiter.h"
+
+
+#ifdef DPMSExtension
+static int DPMSKeyIndex;
+static DevPrivateKey DPMSKey;
+static Bool DPMSClose(int i, ScreenPtr pScreen);
+static int DPMSCount = 0;
+#endif
+
+
+Bool
+xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
+{
+#ifdef DPMSExtension
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DPMSPtr pDPMS;
+ pointer DPMSOpt;
+ MessageType enabled_from;
+
+ DPMSKey = &DPMSKeyIndex;
+
+ if (!dixSetPrivate(&pScreen->devPrivates, DPMSKey,
+ calloc(sizeof(DPMSRec), 1)))
+ return FALSE;
+
+ pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+ pScrn->DPMSSet = set;
+ pDPMS->Flags = flags;
+ DPMSOpt = xf86FindOption(pScrn->options, "dpms");
+ if (DPMSDisabledSwitch) {
+ enabled_from = X_CMDLINE;
+ DPMSEnabled = FALSE;
+ }
+ else if (DPMSOpt) {
+ enabled_from = X_CONFIG;
+ DPMSEnabled = xf86CheckBoolOption(pScrn->options, "dpms", FALSE);
+ xf86MarkOptionUsed(DPMSOpt);
+ }
+ else {
+ enabled_from = X_DEFAULT;
+ DPMSEnabled = TRUE;
+ }
+ if (DPMSEnabled)
+ xf86DrvMsg(pScreen->myNum, enabled_from, "DPMS enabled\n");
+ pDPMS->Enabled = DPMSEnabled;
+ pDPMS->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = DPMSClose;
+ DPMSCount++;
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+
+#ifdef DPMSExtension
+
+static Bool
+DPMSClose(int i, ScreenPtr pScreen)
+{
+ DPMSPtr pDPMS;
+
+ /* This shouldn't happen */
+ if (DPMSKey == NULL)
+ return FALSE;
+
+ pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+
+ /* This shouldn't happen */
+ if (!pDPMS)
+ return FALSE;
+
+ pScreen->CloseScreen = pDPMS->CloseScreen;
+
+ /*
+ * Turn on DPMS when shutting down. If this function can be used
+ * depends on the order the driver wraps things. If this is called
+ * after the driver has shut down everything the driver will have
+ * to deal with this internally.
+ */
+ if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
+ xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
+ }
+
+ free(pDPMS);
+ dixSetPrivate(&pScreen->devPrivates, DPMSKey, NULL);
+ if (--DPMSCount == 0)
+ DPMSKey = NULL;
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+
+/*
+ * DPMSSet --
+ * Device dependent DPMS mode setting hook. This is called whenever
+ * the DPMS mode is to be changed.
+ */
+int
+DPMSSet(ClientPtr client, int level)
+{
+ int rc, i;
+ DPMSPtr pDPMS;
+ ScrnInfoPtr pScrn;
+
+ DPMSPowerLevel = level;
+
+ if (DPMSKey == NULL)
+ return Success;
+
+ if (level != DPMSModeOn) {
+ rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
+ if (rc != Success)
+ return rc;
+ }
+
+ /* For each screen, set the DPMS level */
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScrn = xf86Screens[i];
+ pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
+ if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
+ xf86VGAarbiterLock(pScrn);
+ pScrn->DPMSSet(pScrn, level, 0);
+ xf86VGAarbiterUnlock(pScrn);
+ }
+ }
+ return Success;
+}
+
+
+/*
+ * DPMSSupported --
+ * Return TRUE if any screen supports DPMS.
+ */
+Bool
+DPMSSupported(void)
+{
+ int i;
+ DPMSPtr pDPMS;
+ ScrnInfoPtr pScrn;
+
+ if (DPMSKey == NULL) {
+ return FALSE;
+ }
+
+ /* For each screen, check if DPMS is supported */
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScrn = xf86Screens[i];
+ pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
+ if (pDPMS && pScrn->DPMSSet)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif /* DPMSExtension */
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index ee4835233..9d3a58f91 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -567,7 +567,7 @@ addInputHandler(int fd, InputHandlerProc proc, pointer data)
if (fd < 0 || !proc)
return NULL;
- ih = xcalloc(sizeof(*ih), 1);
+ ih = calloc(sizeof(*ih), 1);
if (!ih)
return NULL;
@@ -616,7 +616,7 @@ removeInputHandler(IHPtr ih)
if (ih)
p->next = ih->next;
}
- xfree(ih);
+ free(ih);
}
int
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index 1cc1526c9..4cc543fc4 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -1,2588 +1,2588 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * ... and others
- *
- * This file includes the helper functions that the server provides for
- * different drivers.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <pciaccess.h>
-#include "Pci.h"
-
-#include <X11/X.h>
-#include "os.h"
-#include "servermd.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "gcstruct.h"
-#include "loaderProcs.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "micmap.h"
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "mivalidate.h"
-#include "xf86Bus.h"
-#include "xf86Crtc.h"
-
-/* For xf86GetClocks */
-#if defined(CSRG_BASED) || defined(__GNU__)
-#define HAS_SETPRIORITY
-#include <sys/resource.h>
-#endif
-
-static int xf86ScrnInfoPrivateCount = 0;
-
-
-/* Add a pointer to a new DriverRec to xf86DriverList */
-
-void
-xf86AddDriver(DriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86DriverList == NULL)
- xf86NumDrivers = 0;
-
- xf86NumDrivers++;
- xf86DriverList = xnfrealloc(xf86DriverList,
- xf86NumDrivers * sizeof(DriverPtr));
- xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
- if (flags & HaveDriverFuncs)
- *xf86DriverList[xf86NumDrivers - 1] = *driver;
- else {
- (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
- sizeof( DriverRec ) );
- (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
- sizeof(DriverRec1));
-
- }
- xf86DriverList[xf86NumDrivers - 1]->module = module;
- xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
-}
-
-void
-xf86DeleteDriver(int drvIndex)
-{
- if (xf86DriverList[drvIndex]
- && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
- if (xf86DriverList[drvIndex]->module)
- UnloadModule(xf86DriverList[drvIndex]->module);
- xfree(xf86DriverList[drvIndex]);
- xf86DriverList[drvIndex] = NULL;
- }
-}
-
-/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
-
-void
-xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86InputDriverList == NULL)
- xf86NumInputDrivers = 0;
-
- xf86NumInputDrivers++;
- xf86InputDriverList = xnfrealloc(xf86InputDriverList,
- xf86NumInputDrivers * sizeof(InputDriverPtr));
- xf86InputDriverList[xf86NumInputDrivers - 1] =
- xnfalloc(sizeof(InputDriverRec));
- *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
- xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
- xf86InputDriverList[xf86NumInputDrivers - 1]->refCount = 0;
-}
-
-void
-xf86DeleteInputDriver(int drvIndex)
-{
- if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
- UnloadModule(xf86InputDriverList[drvIndex]->module);
- xfree(xf86InputDriverList[drvIndex]);
- xf86InputDriverList[drvIndex] = NULL;
-}
-
-InputDriverPtr
-xf86LookupInputDriver(const char *name)
-{
- int i;
-
- for (i = 0; i < xf86NumInputDrivers; i++) {
- if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
- xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
- return xf86InputDriverList[i];
- }
- return NULL;
-}
-
-InputInfoPtr
-xf86LookupInput(const char *name)
-{
- InputInfoPtr p;
-
- for (p = xf86InputDevs; p != NULL; p = p->next) {
- if (strcmp(name, p->name) == 0)
- return p;
- }
-
- return NULL;
-}
-
-/* Allocate a new ScrnInfoRec in xf86Screens */
-
-ScrnInfoPtr
-xf86AllocateScreen(DriverPtr drv, int flags)
-{
- int i;
-
- if (xf86Screens == NULL)
- xf86NumScreens = 0;
-
- i = xf86NumScreens++;
- xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
- xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
- xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
- xf86Screens[i]->origIndex = i; /* This never changes */
- xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
- xf86ScrnInfoPrivateCount);
- /*
- * EnableDisableFBAccess now gets initialized in InitOutput()
- * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
- */
-
- xf86Screens[i]->drv = drv;
- drv->refCount++;
- xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
-
- xf86Screens[i]->DriverFunc = drv->driverFunc;
-
- return xf86Screens[i];
-}
-
-
-/*
- * Remove an entry from xf86Screens. Ideally it should free all allocated
- * data. To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteScreen(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- /* First check if the screen is valid */
- if (xf86NumScreens == 0 || xf86Screens == NULL)
- return;
-
- if (scrnIndex > xf86NumScreens - 1)
- return;
-
- if (!(pScrn = xf86Screens[scrnIndex]))
- return;
-
- /* If a FreeScreen function is defined, call it here */
- if (pScrn->FreeScreen != NULL)
- pScrn->FreeScreen(scrnIndex, 0);
-
- while (pScrn->modes)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
-
- while (pScrn->modePool)
- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
- xf86OptionListFree(pScrn->options);
-
- if (pScrn->module)
- UnloadModule(pScrn->module);
-
- if (pScrn->drv)
- pScrn->drv->refCount--;
-
- if (pScrn->privates)
- xfree(pScrn->privates);
-
- xf86ClearEntityListForScreen(scrnIndex);
-
- xfree(pScrn);
-
- /* Move the other entries down, updating their scrnIndex fields */
-
- xf86NumScreens--;
-
- for (i = scrnIndex; i < xf86NumScreens; i++) {
- xf86Screens[i] = xf86Screens[i + 1];
- xf86Screens[i]->scrnIndex = i;
- /* Also need to take care of the screen layout settings */
- }
-}
-
-/*
- * Allocate a private in ScrnInfoRec.
- */
-
-int
-xf86AllocateScrnInfoPrivateIndex(void)
-{
- int idx, i;
- ScrnInfoPtr pScr;
- DevUnion *nprivs;
-
- idx = xf86ScrnInfoPrivateCount++;
- for (i = 0; i < xf86NumScreens; i++) {
- pScr = xf86Screens[i];
- nprivs = xnfrealloc(pScr->privates,
- xf86ScrnInfoPrivateCount * sizeof(DevUnion));
- /* Zero the new private */
- bzero(&nprivs[idx], sizeof(DevUnion));
- pScr->privates = nprivs;
- }
- return idx;
-}
-
-/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
-InputInfoPtr
-xf86AllocateInput(InputDriverPtr drv, int flags)
-{
- InputInfoPtr new, *prev = NULL;
-
- if (!(new = xcalloc(sizeof(InputInfoRec), 1)))
- return NULL;
-
- new->drv = drv;
- drv->refCount++;
- new->module = DuplicateModule(drv->module, NULL);
-
- for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
- ;
-
- *prev = new;
- new->next = NULL;
-
- return new;
-}
-
-
-/*
- * Remove an entry from xf86InputDevs. Ideally it should free all allocated
- * data. To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteInput(InputInfoPtr pInp, int flags)
-{
- InputInfoPtr p;
-
- /* First check if the inputdev is valid. */
- if (pInp == NULL)
- return;
-
-#if 0
- /* If a free function is defined, call it here. */
- if (pInp->free)
- pInp->free(pInp, 0);
-#endif
-
- if (pInp->module)
- UnloadModule(pInp->module);
-
- if (pInp->drv)
- pInp->drv->refCount--;
-
- /* This should *really* be handled in drv->UnInit(dev) call instead, but
- * if the driver forgets about it make sure we free it or at least crash
- * with flying colors */
- if (pInp->private)
- xfree(pInp->private);
-
- /* Remove the entry from the list. */
- if (pInp == xf86InputDevs)
- xf86InputDevs = pInp->next;
- else {
- p = xf86InputDevs;
- while (p && p->next != pInp)
- p = p->next;
- if (p)
- p->next = pInp->next;
- /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
- }
- xfree(pInp);
-}
-
-Bool
-xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
-{
- int i;
-
- if (pScrn->numFormats >= MAXFORMATS)
- return FALSE;
-
- if (bpp <= 0) {
- if (depth == 1)
- bpp = 1;
- else if (depth <= 8)
- bpp = 8;
- else if (depth <= 16)
- bpp = 16;
- else if (depth <= 32)
- bpp = 32;
- else
- return FALSE;
- }
- if (pad <= 0)
- pad = BITMAP_SCANLINE_PAD;
-
- i = pScrn->numFormats++;
- pScrn->formats[i].depth = depth;
- pScrn->formats[i].bitsPerPixel = bpp;
- pScrn->formats[i].scanlinePad = pad;
- return TRUE;
-}
-
-/*
- * Set the depth we are using based on (in the following order of preference):
- * - values given on the command line
- * - values given in the config file
- * - values provided by the driver
- * - an overall default when nothing else is given
- *
- * Also find a Display subsection matching the depth/bpp found.
- *
- * Sets the following ScrnInfoRec fields:
- * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
- * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
- * formats, fbFormat.
- */
-
-/* Can the screen handle 24 bpp pixmaps */
-#define DO_PIX24(f) ((f & Support24bppFb) || \
- ((f & Support32bppFb) && (f & SupportConvert24to32)))
-
-/* Can the screen handle 32 bpp pixmaps */
-#define DO_PIX32(f) ((f & Support32bppFb) || \
- ((f & Support24bppFb) && (f & SupportConvert32to24)))
-
-/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
-#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
- && (f & PreferConvert24to32))
-
-/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
-#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
- && (f & PreferConvert32to24))
-
-/* Can the screen handle 32bpp pixmaps for 24bpp fb */
-#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
-
-/* Can the screen handle 24bpp pixmaps for 32bpp fb */
-#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
-
-#ifndef GLOBAL_DEFAULT_DEPTH
-#define GLOBAL_DEFAULT_DEPTH 24
-#endif
-
-Bool
-xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
- int depth24flags)
-{
- int i;
- DispPtr disp;
- Pix24Flags pix24 = xf86Info.pixmap24;
- Bool nomatch = FALSE;
-
- scrp->bitsPerPixel = -1;
- scrp->depth = -1;
- scrp->pixmap24 = Pix24DontCare;
- scrp->bitsPerPixelFrom = X_DEFAULT;
- scrp->depthFrom = X_DEFAULT;
-
- if (xf86FbBpp > 0) {
- scrp->bitsPerPixel = xf86FbBpp;
- scrp->bitsPerPixelFrom = X_CMDLINE;
- }
-
- if (xf86Depth > 0) {
- scrp->depth = xf86Depth;
- scrp->depthFrom = X_CMDLINE;
- }
-
- if (xf86FbBpp < 0 && xf86Depth < 0) {
- if (scrp->confScreen->defaultfbbpp > 0) {
- scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
- scrp->bitsPerPixelFrom = X_CONFIG;
- }
- if (scrp->confScreen->defaultdepth > 0) {
- scrp->depth = scrp->confScreen->defaultdepth;
- scrp->depthFrom = X_CONFIG;
- }
-
- if (scrp->confScreen->defaultfbbpp <= 0 &&
- scrp->confScreen->defaultdepth <= 0) {
- /*
- * Check for DefaultDepth and DefaultFbBpp options in the
- * Device sections.
- */
- int i;
- GDevPtr device;
- Bool found = FALSE;
-
- for (i = 0; i < scrp->numEntities; i++) {
- device = xf86GetDevFromEntity(scrp->entityList[i],
- scrp->entityInstanceList[i]);
- if (device && device->options) {
- if (xf86FindOption(device->options, "DefaultDepth")) {
- scrp->depth = xf86SetIntOption(device->options,
- "DefaultDepth", -1);
- scrp->depthFrom = X_CONFIG;
- found = TRUE;
- }
- if (xf86FindOption(device->options, "DefaultFbBpp")) {
- scrp->bitsPerPixel = xf86SetIntOption(device->options,
- "DefaultFbBpp",
- -1);
- scrp->bitsPerPixelFrom = X_CONFIG;
- found = TRUE;
- }
- }
- if (found)
- break;
- }
- }
- }
-
- /* If none of these is set, pick a default */
- if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
- if (fbbpp > 0 || depth > 0) {
- if (fbbpp > 0)
- scrp->bitsPerPixel = fbbpp;
- if (depth > 0)
- scrp->depth = depth;
- } else {
- scrp->depth = GLOBAL_DEFAULT_DEPTH;
- }
- }
-
- /* If any are not given, determine a default for the others */
-
- if (scrp->bitsPerPixel < 0) {
- /* The depth must be set */
- if (scrp->depth > -1) {
- if (scrp->depth == 1)
- scrp->bitsPerPixel = 1;
- else if (scrp->depth <= 4)
- scrp->bitsPerPixel = 4;
- else if (scrp->depth <= 8)
- scrp->bitsPerPixel = 8;
- else if (scrp->depth <= 16)
- scrp->bitsPerPixel = 16;
- else if (scrp->depth <= 24) {
- /*
- * Figure out if a choice is possible based on the depth24
- * and pix24 flags.
- */
- /* Check pix24 first */
- if (pix24 != Pix24DontCare) {
- if (pix24 == Pix24Use32) {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else {
- nomatch = TRUE;
- }
- } else if (pix24 == Pix24Use24) {
- if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- } else {
- nomatch = TRUE;
- }
- }
- } else {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- }
- }
- } else if (scrp->depth <= 32)
- scrp->bitsPerPixel = 32;
- else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than 32\n",
- scrp->depth);
- return FALSE;
- }
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "xf86SetDepthBpp: internal error: depth and fbbpp"
- " are both not set\n");
- return FALSE;
- }
- if (scrp->bitsPerPixel < 0) {
- if (nomatch)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24 pixmap format (%d)\n",
- PIX24TOBPP(pix24));
- else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
- NoDepth24Support)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24\n");
- else
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't find fbbpp for depth 24\n");
- return FALSE;
- }
- scrp->bitsPerPixelFrom = X_PROBED;
- }
-
- if (scrp->depth <= 0) {
- /* bitsPerPixel is already set */
- switch (scrp->bitsPerPixel) {
- case 32:
- scrp->depth = 24;
- break;
- default:
- /* 1, 4, 8, 16 and 24 */
- scrp->depth = scrp->bitsPerPixel;
- break;
- }
- scrp->depthFrom = X_PROBED;
- }
-
- /* Sanity checks */
- if (scrp->depth < 1 || scrp->depth > 32) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is not in the range 1-32\n",
- scrp->depth);
- return FALSE;
- }
- switch (scrp->bitsPerPixel) {
- case 1:
- case 4:
- case 8:
- case 16:
- case 24:
- case 32:
- break;
- default:
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified fbbpp (%d) is not a permitted value\n",
- scrp->bitsPerPixel);
- return FALSE;
- }
- if (scrp->depth > scrp->bitsPerPixel) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than the fbbpp (%d)\n",
- scrp->depth, scrp->bitsPerPixel);
- return FALSE;
- }
-
- /* set scrp->pixmap24 if the driver isn't flexible */
- if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
- scrp->pixmap24 = Pix24Use24;
- }
- if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
- scrp->pixmap24 = Pix24Use32;
- }
-
- /*
- * Find the Display subsection matching the depth/fbbpp and initialise
- * scrp->display with it.
- */
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
- || (disp->depth == scrp->depth && disp->fbbpp <= 0)
- || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
- scrp->display = disp;
- break;
- }
- }
-
- /*
- * If an exact match can't be found, see if there is one with no
- * depth or fbbpp specified.
- */
- if (i == scrp->confScreen->numdisplays) {
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if (disp->depth <= 0 && disp->fbbpp <= 0) {
- scrp->display = disp;
- break;
- }
- }
- }
-
- /*
- * If all else fails, create a default one.
- */
- if (i == scrp->confScreen->numdisplays) {
- scrp->confScreen->numdisplays++;
- scrp->confScreen->displays =
- xnfrealloc(scrp->confScreen->displays,
- scrp->confScreen->numdisplays * sizeof(DispRec));
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Creating default Display subsection in Screen section\n"
- "\t\"%s\" for depth/fbbpp %d/%d\n",
- scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
- memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
- scrp->confScreen->displays[i].blackColour.red = -1;
- scrp->confScreen->displays[i].blackColour.green = -1;
- scrp->confScreen->displays[i].blackColour.blue = -1;
- scrp->confScreen->displays[i].whiteColour.red = -1;
- scrp->confScreen->displays[i].whiteColour.green = -1;
- scrp->confScreen->displays[i].whiteColour.blue = -1;
- scrp->confScreen->displays[i].defaultVisual = -1;
- scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
- scrp->confScreen->displays[i].modes[0] = NULL;
- scrp->confScreen->displays[i].depth = depth;
- scrp->confScreen->displays[i].fbbpp = fbbpp;
- scrp->display = &scrp->confScreen->displays[i];
- }
-
- /*
- * Setup defaults for the display-wide attributes the framebuffer will
- * need. These defaults should eventually be set globally, and not
- * dependent on the screens.
- */
- scrp->imageByteOrder = IMAGE_BYTE_ORDER;
- scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- if (scrp->depth < 8) {
- /* Planar modes need these settings */
- scrp->bitmapScanlineUnit = 8;
- scrp->bitmapBitOrder = MSBFirst;
- } else {
- scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
- }
-
- /*
- * If an unusual depth is required, add it to scrp->formats. The formats
- * for the common depths are handled globally in InitOutput
- */
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- case 15:
- case 16:
- case 24:
- /* Common depths. Nothing to do for them */
- break;
- default:
- if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't add pixmap format for depth %d\n", scrp->depth);
- return FALSE;
- }
- }
-
- /* Initialise the framebuffer format for this screen */
- scrp->fbFormat.depth = scrp->depth;
- scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
- scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
-
- return TRUE;
-}
-
-/*
- * Print out the selected depth and bpp.
- */
-void
-xf86PrintDepthBpp(ScrnInfoPtr scrp)
-{
- xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
- xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
-}
-
-/*
- * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
- * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
- */
-Bool
-xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
-{
- MessageType weightFrom = X_DEFAULT;
-
- scrp->weight.red = 0;
- scrp->weight.green = 0;
- scrp->weight.blue = 0;
-
- if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
- scrp->weight = xf86Weight;
- weightFrom = X_CMDLINE;
- } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
- && scrp->display->weight.blue > 0) {
- scrp->weight = scrp->display->weight;
- weightFrom = X_CONFIG;
- } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
- scrp->weight = weight;
- } else {
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- scrp->weight.red = scrp->weight.green =
- scrp->weight.blue = scrp->rgbBits;
- break;
- case 15:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
- break;
- case 16:
- scrp->weight.red = scrp->weight.blue = 5;
- scrp->weight.green = 6;
- break;
- case 24:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
- break;
- case 30:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
- break;
- }
- }
-
- if (scrp->weight.red)
- xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue);
-
- if (scrp->depth > MAX_PSEUDO_DEPTH &&
- (scrp->depth != scrp->weight.red + scrp->weight.green +
- scrp->weight.blue)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Weight given (%d%d%d) is inconsistent with the "
- "depth (%d)\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue, scrp->depth);
- return FALSE;
- }
- if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
- /*
- * XXX Does this even mean anything for TrueColor visuals?
- * If not, we shouldn't even be setting it here. However, this
- * matches the behaviour of 3.x versions of XFree86.
- */
- scrp->rgbBits = scrp->weight.red;
- if (scrp->weight.green > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.green;
- if (scrp->weight.blue > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.blue;
- }
-
- /* Set the mask and offsets */
- if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
- /* Default to a setting common to PC hardware */
- scrp->offset.red = scrp->weight.green + scrp->weight.blue;
- scrp->offset.green = scrp->weight.blue;
- scrp->offset.blue = 0;
- scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
- scrp->mask.green = ((1 << scrp->weight.green) - 1)
- << scrp->offset.green;
- scrp->mask.blue = (1 << scrp->weight.blue) - 1;
- } else {
- /* Initialise to the values passed */
- scrp->mask.red = mask.red;
- scrp->mask.green = mask.green;
- scrp->mask.blue = mask.blue;
- scrp->offset.red = ffs(mask.red);
- scrp->offset.green = ffs(mask.green);
- scrp->offset.blue = ffs(mask.blue);
- }
- return TRUE;
-}
-
-Bool
-xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
-{
- MessageType visualFrom = X_DEFAULT;
-
- if (defaultColorVisualClass >= 0) {
- scrp->defaultVisual = defaultColorVisualClass;
- visualFrom = X_CMDLINE;
- } else if (scrp->display->defaultVisual >= 0) {
- scrp->defaultVisual = scrp->display->defaultVisual;
- visualFrom = X_CONFIG;
- } else if (visual >= 0) {
- scrp->defaultVisual = visual;
- } else {
- if (scrp->depth == 1)
- scrp->defaultVisual = StaticGray;
- else if (scrp->depth == 4)
- scrp->defaultVisual = StaticColor;
- else if (scrp->depth <= MAX_PSEUDO_DEPTH)
- scrp->defaultVisual = PseudoColor;
- else
- scrp->defaultVisual = TrueColor;
- }
- switch (scrp->defaultVisual) {
- case StaticGray:
- case GrayScale:
- case StaticColor:
- case PseudoColor:
- case TrueColor:
- case DirectColor:
- xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
- xf86VisualNames[scrp->defaultVisual]);
- return TRUE;
- default:
-
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Invalid default visual class (%d)\n", scrp->defaultVisual);
- return FALSE;
- }
-}
-
-#define TEST_GAMMA(g) \
- (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
-
-#define SET_GAMMA(g) \
- (g) > GAMMA_ZERO ? (g) : 1.0
-
-Bool
-xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
-{
- MessageType from = X_DEFAULT;
-#if 0
- xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
-#endif
- if (TEST_GAMMA(xf86Gamma)) {
- from = X_CMDLINE;
- scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
- scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
- scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
- } else if (TEST_GAMMA(scrp->monitor->gamma)) {
- from = X_CONFIG;
- scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
- scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
- scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
-#if 0
- } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
- from = X_PROBED;
- scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
- /* EDID structure version 2 gives optional seperate red, green & blue gamma values
- * in bytes 0x57-0x59 */
-#endif
- } else if (TEST_GAMMA(gamma)) {
- scrp->gamma.red = SET_GAMMA(gamma.red);
- scrp->gamma.green = SET_GAMMA(gamma.green);
- scrp->gamma.blue = SET_GAMMA(gamma.blue);
- } else {
- scrp->gamma.red = 1.0;
- scrp->gamma.green = 1.0;
- scrp->gamma.blue = 1.0;
- }
- /* Pretend we succeeded if we support better a gamma system.
- * This avoids a confusing message.
- */
- if (xf86_crtc_supports_gamma(scrp))
- return TRUE;
- xf86DrvMsg(scrp->scrnIndex, from,
- "Using gamma correction (%.1f, %.1f, %.1f)\n",
- scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
-
- return TRUE;
-}
-
-#undef TEST_GAMMA
-#undef SET_GAMMA
-
-
-/*
- * Set the DPI from the command line option. XXX should allow it to be
- * calculated from the widthmm/heightmm values.
- */
-
-#undef MMPERINCH
-#define MMPERINCH 25.4
-
-void
-xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
-{
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
- int ddcWidthmm, ddcHeightmm;
- int widthErr, heightErr;
-
- /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
- pScrn->widthmm = pScrn->monitor->widthmm;
- pScrn->heightmm = pScrn->monitor->heightmm;
-
- if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
- /* DDC gives display size in mm for individual modes,
- * but cm for monitor
- */
- ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
- ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
- } else {
- ddcWidthmm = ddcHeightmm = 0;
- }
-
- if (monitorResolution > 0) {
- pScrn->xDpi = monitorResolution;
- pScrn->yDpi = monitorResolution;
- from = X_CMDLINE;
- } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
- from = X_CONFIG;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- pScrn->widthmm, pScrn->heightmm);
-
- /* Warn if config and probe disagree about display size */
- if ( ddcWidthmm && ddcHeightmm ) {
- if (pScrn->widthmm > 0) {
- widthErr = abs(ddcWidthmm - pScrn->widthmm);
- } else {
- widthErr = 0;
- }
- if (pScrn->heightmm > 0) {
- heightErr = abs(ddcHeightmm - pScrn->heightmm);
- } else {
- heightErr = 0;
- }
- if (widthErr>10 || heightErr>10) {
- /* Should include config file name for monitor here */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
- ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
- }
- }
- } else if ( ddcWidthmm && ddcHeightmm ) {
- from = X_PROBED;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- ddcWidthmm, ddcHeightmm );
- pScrn->widthmm = ddcWidthmm;
- pScrn->heightmm = ddcHeightmm;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- } else {
- if (x > 0)
- pScrn->xDpi = x;
- else
- pScrn->xDpi = DEFAULT_DPI;
- if (y > 0)
- pScrn->yDpi = y;
- else
- pScrn->yDpi = DEFAULT_DPI;
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
- pScrn->xDpi, pScrn->yDpi);
-}
-
-#undef MMPERINCH
-
-
-void
-xf86SetBlackWhitePixels(ScreenPtr pScreen)
-{
- if (xf86FlipPixels) {
- pScreen->whitePixel = 0;
- pScreen->blackPixel = 1;
- } else {
- pScreen->whitePixel = 1;
- pScreen->blackPixel = 0;
- }
-}
-
-/*
- * xf86SetRootClip --
- * Enable or disable rendering to the screen by
- * setting the root clip list and revalidating
- * all of the windows
- */
-
-static void
-xf86SetRootClip (ScreenPtr pScreen, Bool enable)
-{
- WindowPtr pWin = WindowTable[pScreen->myNum];
- WindowPtr pChild;
- Bool WasViewable = (Bool)(pWin->viewable);
- Bool anyMarked = FALSE;
- WindowPtr pLayerWin;
- BoxRec box;
-
- if (WasViewable)
- {
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- (void) (*pScreen->MarkOverlappedWindows)(pChild,
- pChild,
- &pLayerWin);
- }
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- if (pWin->valdata)
- {
- if (HasBorder (pWin))
- {
- RegionPtr borderVisible;
-
- borderVisible = REGION_CREATE(pScreen, NullBox, 1);
- REGION_SUBTRACT(pScreen, borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- }
- pWin->valdata->before.resized = TRUE;
- }
- }
-
- /*
- * Use REGION_BREAK to avoid optimizations in ValidateTree
- * that assume the root borderClip can't change well, normally
- * it doesn't...)
- */
- if (enable)
- {
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pScreen->width;
- box.y2 = pScreen->height;
- REGION_INIT (pScreen, &pWin->winSize, &box, 1);
- REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
- if (WasViewable)
- REGION_RESET(pScreen, &pWin->borderClip, &box);
- pWin->drawable.width = pScreen->width;
- pWin->drawable.height = pScreen->height;
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
- else
- {
- REGION_EMPTY(pScreen, &pWin->borderClip);
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
-
- ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
-
- if (WasViewable)
- {
- if (pWin->firstChild)
- {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
- pWin->firstChild,
- (WindowPtr *)NULL);
- }
- else
- {
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- }
-
-
- if (anyMarked)
- (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
- }
-
- if (WasViewable)
- {
- if (anyMarked)
- (*pScreen->HandleExposures)(pWin);
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
- FlushAllOutput ();
-}
-
-/*
- * Function to enable/disable access to the frame buffer
- *
- * This is used when VT switching and when entering/leaving DGA direct mode.
- *
- * This has been rewritten again to eliminate the saved pixmap. The
- * devPrivate field in the screen pixmap is set to NULL to catch code
- * accidentally referencing the frame buffer while the X server is not
- * supposed to touch it.
- *
- * Here, we exchange the pixmap private data, rather than the pixmaps
- * themselves to avoid having to find and change any references to the screen
- * pixmap such as GC's, window privates etc. This also means that this code
- * does not need to know exactly how the pixmap pixels are accessed. Further,
- * this exchange is >not< done through the screen's ModifyPixmapHeader()
- * vector. This means the called frame buffer code layers can determine
- * whether they are switched in or out by keeping track of the root pixmap's
- * private data, and therefore don't need to access pScrnInfo->vtSema.
- */
-void
-xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
-{
- ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
- ScreenPtr pScreen = pScrnInfo->pScreen;
- PixmapPtr pspix;
-
- pspix = (*pScreen->GetScreenPixmap) (pScreen);
- if (enable)
- {
- /*
- * Restore the screen pixmap devPrivate field
- */
- pspix->devPrivate = pScrnInfo->pixmapPrivate;
- /*
- * Restore all of the clip lists on the screen
- */
- if (!xf86Resetting)
- xf86SetRootClip (pScreen, TRUE);
-
- }
- else
- {
- /*
- * Empty all of the clip lists on the screen
- */
- xf86SetRootClip (pScreen, FALSE);
- /*
- * save the screen pixmap devPrivate field and
- * replace it with NULL so accidental references
- * to the frame buffer are caught
- */
- pScrnInfo->pixmapPrivate = pspix->devPrivate;
- pspix->devPrivate.ptr = NULL;
- }
-}
-
-/* Print driver messages in the standard format */
-
-#undef PREFIX_SIZE
-#define PREFIX_SIZE 14
-
-void
-xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
- va_list args)
-{
- char *tmpFormat;
-
- /* Prefix the scrnIndex name to the format string. */
- if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
- xf86Screens[scrnIndex]->name) {
- tmpFormat = xalloc(strlen(format) +
- strlen(xf86Screens[scrnIndex]->name) +
- PREFIX_SIZE + 1);
- if (!tmpFormat)
- return;
-
- snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
- xf86Screens[scrnIndex]->name, scrnIndex);
-
- strcat(tmpFormat, format);
- LogVMessageVerb(type, verb, tmpFormat, args);
- xfree(tmpFormat);
- } else
- LogVMessageVerb(type, verb, format, args);
-}
-#undef PREFIX_SIZE
-
-/* Print driver messages, with verbose level specified directly */
-void
-xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
- ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print driver messages, with verbose level of 1 (default) */
-void
-xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
- va_end(ap);
-}
-
-/* Print non-driver messages with verbose level specified directly */
-void
-xf86MsgVerb(MessageType type, int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(-1, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print non-driver messages with verbose level of 1 (default) */
-void
-xf86Msg(MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(-1, type, 1, format, ap);
- va_end(ap);
-}
-
-/* Just like ErrorF, but with the verbose level checked */
-void
-xf86ErrorFVerb(int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= verb || xf86LogVerbose >= verb)
- LogVWrite(verb, format, ap);
- va_end(ap);
-}
-
-/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
-void
-xf86ErrorF(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
- LogVWrite(1, format, ap);
- va_end(ap);
-}
-
-
-void
-xf86LogInit(void)
-{
- char *lf = NULL;
-
-#define LOGSUFFIX ".log"
-#define LOGOLDSUFFIX ".old"
-
- /* Get the log file name */
- if (xf86LogFileFrom == X_DEFAULT) {
- /* Append the display number and ".log" */
- lf = malloc(strlen(xf86LogFile) + strlen("%s") +
- strlen(LOGSUFFIX) + 1);
- if (!lf)
- FatalError("Cannot allocate space for the log file name\n");
- sprintf(lf, "%s%%s" LOGSUFFIX, xf86LogFile);
- xf86LogFile = lf;
- }
-
- xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
- xf86LogFileWasOpened = TRUE;
-
- xf86SetVerbosity(xf86Verbose);
- xf86SetLogVerbosity(xf86LogVerbose);
-
-#undef LOGSUFFIX
-#undef LOGOLDSUFFIX
-
- free(lf);
-}
-
-void
-xf86CloseLog(void)
-{
- LogClose();
-}
-
-
-/*
- * Drivers can use these for using their own SymTabRecs.
- */
-
-const char *
-xf86TokenToString(SymTabPtr table, int token)
-{
- int i;
-
- for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
- ;
-
- if (table[i].token < 0)
- return NULL;
- else
- return(table[i].name);
-}
-
-int
-xf86StringToToken(SymTabPtr table, const char *string)
-{
- int i;
-
- if (string == NULL)
- return -1;
-
- for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
- ;
-
- return(table[i].token);
-}
-
-/*
- * helper to display the clocks found on a card
- */
-void
-xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
-{
- int j;
-
- xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
- for (j=0; j < scrp->numClocks; j++) {
- if ((j % 4) == 0) {
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
- }
- xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
- }
- xf86ErrorF("\n");
-}
-
-
-/*
- * This prints out the driver identify message, including the names of
- * the supported chipsets.
- *
- * XXX This makes assumptions about the line width, etc. Maybe we could
- * use a more general "pretty print" function for messages.
- */
-void
-xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
-{
- int len, i;
-
- len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
- xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
- for (i = 0; chips[i].name != NULL; i++) {
- if (i != 0) {
- xf86ErrorF(",");
- len++;
- }
- if (len + 2 + strlen(chips[i].name) < 78) {
- xf86ErrorF(" ");
- len++;
- } else {
- xf86ErrorF("\n\t");
- len = 8;
- }
- xf86ErrorF("%s", chips[i].name);
- len += strlen(chips[i].name);
- }
- xf86ErrorF("\n");
-}
-
-
-int
-xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
-{
- GDevPtr gdp, *pgdp = NULL;
- confScreenPtr screensecptr;
- int i,j;
-
- if (sectlist)
- *sectlist = NULL;
-
- if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
-
- /*
- * This is a very important function that matches the device sections
- * as they show up in the config file with the drivers that the server
- * loads at run time.
- *
- * ChipProbe can call
- * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
- * with its driver name. The function allocates an array of GDevPtr and
- * returns this via sectlist and returns the number of elements in
- * this list as return value. 0 means none found, -1 means fatal error.
- *
- * It can figure out which of the Device sections to use for which card
- * (using things like the Card statement, etc). For single headed servers
- * there will of course be just one such Device section.
- */
- i = 0;
-
- /*
- * first we need to loop over all the Screens sections to get to all
- * 'active' device sections
- */
- for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
- screensecptr = xf86ConfigLayout.screens[j].screen;
- if ((screensecptr->device->driver != NULL)
- && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
- && (! screensecptr->device->claimed)) {
- /*
- * we have a matching driver that wasn't claimed, yet
- */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = screensecptr->device;
- }
- }
-
- /* Then handle the inactive devices */
- j = 0;
- while (xf86ConfigLayout.inactives[j].identifier) {
- gdp = &xf86ConfigLayout.inactives[j];
- if (gdp->driver && !gdp->claimed &&
- !xf86NameCmp(gdp->driver,drivername)) {
- /* we have a matching driver that wasn't claimed yet */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = gdp;
- }
- j++;
- }
-
- /*
- * make the array NULL terminated and return its address
- */
- if (i)
- pgdp[i] = NULL;
-
- if (sectlist)
- *sectlist = pgdp;
- else
- xfree(pgdp);
- return i;
-}
-
-static Bool
-pciDeviceHasBars(struct pci_device *pci)
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (pci->regions[i].size)
- return TRUE;
-
- if (pci->rom_size)
- return TRUE;
-
- return FALSE;
-}
-
-struct Inst {
- struct pci_device * pci;
- GDevPtr dev;
- Bool foundHW; /* PCIid in list of supported chipsets */
- Bool claimed; /* BusID matches with a device section */
- int chip;
- int screen;
-};
-
-
-/**
- * Find set of unclaimed devices matching a given vendor ID.
- *
- * Used by drivers to find as yet unclaimed devices matching the specified
- * vendor ID.
- *
- * \param driverName Name of the driver. This is used to find Device
- * sections in the config file.
- * \param vendorID PCI vendor ID of associated devices. If zero, then
- * the true vendor ID must be encoded in the \c PCIid
- * fields of the \c PCIchipsets entries.
- * \param chipsets Symbol table used to associate chipset names with
- * PCI IDs.
- * \param devList List of Device sections parsed from the config file.
- * \param numDevs Number of entries in \c devList.
- * \param drvp Pointer the driver's control structure.
- * \param foundEntities Returned list of entity indicies associated with the
- * driver.
- *
- * \returns
- * The number of elements in returned in \c foundEntities on success or zero
- * on failure.
- *
- * \todo
- * This function does a bit more than short description says. Fill in some
- * more of the details of its operation.
- *
- * \todo
- * The \c driverName parameter is redundant. It is the same as
- * \c DriverRec::driverName. In a future version of this function, remove
- * that parameter.
- */
-int
-xf86MatchPciInstances(const char *driverName, int vendorID,
- SymTabPtr chipsets, PciChipsets *PCIchipsets,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities)
-{
- int i,j;
- struct pci_device * pPci;
- struct pci_device_iterator *iter;
- struct Inst *instances = NULL;
- int numClaimedInstances = 0;
- int allocatedInstances = 0;
- int numFound = 0;
- SymTabRec *c;
- PciChipsets *id;
- int *retEntities = NULL;
-
- *foundEntities = NULL;
-
-
- /* Each PCI device will contribute at least one entry. Each device
- * section can contribute at most one entry. The sum of the two is
- * guaranteed to be larger than the maximum possible number of entries.
- * Do this calculation and memory allocation once now to eliminate the
- * need for realloc calls inside the loop.
- */
- if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
- unsigned max_entries = numDevs;
-
- iter = pci_slot_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- max_entries++;
- }
-
- pci_iterator_destroy(iter);
- instances = xnfalloc(max_entries * sizeof(struct Inst));
- }
-
- iter = pci_slot_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- unsigned device_class = pPci->device_class;
- Bool foundVendor = FALSE;
-
-
- /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
- * 2.0 version of the same class.
- */
- if ( device_class == 0x00000101 ) {
- device_class = 0x00030000;
- }
-
-
- /* Find PCI devices that match the given vendor ID. The vendor ID is
- * either specified explicitly as a parameter to the function or
- * implicitly encoded in the high bits of id->PCIid.
- *
- * The first device with a matching vendor is recorded, even if the
- * device ID doesn't match. This is done because the Device section
- * in the xorg.conf file can over-ride the device ID. A matching PCI
- * ID might not be found now, but after the device ID over-ride is
- * applied there /might/ be a match.
- */
- for (id = PCIchipsets; id->PCIid != -1; id++) {
- const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
- | vendorID;
- const unsigned device_id = (id->PCIid & 0x0000FFFF);
- const unsigned match_class = 0x00030000 | id->PCIid;
-
- if ((vendor_id == pPci->vendor_id)
- || ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
- if (!foundVendor && (instances != NULL)) {
- ++allocatedInstances;
- instances[allocatedInstances - 1].pci = pPci;
- instances[allocatedInstances - 1].dev = NULL;
- instances[allocatedInstances - 1].claimed = FALSE;
- instances[allocatedInstances - 1].foundHW = FALSE;
- instances[allocatedInstances - 1].screen = 0;
- }
-
- foundVendor = TRUE;
-
- if ( (device_id == pPci->device_id)
- || ((vendorID == PCI_VENDOR_GENERIC)
- && (match_class == device_class)) ) {
- if ( instances != NULL ) {
- instances[allocatedInstances - 1].foundHW = TRUE;
- instances[allocatedInstances - 1].chip = id->numChipset;
- }
-
-
- if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
- if (xf86CheckPciSlot(pPci)) {
- GDevPtr pGDev =
- xf86AddBusDeviceToConfigure(drvp->driverName,
- BUS_PCI, pPci, -1);
- if (pGDev) {
- /* After configure pass 1, chipID and chipRev
- * are treated as over-rides, so clobber them
- * here.
- */
- pGDev->chipID = -1;
- pGDev->chipRev = -1;
- }
-
- numFound++;
- }
- }
- else {
- numFound++;
- }
-
- break;
- }
- }
- }
- }
-
- pci_iterator_destroy(iter);
-
-
- /* In "probe only" or "configure" mode (signaled by instances being NULL),
- * our work is done. Return the number of detected devices.
- */
- if ( instances == NULL ) {
- return numFound;
- }
-
-
- /*
- * This may be debatable, but if no PCI devices with a matching vendor
- * type is found, return zero now. It is probably not desirable to
- * allow the config file to override this.
- */
- if (allocatedInstances <= 0) {
- xfree(instances);
- return 0;
- }
-
-
- DebugF("%s instances found: %d\n", driverName, allocatedInstances);
-
- /*
- * Check for devices that need duplicated instances. This is required
- * when there is more than one screen per entity.
- *
- * XXX This currently doesn't work for cases where the BusID isn't
- * specified explicitly in the config file.
- */
-
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->screen > 0 && devList[j]->busID
- && *devList[j]->busID) {
- for (i = 0; i < allocatedInstances; i++) {
- pPci = instances[i].pci;
- if (xf86ComparePciBusString(devList[j]->busID,
- PCI_MAKE_BUS( pPci->domain, pPci->bus ),
- pPci->dev,
- pPci->func)) {
- allocatedInstances++;
- instances[allocatedInstances - 1] = instances[i];
- instances[allocatedInstances - 1].screen =
- devList[j]->screen;
- numFound++;
- break;
- }
- }
- }
- }
-
- for (i = 0; i < allocatedInstances; i++) {
- GDevPtr dev = NULL;
- GDevPtr devBus = NULL;
-
- pPci = instances[i].pci;
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->busID && *devList[j]->busID) {
- if (xf86ComparePciBusString(devList[j]->busID,
- PCI_MAKE_BUS( pPci->domain, pPci->bus ),
- pPci->dev,
- pPci->func) &&
- devList[j]->screen == instances[i].screen) {
-
- if (devBus)
- xf86MsgVerb(X_WARNING,0,
- "%s: More than one matching Device section for "
- "instances\n\t(BusID: %s) found: %s\n",
- driverName, devList[j]->busID,
- devList[j]->identifier);
- else
- devBus = devList[j];
- }
- } else {
- /*
- * if device section without BusID is found
- * only assign to it to the primary device.
- */
- if (xf86IsPrimaryPci(pPci)) {
- xf86Msg(X_PROBED, "Assigning device section with no busID"
- " to primary device\n");
- if (dev || devBus)
- xf86MsgVerb(X_WARNING, 0,
- "%s: More than one matching Device section "
- "found: %s\n", driverName, devList[j]->identifier);
- else
- dev = devList[j];
- }
- }
- }
- if (devBus) dev = devBus; /* busID preferred */
- if (!dev) {
- if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID PCI:%u@%u:%u:%u) found\n",
- driverName, pPci->domain, pPci->bus, pPci->dev,
- pPci->func);
- }
- } else {
- numClaimedInstances++;
- instances[i].claimed = TRUE;
- instances[i].dev = dev;
- }
- }
- DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
- /*
- * Now check that a chipset or chipID override in the device section
- * is valid. Chipset has precedence over chipID.
- * If chipset is not valid ignore BusSlot completely.
- */
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
- MessageType from = X_PROBED;
-
- if (!instances[i].claimed) {
- continue;
- }
- if (instances[i].dev->chipset) {
- for (c = chipsets; c->token >= 0; c++) {
- if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
- break;
- }
- if (c->token == -1) {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
- "section \"%s\" isn't valid for this driver\n",
- driverName, instances[i].dev->chipset,
- instances[i].dev->identifier);
- } else {
- instances[i].chip = c->token;
-
- for (id = PCIchipsets; id->numChipset >= 0; id++) {
- if (id->numChipset == instances[i].chip)
- break;
- }
- if(id->numChipset >=0){
- xf86Msg(X_CONFIG,"Chipset override: %s\n",
- instances[i].dev->chipset);
- from = X_CONFIG;
- } else {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
- "section \"%s\" isn't a valid PCI chipset\n",
- driverName, instances[i].dev->chipset,
- instances[i].dev->identifier);
- }
- }
- } else if (instances[i].dev->chipID > 0) {
- for (id = PCIchipsets; id->numChipset >= 0; id++) {
- if (id->PCIid == instances[i].dev->chipID)
- break;
- }
- if (id->numChipset == -1) {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
- "section \"%s\" isn't valid for this driver\n",
- driverName, instances[i].dev->chipID,
- instances[i].dev->identifier);
- } else {
- instances[i].chip = id->numChipset;
-
- xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
- instances[i].dev->chipID);
- from = X_CONFIG;
- }
- } else if (!instances[i].foundHW) {
- /*
- * This means that there was no override and the PCI chipType
- * doesn't match one that is supported
- */
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- }
- if (instances[i].claimed == TRUE){
- for (c = chipsets; c->token >= 0; c++) {
- if (c->token == instances[i].chip)
- break;
- }
- xf86Msg(from,"Chipset %s found\n",
- c->name);
- }
- }
-
- /*
- * Of the claimed instances, check that another driver hasn't already
- * claimed its slot.
- */
- numFound = 0;
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
-
- if (!instances[i].claimed)
- continue;
- pPci = instances[i].pci;
-
-
- /*
- * Allow the same entity to be used more than once for devices with
- * multiple screens per entity. This assumes implicitly that there
- * will be a screen == 0 instance.
- *
- * XXX Need to make sure that two different drivers don't claim
- * the same screen > 0 instance.
- */
- if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
- continue;
-
- DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
- driverName, pPci->bus, pPci->dev, pPci->func);
-
- /* Allocate an entry in the lists to be returned */
- numFound++;
- retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
- retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
- instances[i].chip,
- instances[i].dev,
- instances[i].dev->active);
- if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
- for (j = 0; j < xf86NumEntities; j++) {
- EntityPtr pEnt = xf86Entities[j];
- if (pEnt->bus.type != BUS_PCI)
- continue;
- if (pEnt->bus.id.pci == pPci) {
- retEntities[numFound - 1] = j;
- xf86AddDevToEntity(j, instances[i].dev);
- break;
- }
- }
- }
- }
- xfree(instances);
- if (numFound > 0) {
- *foundEntities = retEntities;
- }
-
- return numFound;
-}
-
-/*
- * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
- */
-void
-xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
- void (*ProtectRegs)(ScrnInfoPtr, Bool),
- void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
- int maskval, int knownclkindex, int knownclkvalue)
-{
- register int status = vertsyncreg;
- unsigned long i, cnt, rcnt, sync;
-
- /* First save registers that get written on */
- (*ClockFunc)(pScrn, CLK_REG_SAVE);
-
- if (num > MAXCLOCKS)
- num = MAXCLOCKS;
-
- for (i = 0; i < num; i++)
- {
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, TRUE);
- if (!(*ClockFunc)(pScrn, i))
- {
- pScrn->clock[i] = -1;
- continue;
- }
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, FALSE);
- if (BlankScreen)
- (*BlankScreen)(pScrn, FALSE);
-
- usleep(50000); /* let VCO stabilise */
-
- cnt = 0;
- sync = 200000;
-
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == maskval)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
-
- for (rcnt = 0; rcnt < 5; rcnt++)
- {
- while (!(inb(status) & maskval))
- cnt++;
- while ((inb(status) & maskval))
- cnt++;
- }
-
-finish:
- pScrn->clock[i] = cnt ? cnt : -1;
- if (BlankScreen)
- (*BlankScreen)(pScrn, TRUE);
- }
-
- for (i = 0; i < num; i++)
- {
- if (i != knownclkindex)
- {
- if (pScrn->clock[i] == -1)
- {
- pScrn->clock[i] = 0;
- }
- else
- {
- pScrn->clock[i] = (int)(0.5 +
- (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
- (pScrn->clock[i]));
- /* Round to nearest 10KHz */
- pScrn->clock[i] += 5;
- pScrn->clock[i] /= 10;
- pScrn->clock[i] *= 10;
- }
- }
- }
-
- pScrn->clock[knownclkindex] = knownclkvalue;
- pScrn->numClocks = num;
-
- /* Restore registers that were written on */
- (*ClockFunc)(pScrn, CLK_REG_RESTORE);
-}
-
-const char *
-xf86GetVisualName(int visual)
-{
- if (visual < 0 || visual > DirectColor)
- return NULL;
-
- return xf86VisualNames[visual];
-}
-
-
-int
-xf86GetVerbosity(void)
-{
- return max(xf86Verbose, xf86LogVerbose);
-}
-
-Pix24Flags
-xf86GetPix24(void)
-{
- return xf86Info.pixmap24;
-}
-
-
-int
-xf86GetDepth(void)
-{
- return xf86Depth;
-}
-
-
-rgb
-xf86GetWeight(void)
-{
- return xf86Weight;
-}
-
-
-Gamma
-xf86GetGamma(void)
-{
- return xf86Gamma;
-}
-
-
-Bool
-xf86GetFlipPixels(void)
-{
- return xf86FlipPixels;
-}
-
-
-const char *
-xf86GetServerName(void)
-{
- return xf86ServerName;
-}
-
-
-Bool
-xf86ServerIsExiting(void)
-{
- return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
-}
-
-
-Bool
-xf86ServerIsResetting(void)
-{
- return xf86Resetting;
-}
-
-
-Bool
-xf86ServerIsInitialising(void)
-{
- return xf86Initialising;
-}
-
-
-Bool
-xf86ServerIsOnlyDetecting(void)
-{
- return xf86DoConfigure;
-}
-
-
-Bool
-xf86CaughtSignal(void)
-{
- return xf86Info.caughtSignal;
-}
-
-
-Bool
-xf86GetVidModeAllowNonLocal(void)
-{
- return xf86Info.vidModeAllowNonLocal;
-}
-
-
-Bool
-xf86GetVidModeEnabled(void)
-{
- return xf86Info.vidModeEnabled;
-}
-
-Bool
-xf86GetModInDevAllowNonLocal(void)
-{
- return xf86Info.miscModInDevAllowNonLocal;
-}
-
-
-Bool
-xf86GetModInDevEnabled(void)
-{
- return xf86Info.miscModInDevEnabled;
-}
-
-
-Bool
-xf86GetAllowMouseOpenFail(void)
-{
- return xf86Info.allowMouseOpenFail;
-}
-
-
-Bool
-xf86IsPc98(void)
-{
-#if SUPPORT_PC98
- return xf86Info.pc98;
-#else
- return FALSE;
-#endif
-}
-
-void
-xf86DisableRandR(void)
-{
- xf86Info.disableRandR = TRUE;
- xf86Info.randRFrom = X_PROBED;
-}
-
-CARD32
-xf86GetModuleVersion(pointer module)
-{
- return (CARD32)LoaderGetModuleVersion(module);
-}
-
-pointer
-xf86LoadDrvSubModule(DriverPtr drv, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- return ret;
-}
-
-pointer
-xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
- return ret;
-}
-
-/*
- * xf86LoadOneModule loads a single module.
- */
-pointer
-xf86LoadOneModule(char *name, pointer opt)
-{
- int errmaj, errmin;
- char *Name;
- pointer mod;
-
- if (!name)
- return NULL;
-
- /* Normalise the module name */
- Name = xf86NormalizeName(name);
-
- /* Skip empty names */
- if (Name == NULL)
- return NULL;
- if (*Name == '\0') {
- xfree(Name);
- return NULL;
- }
-
- mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
- if (!mod)
- LoaderErrorMsg(NULL, Name, errmaj, errmin);
- xfree(Name);
- return mod;
-}
-
-void
-xf86UnloadSubModule(pointer mod)
-{
- /*
- * This is disabled for now. The loader isn't smart enough yet to undo
- * relocations.
- */
-#if 0
- UnloadSubModule(mod);
-#endif
-}
-
-Bool
-xf86LoaderCheckSymbol(const char *name)
-{
- return LoaderSymbol(name) != NULL;
-}
-
-typedef enum {
- OPTION_BACKING_STORE
-} BSOpts;
-
-static const OptionInfoRec BSOptions[] = {
- { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetBackingStore(ScreenPtr pScreen)
-{
- Bool useBS = FALSE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(BSOptions));
- (void)memcpy(options, BSOptions, sizeof(BSOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- if (xf86bsEnableFlag) {
- from = X_CMDLINE;
- useBS = TRUE;
- } else if (xf86bsDisableFlag) {
- from = X_CMDLINE;
- useBS = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
- from = X_CONFIG;
- }
- xfree(options);
- pScreen->backingStoreSupport = useBS ? Always : NotUseful;
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
- useBS ? "enabled" : "disabled");
-}
-
-
-typedef enum {
- OPTION_SILKEN_MOUSE
-} SMOpts;
-
-static const OptionInfoRec SMOptions[] = {
- { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetSilkenMouse (ScreenPtr pScreen)
-{
- Bool useSM = TRUE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(SMOptions));
- (void)memcpy(options, SMOptions, sizeof(SMOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- /* disable if screen shares resources */
- /* TODO VGA arb disable silken mouse */
- if (xf86silkenMouseDisableFlag) {
- from = X_CMDLINE;
- useSM = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
- from = X_CONFIG;
- }
- xfree(options);
- /*
- * XXX quick hack to report correctly for OSs that can't do SilkenMouse
- * yet. Should handle this differently so that alternate async methods
- * work correctly with this too.
- */
- pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
- pScrn->silkenMouse ? "enabled" : "disabled");
-}
-
-/* Wrote this function for the PM2 Xv driver, preliminary. */
-
-pointer
-xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
- char **adaptor_name, pointer *adaptor_options)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- confXvAdaptorPtr adaptor;
- int i;
-
- if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
- if (adaptor_name) *adaptor_name = NULL;
- if (adaptor_options) *adaptor_options = NULL;
- return NULL;
- }
-
- adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
- if (adaptor_name) *adaptor_name = adaptor->identifier;
- if (adaptor_options) *adaptor_options = adaptor->options;
-
- for (i = 0; i < adaptor->numports; i++)
- if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
- return adaptor->ports[i].options;
-
- return NULL;
-}
-
-/* Rather than duplicate loader's get OS function, just include it directly */
-#define LoaderGetOS xf86GetOS
-#include "loader/os.c"
-
-/* new RAC */
-/*
- * xf86ConfigPciEntityInactive() -- This function can be used
- * to configure an inactive entity as well as to reconfigure an
- * previously active entity inactive. If the entity has been
- * assigned to a screen before it will be removed. If p_chip is
- * non-NULL all static resources listed there will be registered.
- */
-static void
-xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
- EntityProc init, EntityProc enter,
- EntityProc leave, pointer private)
-{
- ScrnInfoPtr pScrn;
-
- if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
- xf86RemoveEntityFromScreen(pScrn,pEnt->index);
-
- /* shared resources are only needed when entity is active: remove */
- xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
-}
-
-static void
-xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- ScrnInfoPtr pScrn;
-
- if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
- xf86RemoveEntityFromScreen(pScrn,pEnt->index);
- xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
-}
-
-ScrnInfoPtr
-xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
- PciChipsets *p_chip, void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return pScrn;
-
- if (!(pEnt->location.type == BUS_PCI)
- || !xf86GetPciInfoForEntity(entityIndex)) {
- xfree(pEnt);
- return pScrn;
- }
- if (!pEnt->active) {
- xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
- leave, private);
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pScrn)
- pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
- if (xf86IsEntitySharable(entityIndex)) {
- xf86SetEntityShared(entityIndex);
- }
- xf86AddEntityToScreen(pScrn,entityIndex);
- if (xf86IsEntityShared(entityIndex)) {
- return pScrn;
- }
- xfree(pEnt);
-
- xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
-
- return pScrn;
-}
-
-ScrnInfoPtr
-xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
- EntityProc init, EntityProc enter, EntityProc leave,
- pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return pScrn;
-
- if (!(pEnt->location.type == BUS_NONE)) {
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pEnt->active) {
- xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pScrn)
- pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
- xf86AddEntityToScreen(pScrn,entityIndex);
-
- xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
-
- return pScrn;
-}
-
-/*
- *
- * OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
- * It is likely to be removed. Don't use!
- */
-
-Bool
-xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
- PciChipsets *p_chip, void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return FALSE;
-
- if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
- xfree(pEnt);
- return FALSE;
- }
- xf86AddEntityToScreen(pScrn,entityIndex);
-
- xfree(pEnt);
- if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-xf86IsScreenPrimary(int scrnIndex)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int i;
-
- for (i=0 ; i < pScrn->numEntities; i++) {
- if (xf86IsEntityPrimary(i))
- return TRUE;
- }
- return FALSE;
-}
-
-int
-xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
- int format, unsigned long len, pointer value )
-{
- RootWinPropPtr pNewProp = NULL, pRegProp;
- int i;
- Bool existing = FALSE;
-
- DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
- ScrnIndex, property, type, format, len, value);
-
- if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
- return(BadMatch);
- }
-
- if (xf86RegisteredPropertiesTable &&
- xf86RegisteredPropertiesTable[ScrnIndex]) {
- for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
- pNewProp; pNewProp = pNewProp->next) {
- if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
- break;
- }
- }
-
- if (!pNewProp) {
- if ((pNewProp = (RootWinPropPtr)xalloc(sizeof(RootWinProp))) == NULL) {
- return(BadAlloc);
- }
- /*
- * We will put this property at the end of the list so that
- * the changes are made in the order they were requested.
- */
- pNewProp->next = NULL;
- } else {
- if (pNewProp->name)
- xfree(pNewProp->name);
- existing = TRUE;
- }
-
- pNewProp->name = xnfstrdup(NameForAtom(property));
- pNewProp->type = type;
- pNewProp->format = format;
- pNewProp->size = len;
- pNewProp->data = value;
-
- DebugF("new property filled\n");
-
- if (NULL==xf86RegisteredPropertiesTable) {
- DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
- xf86NumScreens);
- if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
- return(BadAlloc);
- }
- for (i=0; i<xf86NumScreens; i++) {
- xf86RegisteredPropertiesTable[i] = NULL;
- }
- }
-
- DebugF("xf86RegisteredPropertiesTable %p\n",
- (void *)xf86RegisteredPropertiesTable);
- DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
- ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
-
- if (!existing) {
- if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
- xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
- } else {
- pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
- while (pRegProp->next != NULL) {
- DebugF("- next %p\n", (void *)pRegProp);
- pRegProp = pRegProp->next;
- }
- pRegProp->next = pNewProp;
- }
- }
- DebugF("xf86RegisterRootWindowProperty succeeded\n");
- return(Success);
-}
-
-Bool
-xf86IsUnblank(int mode)
-{
- switch(mode) {
- case SCREEN_SAVER_OFF:
- case SCREEN_SAVER_FORCER:
- return TRUE;
- case SCREEN_SAVER_ON:
- case SCREEN_SAVER_CYCLE:
- return FALSE;
- default:
- xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
- return TRUE;
- }
-}
-
-void
-xf86MotionHistoryAllocate(LocalDevicePtr local)
-{
- AllocateMotionHistory(local->dev);
-}
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * Authors: Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * ... and others
+ *
+ * This file includes the helper functions that the server provides for
+ * different drivers.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <pciaccess.h>
+#include "Pci.h"
+
+#include <X11/X.h>
+#include "os.h"
+#include "servermd.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "gcstruct.h"
+#include "loaderProcs.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "micmap.h"
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "mivalidate.h"
+#include "xf86Bus.h"
+#include "xf86Crtc.h"
+
+/* For xf86GetClocks */
+#if defined(CSRG_BASED) || defined(__GNU__)
+#define HAS_SETPRIORITY
+#include <sys/resource.h>
+#endif
+
+static int xf86ScrnInfoPrivateCount = 0;
+
+
+/* Add a pointer to a new DriverRec to xf86DriverList */
+
+void
+xf86AddDriver(DriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86DriverList == NULL)
+ xf86NumDrivers = 0;
+
+ xf86NumDrivers++;
+ xf86DriverList = xnfrealloc(xf86DriverList,
+ xf86NumDrivers * sizeof(DriverPtr));
+ xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
+ if (flags & HaveDriverFuncs)
+ *xf86DriverList[xf86NumDrivers - 1] = *driver;
+ else {
+ (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
+ sizeof( DriverRec ) );
+ (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
+ sizeof(DriverRec1));
+
+ }
+ xf86DriverList[xf86NumDrivers - 1]->module = module;
+ xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
+}
+
+void
+xf86DeleteDriver(int drvIndex)
+{
+ if (xf86DriverList[drvIndex]
+ && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
+ if (xf86DriverList[drvIndex]->module)
+ UnloadModule(xf86DriverList[drvIndex]->module);
+ free(xf86DriverList[drvIndex]);
+ xf86DriverList[drvIndex] = NULL;
+ }
+}
+
+/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
+
+void
+xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86InputDriverList == NULL)
+ xf86NumInputDrivers = 0;
+
+ xf86NumInputDrivers++;
+ xf86InputDriverList = xnfrealloc(xf86InputDriverList,
+ xf86NumInputDrivers * sizeof(InputDriverPtr));
+ xf86InputDriverList[xf86NumInputDrivers - 1] =
+ xnfalloc(sizeof(InputDriverRec));
+ *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
+ xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
+ xf86InputDriverList[xf86NumInputDrivers - 1]->refCount = 0;
+}
+
+void
+xf86DeleteInputDriver(int drvIndex)
+{
+ if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
+ UnloadModule(xf86InputDriverList[drvIndex]->module);
+ free(xf86InputDriverList[drvIndex]);
+ xf86InputDriverList[drvIndex] = NULL;
+}
+
+InputDriverPtr
+xf86LookupInputDriver(const char *name)
+{
+ int i;
+
+ for (i = 0; i < xf86NumInputDrivers; i++) {
+ if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
+ xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
+ return xf86InputDriverList[i];
+ }
+ return NULL;
+}
+
+InputInfoPtr
+xf86LookupInput(const char *name)
+{
+ InputInfoPtr p;
+
+ for (p = xf86InputDevs; p != NULL; p = p->next) {
+ if (strcmp(name, p->name) == 0)
+ return p;
+ }
+
+ return NULL;
+}
+
+/* Allocate a new ScrnInfoRec in xf86Screens */
+
+ScrnInfoPtr
+xf86AllocateScreen(DriverPtr drv, int flags)
+{
+ int i;
+
+ if (xf86Screens == NULL)
+ xf86NumScreens = 0;
+
+ i = xf86NumScreens++;
+ xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
+ xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
+ xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
+ xf86Screens[i]->origIndex = i; /* This never changes */
+ xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
+ xf86ScrnInfoPrivateCount);
+ /*
+ * EnableDisableFBAccess now gets initialized in InitOutput()
+ * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+ */
+
+ xf86Screens[i]->drv = drv;
+ drv->refCount++;
+ xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
+
+ xf86Screens[i]->DriverFunc = drv->driverFunc;
+
+ return xf86Screens[i];
+}
+
+
+/*
+ * Remove an entry from xf86Screens. Ideally it should free all allocated
+ * data. To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ /* First check if the screen is valid */
+ if (xf86NumScreens == 0 || xf86Screens == NULL)
+ return;
+
+ if (scrnIndex > xf86NumScreens - 1)
+ return;
+
+ if (!(pScrn = xf86Screens[scrnIndex]))
+ return;
+
+ /* If a FreeScreen function is defined, call it here */
+ if (pScrn->FreeScreen != NULL)
+ pScrn->FreeScreen(scrnIndex, 0);
+
+ while (pScrn->modes)
+ xf86DeleteMode(&pScrn->modes, pScrn->modes);
+
+ while (pScrn->modePool)
+ xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
+
+ xf86OptionListFree(pScrn->options);
+
+ if (pScrn->module)
+ UnloadModule(pScrn->module);
+
+ if (pScrn->drv)
+ pScrn->drv->refCount--;
+
+ if (pScrn->privates)
+ free(pScrn->privates);
+
+ xf86ClearEntityListForScreen(scrnIndex);
+
+ free(pScrn);
+
+ /* Move the other entries down, updating their scrnIndex fields */
+
+ xf86NumScreens--;
+
+ for (i = scrnIndex; i < xf86NumScreens; i++) {
+ xf86Screens[i] = xf86Screens[i + 1];
+ xf86Screens[i]->scrnIndex = i;
+ /* Also need to take care of the screen layout settings */
+ }
+}
+
+/*
+ * Allocate a private in ScrnInfoRec.
+ */
+
+int
+xf86AllocateScrnInfoPrivateIndex(void)
+{
+ int idx, i;
+ ScrnInfoPtr pScr;
+ DevUnion *nprivs;
+
+ idx = xf86ScrnInfoPrivateCount++;
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScr = xf86Screens[i];
+ nprivs = xnfrealloc(pScr->privates,
+ xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pScr->privates = nprivs;
+ }
+ return idx;
+}
+
+/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
+InputInfoPtr
+xf86AllocateInput(InputDriverPtr drv, int flags)
+{
+ InputInfoPtr new, *prev = NULL;
+
+ if (!(new = calloc(sizeof(InputInfoRec), 1)))
+ return NULL;
+
+ new->drv = drv;
+ drv->refCount++;
+ new->module = DuplicateModule(drv->module, NULL);
+
+ for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
+ ;
+
+ *prev = new;
+ new->next = NULL;
+
+ return new;
+}
+
+
+/*
+ * Remove an entry from xf86InputDevs. Ideally it should free all allocated
+ * data. To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteInput(InputInfoPtr pInp, int flags)
+{
+ InputInfoPtr p;
+
+ /* First check if the inputdev is valid. */
+ if (pInp == NULL)
+ return;
+
+#if 0
+ /* If a free function is defined, call it here. */
+ if (pInp->free)
+ pInp->free(pInp, 0);
+#endif
+
+ if (pInp->module)
+ UnloadModule(pInp->module);
+
+ if (pInp->drv)
+ pInp->drv->refCount--;
+
+ /* This should *really* be handled in drv->UnInit(dev) call instead, but
+ * if the driver forgets about it make sure we free it or at least crash
+ * with flying colors */
+ if (pInp->private)
+ free(pInp->private);
+
+ /* Remove the entry from the list. */
+ if (pInp == xf86InputDevs)
+ xf86InputDevs = pInp->next;
+ else {
+ p = xf86InputDevs;
+ while (p && p->next != pInp)
+ p = p->next;
+ if (p)
+ p->next = pInp->next;
+ /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
+ }
+ free(pInp);
+}
+
+Bool
+xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
+{
+ int i;
+
+ if (pScrn->numFormats >= MAXFORMATS)
+ return FALSE;
+
+ if (bpp <= 0) {
+ if (depth == 1)
+ bpp = 1;
+ else if (depth <= 8)
+ bpp = 8;
+ else if (depth <= 16)
+ bpp = 16;
+ else if (depth <= 32)
+ bpp = 32;
+ else
+ return FALSE;
+ }
+ if (pad <= 0)
+ pad = BITMAP_SCANLINE_PAD;
+
+ i = pScrn->numFormats++;
+ pScrn->formats[i].depth = depth;
+ pScrn->formats[i].bitsPerPixel = bpp;
+ pScrn->formats[i].scanlinePad = pad;
+ return TRUE;
+}
+
+/*
+ * Set the depth we are using based on (in the following order of preference):
+ * - values given on the command line
+ * - values given in the config file
+ * - values provided by the driver
+ * - an overall default when nothing else is given
+ *
+ * Also find a Display subsection matching the depth/bpp found.
+ *
+ * Sets the following ScrnInfoRec fields:
+ * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
+ * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
+ * formats, fbFormat.
+ */
+
+/* Can the screen handle 24 bpp pixmaps */
+#define DO_PIX24(f) ((f & Support24bppFb) || \
+ ((f & Support32bppFb) && (f & SupportConvert24to32)))
+
+/* Can the screen handle 32 bpp pixmaps */
+#define DO_PIX32(f) ((f & Support32bppFb) || \
+ ((f & Support24bppFb) && (f & SupportConvert32to24)))
+
+/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
+#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
+ && (f & PreferConvert24to32))
+
+/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
+#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
+ && (f & PreferConvert32to24))
+
+/* Can the screen handle 32bpp pixmaps for 24bpp fb */
+#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
+
+/* Can the screen handle 24bpp pixmaps for 32bpp fb */
+#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
+
+#ifndef GLOBAL_DEFAULT_DEPTH
+#define GLOBAL_DEFAULT_DEPTH 24
+#endif
+
+Bool
+xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
+ int depth24flags)
+{
+ int i;
+ DispPtr disp;
+ Pix24Flags pix24 = xf86Info.pixmap24;
+ Bool nomatch = FALSE;
+
+ scrp->bitsPerPixel = -1;
+ scrp->depth = -1;
+ scrp->pixmap24 = Pix24DontCare;
+ scrp->bitsPerPixelFrom = X_DEFAULT;
+ scrp->depthFrom = X_DEFAULT;
+
+ if (xf86FbBpp > 0) {
+ scrp->bitsPerPixel = xf86FbBpp;
+ scrp->bitsPerPixelFrom = X_CMDLINE;
+ }
+
+ if (xf86Depth > 0) {
+ scrp->depth = xf86Depth;
+ scrp->depthFrom = X_CMDLINE;
+ }
+
+ if (xf86FbBpp < 0 && xf86Depth < 0) {
+ if (scrp->confScreen->defaultfbbpp > 0) {
+ scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ }
+ if (scrp->confScreen->defaultdepth > 0) {
+ scrp->depth = scrp->confScreen->defaultdepth;
+ scrp->depthFrom = X_CONFIG;
+ }
+
+ if (scrp->confScreen->defaultfbbpp <= 0 &&
+ scrp->confScreen->defaultdepth <= 0) {
+ /*
+ * Check for DefaultDepth and DefaultFbBpp options in the
+ * Device sections.
+ */
+ int i;
+ GDevPtr device;
+ Bool found = FALSE;
+
+ for (i = 0; i < scrp->numEntities; i++) {
+ device = xf86GetDevFromEntity(scrp->entityList[i],
+ scrp->entityInstanceList[i]);
+ if (device && device->options) {
+ if (xf86FindOption(device->options, "DefaultDepth")) {
+ scrp->depth = xf86SetIntOption(device->options,
+ "DefaultDepth", -1);
+ scrp->depthFrom = X_CONFIG;
+ found = TRUE;
+ }
+ if (xf86FindOption(device->options, "DefaultFbBpp")) {
+ scrp->bitsPerPixel = xf86SetIntOption(device->options,
+ "DefaultFbBpp",
+ -1);
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ found = TRUE;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+ }
+
+ /* If none of these is set, pick a default */
+ if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
+ if (fbbpp > 0 || depth > 0) {
+ if (fbbpp > 0)
+ scrp->bitsPerPixel = fbbpp;
+ if (depth > 0)
+ scrp->depth = depth;
+ } else {
+ scrp->depth = GLOBAL_DEFAULT_DEPTH;
+ }
+ }
+
+ /* If any are not given, determine a default for the others */
+
+ if (scrp->bitsPerPixel < 0) {
+ /* The depth must be set */
+ if (scrp->depth > -1) {
+ if (scrp->depth == 1)
+ scrp->bitsPerPixel = 1;
+ else if (scrp->depth <= 4)
+ scrp->bitsPerPixel = 4;
+ else if (scrp->depth <= 8)
+ scrp->bitsPerPixel = 8;
+ else if (scrp->depth <= 16)
+ scrp->bitsPerPixel = 16;
+ else if (scrp->depth <= 24) {
+ /*
+ * Figure out if a choice is possible based on the depth24
+ * and pix24 flags.
+ */
+ /* Check pix24 first */
+ if (pix24 != Pix24DontCare) {
+ if (pix24 == Pix24Use32) {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else {
+ nomatch = TRUE;
+ }
+ } else if (pix24 == Pix24Use24) {
+ if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ } else {
+ nomatch = TRUE;
+ }
+ }
+ } else {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ }
+ }
+ } else if (scrp->depth <= 32)
+ scrp->bitsPerPixel = 32;
+ else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than 32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "xf86SetDepthBpp: internal error: depth and fbbpp"
+ " are both not set\n");
+ return FALSE;
+ }
+ if (scrp->bitsPerPixel < 0) {
+ if (nomatch)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24 pixmap format (%d)\n",
+ PIX24TOBPP(pix24));
+ else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
+ NoDepth24Support)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24\n");
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't find fbbpp for depth 24\n");
+ return FALSE;
+ }
+ scrp->bitsPerPixelFrom = X_PROBED;
+ }
+
+ if (scrp->depth <= 0) {
+ /* bitsPerPixel is already set */
+ switch (scrp->bitsPerPixel) {
+ case 32:
+ scrp->depth = 24;
+ break;
+ default:
+ /* 1, 4, 8, 16 and 24 */
+ scrp->depth = scrp->bitsPerPixel;
+ break;
+ }
+ scrp->depthFrom = X_PROBED;
+ }
+
+ /* Sanity checks */
+ if (scrp->depth < 1 || scrp->depth > 32) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is not in the range 1-32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ switch (scrp->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified fbbpp (%d) is not a permitted value\n",
+ scrp->bitsPerPixel);
+ return FALSE;
+ }
+ if (scrp->depth > scrp->bitsPerPixel) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than the fbbpp (%d)\n",
+ scrp->depth, scrp->bitsPerPixel);
+ return FALSE;
+ }
+
+ /* set scrp->pixmap24 if the driver isn't flexible */
+ if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
+ scrp->pixmap24 = Pix24Use24;
+ }
+ if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
+ scrp->pixmap24 = Pix24Use32;
+ }
+
+ /*
+ * Find the Display subsection matching the depth/fbbpp and initialise
+ * scrp->display with it.
+ */
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
+ || (disp->depth == scrp->depth && disp->fbbpp <= 0)
+ || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
+ scrp->display = disp;
+ break;
+ }
+ }
+
+ /*
+ * If an exact match can't be found, see if there is one with no
+ * depth or fbbpp specified.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if (disp->depth <= 0 && disp->fbbpp <= 0) {
+ scrp->display = disp;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If all else fails, create a default one.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ scrp->confScreen->numdisplays++;
+ scrp->confScreen->displays =
+ xnfrealloc(scrp->confScreen->displays,
+ scrp->confScreen->numdisplays * sizeof(DispRec));
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Creating default Display subsection in Screen section\n"
+ "\t\"%s\" for depth/fbbpp %d/%d\n",
+ scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
+ memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
+ scrp->confScreen->displays[i].blackColour.red = -1;
+ scrp->confScreen->displays[i].blackColour.green = -1;
+ scrp->confScreen->displays[i].blackColour.blue = -1;
+ scrp->confScreen->displays[i].whiteColour.red = -1;
+ scrp->confScreen->displays[i].whiteColour.green = -1;
+ scrp->confScreen->displays[i].whiteColour.blue = -1;
+ scrp->confScreen->displays[i].defaultVisual = -1;
+ scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
+ scrp->confScreen->displays[i].modes[0] = NULL;
+ scrp->confScreen->displays[i].depth = depth;
+ scrp->confScreen->displays[i].fbbpp = fbbpp;
+ scrp->display = &scrp->confScreen->displays[i];
+ }
+
+ /*
+ * Setup defaults for the display-wide attributes the framebuffer will
+ * need. These defaults should eventually be set globally, and not
+ * dependent on the screens.
+ */
+ scrp->imageByteOrder = IMAGE_BYTE_ORDER;
+ scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ if (scrp->depth < 8) {
+ /* Planar modes need these settings */
+ scrp->bitmapScanlineUnit = 8;
+ scrp->bitmapBitOrder = MSBFirst;
+ } else {
+ scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
+ }
+
+ /*
+ * If an unusual depth is required, add it to scrp->formats. The formats
+ * for the common depths are handled globally in InitOutput
+ */
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* Common depths. Nothing to do for them */
+ break;
+ default:
+ if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't add pixmap format for depth %d\n", scrp->depth);
+ return FALSE;
+ }
+ }
+
+ /* Initialise the framebuffer format for this screen */
+ scrp->fbFormat.depth = scrp->depth;
+ scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
+ scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
+
+ return TRUE;
+}
+
+/*
+ * Print out the selected depth and bpp.
+ */
+void
+xf86PrintDepthBpp(ScrnInfoPtr scrp)
+{
+ xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
+ xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
+}
+
+/*
+ * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
+ * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
+ */
+Bool
+xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
+{
+ MessageType weightFrom = X_DEFAULT;
+
+ scrp->weight.red = 0;
+ scrp->weight.green = 0;
+ scrp->weight.blue = 0;
+
+ if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
+ scrp->weight = xf86Weight;
+ weightFrom = X_CMDLINE;
+ } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
+ && scrp->display->weight.blue > 0) {
+ scrp->weight = scrp->display->weight;
+ weightFrom = X_CONFIG;
+ } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
+ scrp->weight = weight;
+ } else {
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ scrp->weight.red = scrp->weight.green =
+ scrp->weight.blue = scrp->rgbBits;
+ break;
+ case 15:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
+ break;
+ case 16:
+ scrp->weight.red = scrp->weight.blue = 5;
+ scrp->weight.green = 6;
+ break;
+ case 24:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
+ break;
+ case 30:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
+ break;
+ }
+ }
+
+ if (scrp->weight.red)
+ xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue);
+
+ if (scrp->depth > MAX_PSEUDO_DEPTH &&
+ (scrp->depth != scrp->weight.red + scrp->weight.green +
+ scrp->weight.blue)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Weight given (%d%d%d) is inconsistent with the "
+ "depth (%d)\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue, scrp->depth);
+ return FALSE;
+ }
+ if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
+ /*
+ * XXX Does this even mean anything for TrueColor visuals?
+ * If not, we shouldn't even be setting it here. However, this
+ * matches the behaviour of 3.x versions of XFree86.
+ */
+ scrp->rgbBits = scrp->weight.red;
+ if (scrp->weight.green > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.green;
+ if (scrp->weight.blue > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.blue;
+ }
+
+ /* Set the mask and offsets */
+ if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
+ /* Default to a setting common to PC hardware */
+ scrp->offset.red = scrp->weight.green + scrp->weight.blue;
+ scrp->offset.green = scrp->weight.blue;
+ scrp->offset.blue = 0;
+ scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
+ scrp->mask.green = ((1 << scrp->weight.green) - 1)
+ << scrp->offset.green;
+ scrp->mask.blue = (1 << scrp->weight.blue) - 1;
+ } else {
+ /* Initialise to the values passed */
+ scrp->mask.red = mask.red;
+ scrp->mask.green = mask.green;
+ scrp->mask.blue = mask.blue;
+ scrp->offset.red = ffs(mask.red);
+ scrp->offset.green = ffs(mask.green);
+ scrp->offset.blue = ffs(mask.blue);
+ }
+ return TRUE;
+}
+
+Bool
+xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
+{
+ MessageType visualFrom = X_DEFAULT;
+
+ if (defaultColorVisualClass >= 0) {
+ scrp->defaultVisual = defaultColorVisualClass;
+ visualFrom = X_CMDLINE;
+ } else if (scrp->display->defaultVisual >= 0) {
+ scrp->defaultVisual = scrp->display->defaultVisual;
+ visualFrom = X_CONFIG;
+ } else if (visual >= 0) {
+ scrp->defaultVisual = visual;
+ } else {
+ if (scrp->depth == 1)
+ scrp->defaultVisual = StaticGray;
+ else if (scrp->depth == 4)
+ scrp->defaultVisual = StaticColor;
+ else if (scrp->depth <= MAX_PSEUDO_DEPTH)
+ scrp->defaultVisual = PseudoColor;
+ else
+ scrp->defaultVisual = TrueColor;
+ }
+ switch (scrp->defaultVisual) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ case TrueColor:
+ case DirectColor:
+ xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
+ xf86VisualNames[scrp->defaultVisual]);
+ return TRUE;
+ default:
+
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Invalid default visual class (%d)\n", scrp->defaultVisual);
+ return FALSE;
+ }
+}
+
+#define TEST_GAMMA(g) \
+ (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
+
+#define SET_GAMMA(g) \
+ (g) > GAMMA_ZERO ? (g) : 1.0
+
+Bool
+xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
+{
+ MessageType from = X_DEFAULT;
+#if 0
+ xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
+#endif
+ if (TEST_GAMMA(xf86Gamma)) {
+ from = X_CMDLINE;
+ scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
+ scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
+ scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
+ } else if (TEST_GAMMA(scrp->monitor->gamma)) {
+ from = X_CONFIG;
+ scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
+ scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
+ scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
+#if 0
+ } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
+ from = X_PROBED;
+ scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
+ /* EDID structure version 2 gives optional seperate red, green & blue gamma values
+ * in bytes 0x57-0x59 */
+#endif
+ } else if (TEST_GAMMA(gamma)) {
+ scrp->gamma.red = SET_GAMMA(gamma.red);
+ scrp->gamma.green = SET_GAMMA(gamma.green);
+ scrp->gamma.blue = SET_GAMMA(gamma.blue);
+ } else {
+ scrp->gamma.red = 1.0;
+ scrp->gamma.green = 1.0;
+ scrp->gamma.blue = 1.0;
+ }
+ /* Pretend we succeeded if we support better a gamma system.
+ * This avoids a confusing message.
+ */
+ if (xf86_crtc_supports_gamma(scrp))
+ return TRUE;
+ xf86DrvMsg(scrp->scrnIndex, from,
+ "Using gamma correction (%.1f, %.1f, %.1f)\n",
+ scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
+
+ return TRUE;
+}
+
+#undef TEST_GAMMA
+#undef SET_GAMMA
+
+
+/*
+ * Set the DPI from the command line option. XXX should allow it to be
+ * calculated from the widthmm/heightmm values.
+ */
+
+#undef MMPERINCH
+#define MMPERINCH 25.4
+
+void
+xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
+{
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
+ int ddcWidthmm, ddcHeightmm;
+ int widthErr, heightErr;
+
+ /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
+ pScrn->widthmm = pScrn->monitor->widthmm;
+ pScrn->heightmm = pScrn->monitor->heightmm;
+
+ if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
+ /* DDC gives display size in mm for individual modes,
+ * but cm for monitor
+ */
+ ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
+ ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
+ } else {
+ ddcWidthmm = ddcHeightmm = 0;
+ }
+
+ if (monitorResolution > 0) {
+ pScrn->xDpi = monitorResolution;
+ pScrn->yDpi = monitorResolution;
+ from = X_CMDLINE;
+ } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
+ from = X_CONFIG;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ pScrn->widthmm, pScrn->heightmm);
+
+ /* Warn if config and probe disagree about display size */
+ if ( ddcWidthmm && ddcHeightmm ) {
+ if (pScrn->widthmm > 0) {
+ widthErr = abs(ddcWidthmm - pScrn->widthmm);
+ } else {
+ widthErr = 0;
+ }
+ if (pScrn->heightmm > 0) {
+ heightErr = abs(ddcHeightmm - pScrn->heightmm);
+ } else {
+ heightErr = 0;
+ }
+ if (widthErr>10 || heightErr>10) {
+ /* Should include config file name for monitor here */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
+ ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
+ }
+ }
+ } else if ( ddcWidthmm && ddcHeightmm ) {
+ from = X_PROBED;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ ddcWidthmm, ddcHeightmm );
+ pScrn->widthmm = ddcWidthmm;
+ pScrn->heightmm = ddcHeightmm;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ } else {
+ if (x > 0)
+ pScrn->xDpi = x;
+ else
+ pScrn->xDpi = DEFAULT_DPI;
+ if (y > 0)
+ pScrn->yDpi = y;
+ else
+ pScrn->yDpi = DEFAULT_DPI;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
+ pScrn->xDpi, pScrn->yDpi);
+}
+
+#undef MMPERINCH
+
+
+void
+xf86SetBlackWhitePixels(ScreenPtr pScreen)
+{
+ if (xf86FlipPixels) {
+ pScreen->whitePixel = 0;
+ pScreen->blackPixel = 1;
+ } else {
+ pScreen->whitePixel = 1;
+ pScreen->blackPixel = 0;
+ }
+}
+
+/*
+ * xf86SetRootClip --
+ * Enable or disable rendering to the screen by
+ * setting the root clip list and revalidating
+ * all of the windows
+ */
+
+static void
+xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked = FALSE;
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ /*
+ * Use REGION_BREAK to avoid optimizations in ValidateTree
+ * that assume the root borderClip can't change well, normally
+ * it doesn't...)
+ */
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+ if (WasViewable)
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.height = pScreen->height;
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ FlushAllOutput ();
+}
+
+/*
+ * Function to enable/disable access to the frame buffer
+ *
+ * This is used when VT switching and when entering/leaving DGA direct mode.
+ *
+ * This has been rewritten again to eliminate the saved pixmap. The
+ * devPrivate field in the screen pixmap is set to NULL to catch code
+ * accidentally referencing the frame buffer while the X server is not
+ * supposed to touch it.
+ *
+ * Here, we exchange the pixmap private data, rather than the pixmaps
+ * themselves to avoid having to find and change any references to the screen
+ * pixmap such as GC's, window privates etc. This also means that this code
+ * does not need to know exactly how the pixmap pixels are accessed. Further,
+ * this exchange is >not< done through the screen's ModifyPixmapHeader()
+ * vector. This means the called frame buffer code layers can determine
+ * whether they are switched in or out by keeping track of the root pixmap's
+ * private data, and therefore don't need to access pScrnInfo->vtSema.
+ */
+void
+xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
+ ScreenPtr pScreen = pScrnInfo->pScreen;
+ PixmapPtr pspix;
+
+ pspix = (*pScreen->GetScreenPixmap) (pScreen);
+ if (enable)
+ {
+ /*
+ * Restore the screen pixmap devPrivate field
+ */
+ pspix->devPrivate = pScrnInfo->pixmapPrivate;
+ /*
+ * Restore all of the clip lists on the screen
+ */
+ if (!xf86Resetting)
+ xf86SetRootClip (pScreen, TRUE);
+
+ }
+ else
+ {
+ /*
+ * Empty all of the clip lists on the screen
+ */
+ xf86SetRootClip (pScreen, FALSE);
+ /*
+ * save the screen pixmap devPrivate field and
+ * replace it with NULL so accidental references
+ * to the frame buffer are caught
+ */
+ pScrnInfo->pixmapPrivate = pspix->devPrivate;
+ pspix->devPrivate.ptr = NULL;
+ }
+}
+
+/* Print driver messages in the standard format */
+
+#undef PREFIX_SIZE
+#define PREFIX_SIZE 14
+
+void
+xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
+ va_list args)
+{
+ char *tmpFormat;
+
+ /* Prefix the scrnIndex name to the format string. */
+ if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
+ xf86Screens[scrnIndex]->name) {
+ tmpFormat = malloc(strlen(format) +
+ strlen(xf86Screens[scrnIndex]->name) +
+ PREFIX_SIZE + 1);
+ if (!tmpFormat)
+ return;
+
+ snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
+ xf86Screens[scrnIndex]->name, scrnIndex);
+
+ strcat(tmpFormat, format);
+ LogVMessageVerb(type, verb, tmpFormat, args);
+ free(tmpFormat);
+ } else
+ LogVMessageVerb(type, verb, format, args);
+}
+#undef PREFIX_SIZE
+
+/* Print driver messages, with verbose level specified directly */
+void
+xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
+ ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print driver messages, with verbose level of 1 (default) */
+void
+xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Print non-driver messages with verbose level specified directly */
+void
+xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(-1, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print non-driver messages with verbose level of 1 (default) */
+void
+xf86Msg(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(-1, type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Just like ErrorF, but with the verbose level checked */
+void
+xf86ErrorFVerb(int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= verb || xf86LogVerbose >= verb)
+ LogVWrite(verb, format, ap);
+ va_end(ap);
+}
+
+/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
+void
+xf86ErrorF(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
+ LogVWrite(1, format, ap);
+ va_end(ap);
+}
+
+
+void
+xf86LogInit(void)
+{
+ char *lf = NULL;
+
+#define LOGSUFFIX ".log"
+#define LOGOLDSUFFIX ".old"
+
+ /* Get the log file name */
+ if (xf86LogFileFrom == X_DEFAULT) {
+ /* Append the display number and ".log" */
+ lf = malloc(strlen(xf86LogFile) + strlen("%s") +
+ strlen(LOGSUFFIX) + 1);
+ if (!lf)
+ FatalError("Cannot allocate space for the log file name\n");
+ sprintf(lf, "%s%%s" LOGSUFFIX, xf86LogFile);
+ xf86LogFile = lf;
+ }
+
+ xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
+ xf86LogFileWasOpened = TRUE;
+
+ xf86SetVerbosity(xf86Verbose);
+ xf86SetLogVerbosity(xf86LogVerbose);
+
+#undef LOGSUFFIX
+#undef LOGOLDSUFFIX
+
+ free(lf);
+}
+
+void
+xf86CloseLog(void)
+{
+ LogClose();
+}
+
+
+/*
+ * Drivers can use these for using their own SymTabRecs.
+ */
+
+const char *
+xf86TokenToString(SymTabPtr table, int token)
+{
+ int i;
+
+ for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
+ ;
+
+ if (table[i].token < 0)
+ return NULL;
+ else
+ return(table[i].name);
+}
+
+int
+xf86StringToToken(SymTabPtr table, const char *string)
+{
+ int i;
+
+ if (string == NULL)
+ return -1;
+
+ for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
+ ;
+
+ return(table[i].token);
+}
+
+/*
+ * helper to display the clocks found on a card
+ */
+void
+xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
+{
+ int j;
+
+ xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
+ for (j=0; j < scrp->numClocks; j++) {
+ if ((j % 4) == 0) {
+ xf86ErrorF("\n");
+ xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
+ }
+ xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
+ }
+ xf86ErrorF("\n");
+}
+
+
+/*
+ * This prints out the driver identify message, including the names of
+ * the supported chipsets.
+ *
+ * XXX This makes assumptions about the line width, etc. Maybe we could
+ * use a more general "pretty print" function for messages.
+ */
+void
+xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
+{
+ int len, i;
+
+ len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
+ xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
+ for (i = 0; chips[i].name != NULL; i++) {
+ if (i != 0) {
+ xf86ErrorF(",");
+ len++;
+ }
+ if (len + 2 + strlen(chips[i].name) < 78) {
+ xf86ErrorF(" ");
+ len++;
+ } else {
+ xf86ErrorF("\n\t");
+ len = 8;
+ }
+ xf86ErrorF("%s", chips[i].name);
+ len += strlen(chips[i].name);
+ }
+ xf86ErrorF("\n");
+}
+
+
+int
+xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
+{
+ GDevPtr gdp, *pgdp = NULL;
+ confScreenPtr screensecptr;
+ int i,j;
+
+ if (sectlist)
+ *sectlist = NULL;
+
+ if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
+
+ /*
+ * This is a very important function that matches the device sections
+ * as they show up in the config file with the drivers that the server
+ * loads at run time.
+ *
+ * ChipProbe can call
+ * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
+ * with its driver name. The function allocates an array of GDevPtr and
+ * returns this via sectlist and returns the number of elements in
+ * this list as return value. 0 means none found, -1 means fatal error.
+ *
+ * It can figure out which of the Device sections to use for which card
+ * (using things like the Card statement, etc). For single headed servers
+ * there will of course be just one such Device section.
+ */
+ i = 0;
+
+ /*
+ * first we need to loop over all the Screens sections to get to all
+ * 'active' device sections
+ */
+ for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
+ screensecptr = xf86ConfigLayout.screens[j].screen;
+ if ((screensecptr->device->driver != NULL)
+ && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
+ && (! screensecptr->device->claimed)) {
+ /*
+ * we have a matching driver that wasn't claimed, yet
+ */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = screensecptr->device;
+ }
+ }
+
+ /* Then handle the inactive devices */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j].identifier) {
+ gdp = &xf86ConfigLayout.inactives[j];
+ if (gdp->driver && !gdp->claimed &&
+ !xf86NameCmp(gdp->driver,drivername)) {
+ /* we have a matching driver that wasn't claimed yet */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = gdp;
+ }
+ j++;
+ }
+
+ /*
+ * make the array NULL terminated and return its address
+ */
+ if (i)
+ pgdp[i] = NULL;
+
+ if (sectlist)
+ *sectlist = pgdp;
+ else
+ free(pgdp);
+ return i;
+}
+
+static Bool
+pciDeviceHasBars(struct pci_device *pci)
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ if (pci->regions[i].size)
+ return TRUE;
+
+ if (pci->rom_size)
+ return TRUE;
+
+ return FALSE;
+}
+
+struct Inst {
+ struct pci_device * pci;
+ GDevPtr dev;
+ Bool foundHW; /* PCIid in list of supported chipsets */
+ Bool claimed; /* BusID matches with a device section */
+ int chip;
+ int screen;
+};
+
+
+/**
+ * Find set of unclaimed devices matching a given vendor ID.
+ *
+ * Used by drivers to find as yet unclaimed devices matching the specified
+ * vendor ID.
+ *
+ * \param driverName Name of the driver. This is used to find Device
+ * sections in the config file.
+ * \param vendorID PCI vendor ID of associated devices. If zero, then
+ * the true vendor ID must be encoded in the \c PCIid
+ * fields of the \c PCIchipsets entries.
+ * \param chipsets Symbol table used to associate chipset names with
+ * PCI IDs.
+ * \param devList List of Device sections parsed from the config file.
+ * \param numDevs Number of entries in \c devList.
+ * \param drvp Pointer the driver's control structure.
+ * \param foundEntities Returned list of entity indicies associated with the
+ * driver.
+ *
+ * \returns
+ * The number of elements in returned in \c foundEntities on success or zero
+ * on failure.
+ *
+ * \todo
+ * This function does a bit more than short description says. Fill in some
+ * more of the details of its operation.
+ *
+ * \todo
+ * The \c driverName parameter is redundant. It is the same as
+ * \c DriverRec::driverName. In a future version of this function, remove
+ * that parameter.
+ */
+int
+xf86MatchPciInstances(const char *driverName, int vendorID,
+ SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities)
+{
+ int i,j;
+ struct pci_device * pPci;
+ struct pci_device_iterator *iter;
+ struct Inst *instances = NULL;
+ int numClaimedInstances = 0;
+ int allocatedInstances = 0;
+ int numFound = 0;
+ SymTabRec *c;
+ PciChipsets *id;
+ int *retEntities = NULL;
+
+ *foundEntities = NULL;
+
+
+ /* Each PCI device will contribute at least one entry. Each device
+ * section can contribute at most one entry. The sum of the two is
+ * guaranteed to be larger than the maximum possible number of entries.
+ * Do this calculation and memory allocation once now to eliminate the
+ * need for realloc calls inside the loop.
+ */
+ if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
+ unsigned max_entries = numDevs;
+
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ max_entries++;
+ }
+
+ pci_iterator_destroy(iter);
+ instances = xnfalloc(max_entries * sizeof(struct Inst));
+ }
+
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ unsigned device_class = pPci->device_class;
+ Bool foundVendor = FALSE;
+
+
+ /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
+ * 2.0 version of the same class.
+ */
+ if ( device_class == 0x00000101 ) {
+ device_class = 0x00030000;
+ }
+
+
+ /* Find PCI devices that match the given vendor ID. The vendor ID is
+ * either specified explicitly as a parameter to the function or
+ * implicitly encoded in the high bits of id->PCIid.
+ *
+ * The first device with a matching vendor is recorded, even if the
+ * device ID doesn't match. This is done because the Device section
+ * in the xorg.conf file can over-ride the device ID. A matching PCI
+ * ID might not be found now, but after the device ID over-ride is
+ * applied there /might/ be a match.
+ */
+ for (id = PCIchipsets; id->PCIid != -1; id++) {
+ const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
+ | vendorID;
+ const unsigned device_id = (id->PCIid & 0x0000FFFF);
+ const unsigned match_class = 0x00030000 | id->PCIid;
+
+ if ((vendor_id == pPci->vendor_id)
+ || ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
+ if (!foundVendor && (instances != NULL)) {
+ ++allocatedInstances;
+ instances[allocatedInstances - 1].pci = pPci;
+ instances[allocatedInstances - 1].dev = NULL;
+ instances[allocatedInstances - 1].claimed = FALSE;
+ instances[allocatedInstances - 1].foundHW = FALSE;
+ instances[allocatedInstances - 1].screen = 0;
+ }
+
+ foundVendor = TRUE;
+
+ if ( (device_id == pPci->device_id)
+ || ((vendorID == PCI_VENDOR_GENERIC)
+ && (match_class == device_class)) ) {
+ if ( instances != NULL ) {
+ instances[allocatedInstances - 1].foundHW = TRUE;
+ instances[allocatedInstances - 1].chip = id->numChipset;
+ }
+
+
+ if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
+ if (xf86CheckPciSlot(pPci)) {
+ GDevPtr pGDev =
+ xf86AddBusDeviceToConfigure(drvp->driverName,
+ BUS_PCI, pPci, -1);
+ if (pGDev) {
+ /* After configure pass 1, chipID and chipRev
+ * are treated as over-rides, so clobber them
+ * here.
+ */
+ pGDev->chipID = -1;
+ pGDev->chipRev = -1;
+ }
+
+ numFound++;
+ }
+ }
+ else {
+ numFound++;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+
+ /* In "probe only" or "configure" mode (signaled by instances being NULL),
+ * our work is done. Return the number of detected devices.
+ */
+ if ( instances == NULL ) {
+ return numFound;
+ }
+
+
+ /*
+ * This may be debatable, but if no PCI devices with a matching vendor
+ * type is found, return zero now. It is probably not desirable to
+ * allow the config file to override this.
+ */
+ if (allocatedInstances <= 0) {
+ free(instances);
+ return 0;
+ }
+
+
+ DebugF("%s instances found: %d\n", driverName, allocatedInstances);
+
+ /*
+ * Check for devices that need duplicated instances. This is required
+ * when there is more than one screen per entity.
+ *
+ * XXX This currently doesn't work for cases where the BusID isn't
+ * specified explicitly in the config file.
+ */
+
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->screen > 0 && devList[j]->busID
+ && *devList[j]->busID) {
+ for (i = 0; i < allocatedInstances; i++) {
+ pPci = instances[i].pci;
+ if (xf86ComparePciBusString(devList[j]->busID,
+ PCI_MAKE_BUS( pPci->domain, pPci->bus ),
+ pPci->dev,
+ pPci->func)) {
+ allocatedInstances++;
+ instances[allocatedInstances - 1] = instances[i];
+ instances[allocatedInstances - 1].screen =
+ devList[j]->screen;
+ numFound++;
+ break;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < allocatedInstances; i++) {
+ GDevPtr dev = NULL;
+ GDevPtr devBus = NULL;
+
+ pPci = instances[i].pci;
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->busID && *devList[j]->busID) {
+ if (xf86ComparePciBusString(devList[j]->busID,
+ PCI_MAKE_BUS( pPci->domain, pPci->bus ),
+ pPci->dev,
+ pPci->func) &&
+ devList[j]->screen == instances[i].screen) {
+
+ if (devBus)
+ xf86MsgVerb(X_WARNING,0,
+ "%s: More than one matching Device section for "
+ "instances\n\t(BusID: %s) found: %s\n",
+ driverName, devList[j]->busID,
+ devList[j]->identifier);
+ else
+ devBus = devList[j];
+ }
+ } else {
+ /*
+ * if device section without BusID is found
+ * only assign to it to the primary device.
+ */
+ if (xf86IsPrimaryPci(pPci)) {
+ xf86Msg(X_PROBED, "Assigning device section with no busID"
+ " to primary device\n");
+ if (dev || devBus)
+ xf86MsgVerb(X_WARNING, 0,
+ "%s: More than one matching Device section "
+ "found: %s\n", driverName, devList[j]->identifier);
+ else
+ dev = devList[j];
+ }
+ }
+ }
+ if (devBus) dev = devBus; /* busID preferred */
+ if (!dev) {
+ if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID PCI:%u@%u:%u:%u) found\n",
+ driverName, pPci->domain, pPci->bus, pPci->dev,
+ pPci->func);
+ }
+ } else {
+ numClaimedInstances++;
+ instances[i].claimed = TRUE;
+ instances[i].dev = dev;
+ }
+ }
+ DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
+ /*
+ * Now check that a chipset or chipID override in the device section
+ * is valid. Chipset has precedence over chipID.
+ * If chipset is not valid ignore BusSlot completely.
+ */
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+ MessageType from = X_PROBED;
+
+ if (!instances[i].claimed) {
+ continue;
+ }
+ if (instances[i].dev->chipset) {
+ for (c = chipsets; c->token >= 0; c++) {
+ if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
+ break;
+ }
+ if (c->token == -1) {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
+ "section \"%s\" isn't valid for this driver\n",
+ driverName, instances[i].dev->chipset,
+ instances[i].dev->identifier);
+ } else {
+ instances[i].chip = c->token;
+
+ for (id = PCIchipsets; id->numChipset >= 0; id++) {
+ if (id->numChipset == instances[i].chip)
+ break;
+ }
+ if(id->numChipset >=0){
+ xf86Msg(X_CONFIG,"Chipset override: %s\n",
+ instances[i].dev->chipset);
+ from = X_CONFIG;
+ } else {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
+ "section \"%s\" isn't a valid PCI chipset\n",
+ driverName, instances[i].dev->chipset,
+ instances[i].dev->identifier);
+ }
+ }
+ } else if (instances[i].dev->chipID > 0) {
+ for (id = PCIchipsets; id->numChipset >= 0; id++) {
+ if (id->PCIid == instances[i].dev->chipID)
+ break;
+ }
+ if (id->numChipset == -1) {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
+ "section \"%s\" isn't valid for this driver\n",
+ driverName, instances[i].dev->chipID,
+ instances[i].dev->identifier);
+ } else {
+ instances[i].chip = id->numChipset;
+
+ xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
+ instances[i].dev->chipID);
+ from = X_CONFIG;
+ }
+ } else if (!instances[i].foundHW) {
+ /*
+ * This means that there was no override and the PCI chipType
+ * doesn't match one that is supported
+ */
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ }
+ if (instances[i].claimed == TRUE){
+ for (c = chipsets; c->token >= 0; c++) {
+ if (c->token == instances[i].chip)
+ break;
+ }
+ xf86Msg(from,"Chipset %s found\n",
+ c->name);
+ }
+ }
+
+ /*
+ * Of the claimed instances, check that another driver hasn't already
+ * claimed its slot.
+ */
+ numFound = 0;
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+
+ if (!instances[i].claimed)
+ continue;
+ pPci = instances[i].pci;
+
+
+ /*
+ * Allow the same entity to be used more than once for devices with
+ * multiple screens per entity. This assumes implicitly that there
+ * will be a screen == 0 instance.
+ *
+ * XXX Need to make sure that two different drivers don't claim
+ * the same screen > 0 instance.
+ */
+ if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
+ continue;
+
+ DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
+ driverName, pPci->bus, pPci->dev, pPci->func);
+
+ /* Allocate an entry in the lists to be returned */
+ numFound++;
+ retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+ retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
+ instances[i].chip,
+ instances[i].dev,
+ instances[i].dev->active);
+ if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
+ for (j = 0; j < xf86NumEntities; j++) {
+ EntityPtr pEnt = xf86Entities[j];
+ if (pEnt->bus.type != BUS_PCI)
+ continue;
+ if (pEnt->bus.id.pci == pPci) {
+ retEntities[numFound - 1] = j;
+ xf86AddDevToEntity(j, instances[i].dev);
+ break;
+ }
+ }
+ }
+ }
+ free(instances);
+ if (numFound > 0) {
+ *foundEntities = retEntities;
+ }
+
+ return numFound;
+}
+
+/*
+ * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
+ */
+void
+xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
+ int maskval, int knownclkindex, int knownclkvalue)
+{
+ register int status = vertsyncreg;
+ unsigned long i, cnt, rcnt, sync;
+
+ /* First save registers that get written on */
+ (*ClockFunc)(pScrn, CLK_REG_SAVE);
+
+ if (num > MAXCLOCKS)
+ num = MAXCLOCKS;
+
+ for (i = 0; i < num; i++)
+ {
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, TRUE);
+ if (!(*ClockFunc)(pScrn, i))
+ {
+ pScrn->clock[i] = -1;
+ continue;
+ }
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, FALSE);
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, FALSE);
+
+ usleep(50000); /* let VCO stabilise */
+
+ cnt = 0;
+ sync = 200000;
+
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == maskval)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+
+ for (rcnt = 0; rcnt < 5; rcnt++)
+ {
+ while (!(inb(status) & maskval))
+ cnt++;
+ while ((inb(status) & maskval))
+ cnt++;
+ }
+
+finish:
+ pScrn->clock[i] = cnt ? cnt : -1;
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, TRUE);
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ if (i != knownclkindex)
+ {
+ if (pScrn->clock[i] == -1)
+ {
+ pScrn->clock[i] = 0;
+ }
+ else
+ {
+ pScrn->clock[i] = (int)(0.5 +
+ (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
+ (pScrn->clock[i]));
+ /* Round to nearest 10KHz */
+ pScrn->clock[i] += 5;
+ pScrn->clock[i] /= 10;
+ pScrn->clock[i] *= 10;
+ }
+ }
+ }
+
+ pScrn->clock[knownclkindex] = knownclkvalue;
+ pScrn->numClocks = num;
+
+ /* Restore registers that were written on */
+ (*ClockFunc)(pScrn, CLK_REG_RESTORE);
+}
+
+const char *
+xf86GetVisualName(int visual)
+{
+ if (visual < 0 || visual > DirectColor)
+ return NULL;
+
+ return xf86VisualNames[visual];
+}
+
+
+int
+xf86GetVerbosity(void)
+{
+ return max(xf86Verbose, xf86LogVerbose);
+}
+
+Pix24Flags
+xf86GetPix24(void)
+{
+ return xf86Info.pixmap24;
+}
+
+
+int
+xf86GetDepth(void)
+{
+ return xf86Depth;
+}
+
+
+rgb
+xf86GetWeight(void)
+{
+ return xf86Weight;
+}
+
+
+Gamma
+xf86GetGamma(void)
+{
+ return xf86Gamma;
+}
+
+
+Bool
+xf86GetFlipPixels(void)
+{
+ return xf86FlipPixels;
+}
+
+
+const char *
+xf86GetServerName(void)
+{
+ return xf86ServerName;
+}
+
+
+Bool
+xf86ServerIsExiting(void)
+{
+ return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
+}
+
+
+Bool
+xf86ServerIsResetting(void)
+{
+ return xf86Resetting;
+}
+
+
+Bool
+xf86ServerIsInitialising(void)
+{
+ return xf86Initialising;
+}
+
+
+Bool
+xf86ServerIsOnlyDetecting(void)
+{
+ return xf86DoConfigure;
+}
+
+
+Bool
+xf86CaughtSignal(void)
+{
+ return xf86Info.caughtSignal;
+}
+
+
+Bool
+xf86GetVidModeAllowNonLocal(void)
+{
+ return xf86Info.vidModeAllowNonLocal;
+}
+
+
+Bool
+xf86GetVidModeEnabled(void)
+{
+ return xf86Info.vidModeEnabled;
+}
+
+Bool
+xf86GetModInDevAllowNonLocal(void)
+{
+ return xf86Info.miscModInDevAllowNonLocal;
+}
+
+
+Bool
+xf86GetModInDevEnabled(void)
+{
+ return xf86Info.miscModInDevEnabled;
+}
+
+
+Bool
+xf86GetAllowMouseOpenFail(void)
+{
+ return xf86Info.allowMouseOpenFail;
+}
+
+
+Bool
+xf86IsPc98(void)
+{
+#if SUPPORT_PC98
+ return xf86Info.pc98;
+#else
+ return FALSE;
+#endif
+}
+
+void
+xf86DisableRandR(void)
+{
+ xf86Info.disableRandR = TRUE;
+ xf86Info.randRFrom = X_PROBED;
+}
+
+CARD32
+xf86GetModuleVersion(pointer module)
+{
+ return (CARD32)LoaderGetModuleVersion(module);
+}
+
+pointer
+xf86LoadDrvSubModule(DriverPtr drv, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ return ret;
+}
+
+pointer
+xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
+ return ret;
+}
+
+/*
+ * xf86LoadOneModule loads a single module.
+ */
+pointer
+xf86LoadOneModule(char *name, pointer opt)
+{
+ int errmaj, errmin;
+ char *Name;
+ pointer mod;
+
+ if (!name)
+ return NULL;
+
+ /* Normalise the module name */
+ Name = xf86NormalizeName(name);
+
+ /* Skip empty names */
+ if (Name == NULL)
+ return NULL;
+ if (*Name == '\0') {
+ free(Name);
+ return NULL;
+ }
+
+ mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
+ if (!mod)
+ LoaderErrorMsg(NULL, Name, errmaj, errmin);
+ free(Name);
+ return mod;
+}
+
+void
+xf86UnloadSubModule(pointer mod)
+{
+ /*
+ * This is disabled for now. The loader isn't smart enough yet to undo
+ * relocations.
+ */
+#if 0
+ UnloadSubModule(mod);
+#endif
+}
+
+Bool
+xf86LoaderCheckSymbol(const char *name)
+{
+ return LoaderSymbol(name) != NULL;
+}
+
+typedef enum {
+ OPTION_BACKING_STORE
+} BSOpts;
+
+static const OptionInfoRec BSOptions[] = {
+ { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetBackingStore(ScreenPtr pScreen)
+{
+ Bool useBS = FALSE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(BSOptions));
+ (void)memcpy(options, BSOptions, sizeof(BSOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ if (xf86bsEnableFlag) {
+ from = X_CMDLINE;
+ useBS = TRUE;
+ } else if (xf86bsDisableFlag) {
+ from = X_CMDLINE;
+ useBS = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
+ from = X_CONFIG;
+ }
+ free(options);
+ pScreen->backingStoreSupport = useBS ? Always : NotUseful;
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
+ useBS ? "enabled" : "disabled");
+}
+
+
+typedef enum {
+ OPTION_SILKEN_MOUSE
+} SMOpts;
+
+static const OptionInfoRec SMOptions[] = {
+ { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetSilkenMouse (ScreenPtr pScreen)
+{
+ Bool useSM = TRUE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(SMOptions));
+ (void)memcpy(options, SMOptions, sizeof(SMOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ /* disable if screen shares resources */
+ /* TODO VGA arb disable silken mouse */
+ if (xf86silkenMouseDisableFlag) {
+ from = X_CMDLINE;
+ useSM = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
+ from = X_CONFIG;
+ }
+ free(options);
+ /*
+ * XXX quick hack to report correctly for OSs that can't do SilkenMouse
+ * yet. Should handle this differently so that alternate async methods
+ * work correctly with this too.
+ */
+ pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
+ pScrn->silkenMouse ? "enabled" : "disabled");
+}
+
+/* Wrote this function for the PM2 Xv driver, preliminary. */
+
+pointer
+xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
+ char **adaptor_name, pointer *adaptor_options)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ confXvAdaptorPtr adaptor;
+ int i;
+
+ if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
+ if (adaptor_name) *adaptor_name = NULL;
+ if (adaptor_options) *adaptor_options = NULL;
+ return NULL;
+ }
+
+ adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
+ if (adaptor_name) *adaptor_name = adaptor->identifier;
+ if (adaptor_options) *adaptor_options = adaptor->options;
+
+ for (i = 0; i < adaptor->numports; i++)
+ if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
+ return adaptor->ports[i].options;
+
+ return NULL;
+}
+
+/* Rather than duplicate loader's get OS function, just include it directly */
+#define LoaderGetOS xf86GetOS
+#include "loader/os.c"
+
+/* new RAC */
+/*
+ * xf86ConfigPciEntityInactive() -- This function can be used
+ * to configure an inactive entity as well as to reconfigure an
+ * previously active entity inactive. If the entity has been
+ * assigned to a screen before it will be removed. If p_chip is
+ * non-NULL all static resources listed there will be registered.
+ */
+static void
+xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
+ EntityProc init, EntityProc enter,
+ EntityProc leave, pointer private)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
+ xf86RemoveEntityFromScreen(pScrn,pEnt->index);
+
+ /* shared resources are only needed when entity is active: remove */
+ xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
+}
+
+static void
+xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
+ xf86RemoveEntityFromScreen(pScrn,pEnt->index);
+ xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
+}
+
+ScrnInfoPtr
+xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
+ PciChipsets *p_chip, void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return pScrn;
+
+ if (!(pEnt->location.type == BUS_PCI)
+ || !xf86GetPciInfoForEntity(entityIndex)) {
+ free(pEnt);
+ return pScrn;
+ }
+ if (!pEnt->active) {
+ xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
+ leave, private);
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pScrn)
+ pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
+ if (xf86IsEntitySharable(entityIndex)) {
+ xf86SetEntityShared(entityIndex);
+ }
+ xf86AddEntityToScreen(pScrn,entityIndex);
+ if (xf86IsEntityShared(entityIndex)) {
+ return pScrn;
+ }
+ free(pEnt);
+
+ xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
+
+ return pScrn;
+}
+
+ScrnInfoPtr
+xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
+ EntityProc init, EntityProc enter, EntityProc leave,
+ pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return pScrn;
+
+ if (!(pEnt->location.type == BUS_NONE)) {
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pEnt->active) {
+ xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pScrn)
+ pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
+ xf86AddEntityToScreen(pScrn,entityIndex);
+
+ xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
+
+ return pScrn;
+}
+
+/*
+ *
+ * OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
+ * It is likely to be removed. Don't use!
+ */
+
+Bool
+xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
+ PciChipsets *p_chip, void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return FALSE;
+
+ if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
+ free(pEnt);
+ return FALSE;
+ }
+ xf86AddEntityToScreen(pScrn,entityIndex);
+
+ free(pEnt);
+ if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+xf86IsScreenPrimary(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int i;
+
+ for (i=0 ; i < pScrn->numEntities; i++) {
+ if (xf86IsEntityPrimary(i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
+ int format, unsigned long len, pointer value )
+{
+ RootWinPropPtr pNewProp = NULL, pRegProp;
+ int i;
+ Bool existing = FALSE;
+
+ DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
+ ScrnIndex, property, type, format, len, value);
+
+ if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
+ return(BadMatch);
+ }
+
+ if (xf86RegisteredPropertiesTable &&
+ xf86RegisteredPropertiesTable[ScrnIndex]) {
+ for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ pNewProp; pNewProp = pNewProp->next) {
+ if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
+ break;
+ }
+ }
+
+ if (!pNewProp) {
+ if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
+ return(BadAlloc);
+ }
+ /*
+ * We will put this property at the end of the list so that
+ * the changes are made in the order they were requested.
+ */
+ pNewProp->next = NULL;
+ } else {
+ if (pNewProp->name)
+ free(pNewProp->name);
+ existing = TRUE;
+ }
+
+ pNewProp->name = xnfstrdup(NameForAtom(property));
+ pNewProp->type = type;
+ pNewProp->format = format;
+ pNewProp->size = len;
+ pNewProp->data = value;
+
+ DebugF("new property filled\n");
+
+ if (NULL==xf86RegisteredPropertiesTable) {
+ DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
+ xf86NumScreens);
+ if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
+ return(BadAlloc);
+ }
+ for (i=0; i<xf86NumScreens; i++) {
+ xf86RegisteredPropertiesTable[i] = NULL;
+ }
+ }
+
+ DebugF("xf86RegisteredPropertiesTable %p\n",
+ (void *)xf86RegisteredPropertiesTable);
+ DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
+ ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
+
+ if (!existing) {
+ if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
+ xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
+ } else {
+ pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ while (pRegProp->next != NULL) {
+ DebugF("- next %p\n", (void *)pRegProp);
+ pRegProp = pRegProp->next;
+ }
+ pRegProp->next = pNewProp;
+ }
+ }
+ DebugF("xf86RegisterRootWindowProperty succeeded\n");
+ return(Success);
+}
+
+Bool
+xf86IsUnblank(int mode)
+{
+ switch(mode) {
+ case SCREEN_SAVER_OFF:
+ case SCREEN_SAVER_FORCER:
+ return TRUE;
+ case SCREEN_SAVER_ON:
+ case SCREEN_SAVER_CYCLE:
+ return FALSE;
+ default:
+ xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
+ return TRUE;
+ }
+}
+
+void
+xf86MotionHistoryAllocate(LocalDevicePtr local)
+{
+ AllocateMotionHistory(local->dev);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 55d7a6209..d78d3d1db 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -1,1822 +1,1822 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-/*
- * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-
-#undef HAS_UTSNAME
-#if !defined(WIN32)
-#define HAS_UTSNAME 1
-#include <sys/utsname.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "input.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "site.h"
-#include "mi.h"
-
-#include "compiler.h"
-
-#include "loaderProcs.h"
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#define XF86_OS_PRIVS
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xorgVersion.h"
-#include "xf86Build.h"
-#include "mipointer.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "picturestr.h"
-
-#include "xf86VGAarbiter.h"
-#include "globals.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
-#include <pciaccess.h>
-#include "Pci.h"
-#include "xf86Bus.h"
-
-#include <hotplug.h>
-
-/* forward declarations */
-static Bool probe_devices_from_device_sections(DriverPtr drvp);
-static Bool add_matching_devices_to_configure_list(DriverPtr drvp);
-
-#ifdef XF86PM
-void (*xf86OSPMClose)(void) = NULL;
-#endif
-static Bool xorgHWOpenConsole = FALSE;
-
-/* Common pixmap formats */
-
-static PixmapFormatRec formats[MAXFORMATS] = {
- { 1, 1, BITMAP_SCANLINE_PAD },
- { 4, 8, BITMAP_SCANLINE_PAD },
- { 8, 8, BITMAP_SCANLINE_PAD },
- { 15, 16, BITMAP_SCANLINE_PAD },
- { 16, 16, BITMAP_SCANLINE_PAD },
- { 24, 32, BITMAP_SCANLINE_PAD },
- { 32, 32, BITMAP_SCANLINE_PAD },
-};
-static int numFormats = 7;
-static Bool formatsDone = FALSE;
-
-#ifndef OSNAME
-#define OSNAME " unknown"
-#endif
-#ifndef OSVENDOR
-#define OSVENDOR ""
-#endif
-#ifndef PRE_RELEASE
-#define PRE_RELEASE XORG_VERSION_SNAP
-#endif
-
-static void
-xf86PrintBanner(void)
-{
-#if PRE_RELEASE
- xf86ErrorFVerb(0, "\n"
- "This is a pre-release version of the X server from " XVENDORNAME ".\n"
- "It is not supported in any way.\n"
- "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
- "Select the \"xorg\" product for bugs you find in this release.\n"
- "Before reporting bugs in pre-release versions please check the\n"
- "latest version in the X.Org Foundation git repository.\n"
- "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
-#endif
- xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
- XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR,
- XORG_VERSION_PATCH);
-#if XORG_VERSION_SNAP > 0
- xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
-#endif
-
-#if XORG_VERSION_SNAP >= 900
- /* When the minor number is 99, that signifies that the we are making
- * a release candidate for a major version. (X.0.0)
- * When the patch number is 99, that signifies that the we are making
- * a release candidate for a minor version. (X.Y.0)
- * When the patch number is < 99, then we are making a release
- * candidate for the next point release. (X.Y.Z)
- */
-#if XORG_VERSION_MINOR >= 99
- xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
- XORG_VERSION_SNAP - 900);
-#elif XORG_VERSION_PATCH == 99
- xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
-#else
- xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
- XORG_VERSION_SNAP - 900);
-#endif
-#endif
-
-#ifdef XORG_CUSTOM_VERSION
- xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
-#endif
-#ifndef XORG_DATE
-# define XORG_DATE "Unknown"
-#endif
- xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
- xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
- X_PROTOCOL, X_PROTOCOL_REVISION);
- xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
-#ifdef HAS_UTSNAME
- {
- struct utsname name;
-
- /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
- and Irix) and Single Unix Spec 3 just say that non-negative is success.
- All agree that failure is represented by a negative number.
- */
- if (uname(&name) >= 0) {
- xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
- name.sysname, name.nodename, name.release, name.version, name.machine);
-#ifdef linux
- do {
- char buf[80];
- int fd = open("/proc/cmdline", O_RDONLY);
- if (fd != -1) {
- xf86ErrorFVerb(0, "Kernel command line: ");
- memset(buf, 0, 80);
- while (read(fd, buf, 80) > 0) {
- xf86ErrorFVerb(0, "%.80s", buf);
- memset(buf, 0, 80);
- }
- close(fd);
- }
- } while (0);
-#endif
- }
- }
-#endif
-#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
- {
- struct tm t;
- char buf[100];
-
- bzero(&t, sizeof(t));
- bzero(buf, sizeof(buf));
- t.tm_mday = BUILD_DATE % 100;
- t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
- t.tm_year = BUILD_DATE / 10000 - 1900;
-#if defined(BUILD_TIME)
- t.tm_sec = BUILD_TIME % 100;
- t.tm_min = (BUILD_TIME / 100) % 100;
- t.tm_hour = (BUILD_TIME / 10000) % 100;
- if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#else
- if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#endif
- }
-#endif
-#if defined(BUILDERSTRING)
- xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
-#endif
- xf86ErrorFVerb(0, "Current version of pixman: %s\n",
- pixman_version_string());
- xf86ErrorFVerb(0, "\tBefore reporting problems, check "
- ""__VENDORDWEBSUPPORT__"\n"
- "\tto make sure that you have the latest version.\n");
-}
-
-static void
-xf86PrintMarkers(void)
-{
- LogPrintMarkers();
-}
-
-static Bool
-xf86CreateRootWindow(WindowPtr pWin)
-{
- int ret = TRUE;
- int err = Success;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootWinPropPtr pProp;
- CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
- dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
-
- DebugF("xf86CreateRootWindow(%p)\n", pWin);
-
- if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
- /* Can't find hook we are hung on */
- xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
- "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
- (void *)xf86CreateRootWindow,
- (void *)pScreen->CreateWindow );
- }
-
- /* Unhook this function ... */
- pScreen->CreateWindow = CreateWindow;
- dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
-
- /* ... and call the previous CreateWindow fuction, if any */
- if (NULL!=pScreen->CreateWindow) {
- ret = (*pScreen->CreateWindow)(pWin);
- }
-
- /* Now do our stuff */
- if (xf86RegisteredPropertiesTable != NULL) {
- if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
- for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
- pProp != NULL && err==Success;
- pProp = pProp->next )
- {
- Atom prop;
-
- prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
- err = dixChangeWindowProperty(serverClient, pWin,
- prop, pProp->type,
- pProp->format, PropModeReplace,
- pProp->size, pProp->data,
- FALSE);
- }
-
- /* Look at err */
- ret &= (err==Success);
-
- } else {
- xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
- "non-root window %p (parent %p)\n",
- (void *)pWin, (void *)pWin->parent);
- ret = FALSE;
- }
- }
-
- DebugF("xf86CreateRootWindow() returns %d\n", ret);
- return (ret);
-}
-
-
-static void
-InstallSignalHandlers(void)
-{
- /*
- * Install signal handler for unexpected signals
- */
- xf86Info.caughtSignal=FALSE;
- if (!xf86Info.notrapSignals) {
- OsRegisterSigWrapper(xf86SigWrapper);
- } else {
- signal(SIGSEGV, SIG_DFL);
- signal(SIGILL, SIG_DFL);
-#ifdef SIGEMT
- signal(SIGEMT, SIG_DFL);
-#endif
- signal(SIGFPE, SIG_DFL);
-#ifdef SIGBUS
- signal(SIGBUS, SIG_DFL);
-#endif
-#ifdef SIGSYS
- signal(SIGSYS, SIG_DFL);
-#endif
-#ifdef SIGXCPU
- signal(SIGXCPU, SIG_DFL);
-#endif
-#ifdef SIGXFSZ
- signal(SIGXFSZ, SIG_DFL);
-#endif
- }
-}
-
-
-#define END_OF_MATCHES(m) \
- (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
-
-Bool
-probe_devices_from_device_sections(DriverPtr drvp)
-{
- int i, j;
- struct pci_device * pPci;
- Bool foundScreen = FALSE;
- const struct pci_id_match * const devices = drvp->supported_devices;
- GDevPtr *devList;
- const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
-
-
- for ( i = 0 ; i < numDevs ; i++ ) {
- struct pci_device_iterator *iter;
- unsigned device_id;
-
-
- /* Find the pciVideoRec associated with this device section.
- */
- iter = pci_id_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- if (devList[i]->busID && *devList[i]->busID) {
- if (xf86ComparePciBusString(devList[i]->busID,
- ((pPci->domain << 8)
- | pPci->bus),
- pPci->dev,
- pPci->func)) {
- break;
- }
- }
- else if (xf86IsPrimaryPci(pPci)) {
- break;
- }
- }
-
- pci_iterator_destroy(iter);
-
- if (pPci == NULL) {
- continue;
- }
-
- device_id = (devList[i]->chipID > 0)
- ? devList[i]->chipID : pPci->device_id;
-
-
- /* Once the pciVideoRec is found, determine if the device is supported
- * by the driver. If it is, probe it!
- */
- for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
- if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
- && PCI_ID_COMPARE( devices[j].device_id, device_id )
- && ((devices[j].device_class_mask & pPci->device_class)
- == devices[j].device_class) ) {
- int entry;
-
- /* Allow the same entity to be used more than once for
- * devices with multiple screens per entity. This assumes
- * implicitly that there will be a screen == 0 instance.
- *
- * FIXME Need to make sure that two different drivers don't
- * FIXME claim the same screen > 0 instance.
- */
- if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
- continue;
-
- DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
- drvp->driverName, pPci->bus, pPci->dev, pPci->func);
-
- /* Allocate an entry in the lists to be returned */
- entry = xf86ClaimPciSlot(pPci, drvp, device_id,
- devList[i], devList[i]->active);
-
- if ((entry == -1) && (devList[i]->screen > 0)) {
- unsigned k;
-
- for ( k = 0; k < xf86NumEntities; k++ ) {
- EntityPtr pEnt = xf86Entities[k];
- if (pEnt->bus.type != BUS_PCI)
- continue;
-
- if (pEnt->bus.id.pci == pPci) {
- entry = k;
- xf86AddDevToEntity(k, devList[i]);
- break;
- }
- }
- }
-
- if (entry != -1) {
- if ((*drvp->PciProbe)(drvp, entry, pPci,
- devices[j].match_data)) {
- foundScreen = TRUE;
- } else
- xf86UnclaimPciSlot(pPci);
- }
-
- break;
- }
- }
- }
- xfree(devList);
-
- return foundScreen;
-}
-
-
-Bool
-add_matching_devices_to_configure_list(DriverPtr drvp)
-{
- const struct pci_id_match * const devices = drvp->supported_devices;
- int j;
- struct pci_device *pPci;
- struct pci_device_iterator *iter;
- int numFound = 0;
-
-
- iter = pci_id_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- /* Determine if this device is supported by the driver. If it is,
- * add it to the list of devices to configure.
- */
- for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
- if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
- && PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
- && ((devices[j].device_class_mask & pPci->device_class)
- == devices[j].device_class) ) {
- if (xf86CheckPciSlot(pPci)) {
- GDevPtr pGDev = xf86AddBusDeviceToConfigure(
- drvp->driverName, BUS_PCI, pPci, -1);
- if (pGDev != NULL) {
- /* After configure pass 1, chipID and chipRev are
- * treated as over-rides, so clobber them here.
- */
- pGDev->chipID = -1;
- pGDev->chipRev = -1;
- }
-
- numFound++;
- }
-
- break;
- }
- }
- }
-
- pci_iterator_destroy(iter);
-
-
- return (numFound != 0);
-}
-
-/**
- * Call the driver's correct probe function.
- *
- * If the driver implements the \c DriverRec::PciProbe entry-point and an
- * appropriate PCI device (with matching Device section in the xorg.conf file)
- * is found, it is called. If \c DriverRec::PciProbe or no devices can be
- * successfully probed with it (e.g., only non-PCI devices are available),
- * the driver's \c DriverRec::Probe function is called.
- *
- * \param drv Driver to probe
- *
- * \return
- * If a device can be successfully probed by the driver, \c TRUE is
- * returned. Otherwise, \c FALSE is returned.
- */
-Bool
-xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
-{
- Bool foundScreen = FALSE;
-
- if ( drv->PciProbe != NULL ) {
- if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
- assert( detect_only );
- foundScreen = add_matching_devices_to_configure_list( drv );
- }
- else {
- assert( ! detect_only );
- foundScreen = probe_devices_from_device_sections( drv );
- }
- }
-
- if ( ! foundScreen && (drv->Probe != NULL) ) {
- xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
- drv->driverName );
- foundScreen = (*drv->Probe)( drv, (detect_only) ? PROBE_DETECT
- : PROBE_DEFAULT );
- }
-
- return foundScreen;
-}
-
-/*
- * InitOutput --
- * Initialize screenInfo for all actually accessible framebuffers.
- * That includes vt-manager setup, querying all possible devices and
- * collecting the pixmap formats.
- */
-void
-InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
-{
- int i, j, k, scr_index;
- char **modulelist;
- pointer *optionlist;
- screenLayoutPtr layout;
- Pix24Flags screenpix24, pix24;
- MessageType pix24From = X_DEFAULT;
- Bool pix24Fail = FALSE;
- Bool autoconfig = FALSE;
- GDevPtr configured_device;
-
- xf86Initialising = TRUE;
-
- if (serverGeneration == 1) {
- if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
- xf86ServerName++;
- else
- xf86ServerName = argv[0];
-
- xf86PrintBanner();
- xf86PrintMarkers();
- if (xf86LogFile) {
- time_t t;
- const char *ct;
- t = time(NULL);
- ct = ctime(&t);
- xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
- xf86LogFile, ct);
- }
-
- /* Read and parse the config file */
- if (!xf86DoConfigure && !xf86DoShowOptions) {
- switch (xf86HandleConfigFile(FALSE)) {
- case CONFIG_OK:
- break;
- case CONFIG_PARSE_ERROR:
- xf86Msg(X_ERROR, "Error parsing the config file\n");
- return;
- case CONFIG_NOFILE:
- autoconfig = TRUE;
- break;
- }
- }
-
- InstallSignalHandlers();
-
- /* Initialise the loader */
- LoaderInit();
-
- /* Tell the loader the default module search path */
- LoaderSetPath(xf86ModulePath);
-
- if (xf86Info.ignoreABI) {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- }
-
- if (xf86DoShowOptions)
- DoShowOptions();
-
- /* Do a general bus probe. This will be a PCI probe for x86 platforms */
- xf86BusProbe();
-
- if (xf86DoConfigure)
- DoConfigure();
-
- if (autoconfig) {
- if (!xf86AutoConfig()) {
- xf86Msg(X_ERROR, "Auto configuration failed\n");
- return;
- }
- }
-
-#ifdef XF86PM
- xf86OSPMClose = xf86OSPMOpen();
-#endif
-
- /* Load all modules specified explicitly in the config file */
- if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
- xf86LoadModules(modulelist, optionlist);
- xfree(modulelist);
- xfree(optionlist);
- }
-
- /* Load all driver modules specified in the config file */
- /* If there aren't any specified in the config file, autoconfig them */
- /* FIXME: Does not handle multiple active screen sections, but I'm not
- * sure if we really want to handle that case*/
- configured_device = xf86ConfigLayout.screens->screen->device;
- if ((!configured_device) || (!configured_device->driver)) {
- if (!autoConfigDevice(configured_device)) {
- xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
- return ;
- }
- }
- if ((modulelist = xf86DriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- xfree(modulelist);
- }
-
- /* Load all input driver modules specified in the config file. */
- if ((modulelist = xf86InputDriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- xfree(modulelist);
- }
-
- /*
- * It is expected that xf86AddDriver()/xf86AddInputDriver will be
- * called for each driver as it is loaded. Those functions save the
- * module pointers for drivers.
- * XXX Nothing keeps track of them for other modules.
- */
- /* XXX What do we do if not all of these could be loaded? */
-
- /*
- * At this point, xf86DriverList[] is all filled in with entries for
- * each of the drivers to try and xf86NumDrivers has the number of
- * drivers. If there are none, return now.
- */
-
- if (xf86NumDrivers == 0) {
- xf86Msg(X_ERROR, "No drivers available.\n");
- return;
- }
-
- /*
- * Call each of the Identify functions and call the driverFunc to check
- * if HW access is required. The Identify functions print out some
- * identifying information, and anything else that might be
- * needed at this early stage.
- */
-
- for (i = 0; i < xf86NumDrivers; i++) {
- if (xf86DriverList[i]->Identify != NULL)
- xf86DriverList[i]->Identify(0);
-
- if (!xorgHWAccess || !xorgHWOpenConsole) {
- xorgHWFlags flags;
- if(!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags))
- flags = HW_IO;
-
- if(NEED_IO_ENABLED(flags))
- xorgHWAccess = TRUE;
- if(!(flags & HW_SKIP_CONSOLE))
- xorgHWOpenConsole = TRUE;
- }
- }
-
- if (xorgHWOpenConsole)
- xf86OpenConsole();
- else
- xf86Info.dontVTSwitch = TRUE;
-
- /* Enable full I/O access */
- if (xorgHWAccess)
- xorgHWAccess = xf86EnableIO();
-
- /*
- * Locate bus slot that had register IO enabled at server startup
- */
- if (xorgHWAccess) {
- xf86AccessInit();
- xf86FindPrimaryDevice();
- }
- /*
- * Now call each of the Probe functions. Each successful probe will
- * result in an extra entry added to the xf86Screens[] list for each
- * instance of the hardware found.
- */
-
- for (i = 0; i < xf86NumDrivers; i++) {
- xorgHWFlags flags;
- if (!xorgHWAccess) {
- if (!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags)
- || NEED_IO_ENABLED(flags))
- continue;
- }
-
- xf86CallDriverProbe( xf86DriverList[i], FALSE );
- }
-
- /*
- * If nothing was detected, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR, "No devices detected.\n");
- return;
- }
-
- xf86VGAarbiterInit();
-
- /*
- * Match up the screens found by the probes against those specified
- * in the config file. Remove the ones that won't be used. Sort
- * them in the order specified.
- */
-
- /*
- * What is the best way to do this?
- *
- * For now, go through the screens allocated by the probes, and
- * look for screen config entry which refers to the same device
- * section as picked out by the probe.
- *
- */
-
- for (i = 0; i < xf86NumScreens; i++) {
- for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
- layout++) {
- Bool found = FALSE;
- for (j = 0; j < xf86Screens[i]->numEntities; j++) {
-
- GDevPtr dev =
- xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
- xf86Screens[i]->entityInstanceList[j]);
-
- if (dev == layout->screen->device) {
- /* A match has been found */
- xf86Screens[i]->confScreen = layout->screen;
- found = TRUE;
- break;
- }
- }
- if (found) break;
- }
- if (layout->screen == NULL) {
- /* No match found */
- xf86Msg(X_ERROR,
- "Screen %d deleted because of no matching config section.\n", i);
- xf86DeleteScreen(i--, 0);
- }
- }
-
- /*
- * If no screens left, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR,
- "Device(s) detected, but none match those in the config file.\n");
- return;
- }
-
- xf86PostProbe();
- xf86EntityInit();
-
- /*
- * Sort the drivers to match the requested ording. Using a slow
- * bubble sort.
- */
- for (j = 0; j < xf86NumScreens - 1; j++) {
- for (i = 0; i < xf86NumScreens - j - 1; i++) {
- if (xf86Screens[i + 1]->confScreen->screennum <
- xf86Screens[i]->confScreen->screennum) {
- ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
- xf86Screens[i + 1] = xf86Screens[i];
- xf86Screens[i] = tmpScrn;
- }
- }
- }
- /* Fix up the indexes */
- for (i = 0; i < xf86NumScreens; i++) {
- xf86Screens[i]->scrnIndex = i;
- }
-
- /*
- * Call the driver's PreInit()'s to complete initialisation for the first
- * generation.
- */
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterScrnInit(xf86Screens[i]);
- xf86VGAarbiterLock(xf86Screens[i]);
- if (xf86Screens[i]->PreInit &&
- xf86Screens[i]->PreInit(xf86Screens[i], 0))
- xf86Screens[i]->configured = TRUE;
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- for (i = 0; i < xf86NumScreens; i++)
- if (!xf86Screens[i]->configured)
- xf86DeleteScreen(i--, 0);
-
- /*
- * If no screens left, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR,
- "Screen(s) found, but none have a usable configuration.\n");
- return;
- }
-
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->name == NULL) {
- xf86Screens[i]->name = xnfalloc(strlen("screen") + 10 + 1);
- sprintf(xf86Screens[i]->name, "screen%d", i);
- xf86MsgVerb(X_WARNING, 0,
- "Screen driver %d has no name set, using `%s'.\n",
- i, xf86Screens[i]->name);
- }
- }
-
- /* Remove (unload) drivers that are not required */
- for (i = 0; i < xf86NumDrivers; i++)
- if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
- xf86DeleteDriver(i);
-
- /*
- * At this stage we know how many screens there are.
- */
-
- for (i = 0; i < xf86NumScreens; i++)
- xf86InitViewport(xf86Screens[i]);
-
- /*
- * Collect all pixmap formats and check for conflicts at the display
- * level. Should we die here? Or just delete the offending screens?
- */
- screenpix24 = Pix24DontCare;
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->imageByteOrder !=
- xf86Screens[0]->imageByteOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
- if (xf86Screens[i]->bitmapScanlinePad !=
- xf86Screens[0]->bitmapScanlinePad)
- FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
- if (xf86Screens[i]->bitmapScanlineUnit !=
- xf86Screens[0]->bitmapScanlineUnit)
- FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
- if (xf86Screens[i]->bitmapBitOrder !=
- xf86Screens[0]->bitmapBitOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
-
- /* Determine the depth 24 pixmap format the screens would like */
- if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
- if (screenpix24 == Pix24DontCare)
- screenpix24 = xf86Screens[i]->pixmap24;
- else if (screenpix24 != xf86Screens[i]->pixmap24)
- FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
- }
- }
- /* check if screenpix24 is consistent with the config/cmdline */
- if (xf86Info.pixmap24 != Pix24DontCare) {
- pix24 = xf86Info.pixmap24;
- pix24From = xf86Info.pix24From;
- if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
- pix24Fail = TRUE;
- } else if (screenpix24 != Pix24DontCare) {
- pix24 = screenpix24;
- pix24From = X_PROBED;
- } else
- pix24 = Pix24Use32;
-
- if (pix24Fail)
- FatalError("Screen(s) can't use the required depth 24 pixmap format"
- " (%d). Exiting\n", PIX24TOBPP(pix24));
-
- /* Initialise the depth 24 format */
- for (j = 0; j < numFormats && formats[j].depth != 24; j++)
- ;
- formats[j].bitsPerPixel = PIX24TOBPP(pix24);
-
- /* Collect additional formats */
- for (i = 0; i < xf86NumScreens; i++) {
- for (j = 0; j < xf86Screens[i]->numFormats; j++) {
- for (k = 0; ; k++) {
- if (k >= numFormats) {
- if (k >= MAXFORMATS)
- FatalError("Too many pixmap formats! Exiting\n");
- formats[k] = xf86Screens[i]->formats[j];
- numFormats++;
- break;
- }
- if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
- if ((formats[k].bitsPerPixel ==
- xf86Screens[i]->formats[j].bitsPerPixel) &&
- (formats[k].scanlinePad ==
- xf86Screens[i]->formats[j].scanlinePad))
- break;
- FatalError("Inconsistent pixmap format for depth %d."
- " Exiting\n", formats[k].depth);
- }
- }
- }
- }
- formatsDone = TRUE;
-
- if (xf86Info.vtno >= 0 ) {
-#define VT_ATOM_NAME "XFree86_VT"
- Atom VTAtom=-1;
- CARD32 *VT = NULL;
- int ret;
-
- /* This memory needs to stay available until the screen has been
- initialized, and we can create the property for real.
- */
- if ( (VT = xalloc(sizeof(CARD32)))==NULL ) {
- FatalError("Unable to make VT property - out of memory. Exiting...\n");
- }
- *VT = xf86Info.vtno;
-
- VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
-
- for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
- ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
- VTAtom, XA_INTEGER, 32,
- 1, VT );
- if (ret != Success)
- xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
- "Failed to register VT property\n");
- }
- }
-
- /* If a screen uses depth 24, show what the pixmap format is */
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->depth == 24) {
- xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
- PIX24TOBPP(pix24));
- break;
- }
- }
- } else {
- /*
- * serverGeneration != 1; some OSs have to do things here, too.
- */
- if (xorgHWOpenConsole)
- xf86OpenConsole();
-
-#ifdef XF86PM
- /*
- should we reopen it here? We need to deal with an already opened
- device. We could leave this to the OS layer. For now we simply
- close it here
- */
- if (xf86OSPMClose)
- xf86OSPMClose();
- if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
- xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
-#endif
-
- /* Make sure full I/O access is enabled */
- if (xorgHWAccess)
- xf86EnableIO();
- }
-
- /*
- * Use the previously collected parts to setup pScreenInfo
- */
-
- pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
- pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
- pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
- pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
- pScreenInfo->numPixmapFormats = numFormats;
- for (i = 0; i < numFormats; i++)
- pScreenInfo->formats[i] = formats[i];
-
- /* Make sure the server's VT is active */
-
- if (serverGeneration != 1) {
- xf86Resetting = TRUE;
- /* All screens are in the same state, so just check the first */
- if (!xf86Screens[0]->vtSema) {
-#ifdef HAS_USL_VTS
- ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
-#endif
- xf86AccessEnter();
- xf86EnterServerState(SETUP);
- }
- }
-#ifdef SCO325
- else {
- /*
- * Under SCO we must ack that we got the console at startup,
- * I think this is the safest way to assure it.
- */
- static int once = 1;
- if (once) {
- once = 0;
- if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
- xf86Msg(X_WARNING, "VT_ACKACQ failed");
- }
- }
-#endif /* SCO325 */
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterLock(xf86Screens[i]);
- /*
- * Almost everything uses these defaults, and many of those that
- * don't, will wrap them.
- */
- xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
-#ifdef XFreeXDGA
- xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
-#endif
- xf86Screens[i]->DPMSSet = NULL;
- xf86Screens[i]->LoadPalette = NULL;
- xf86Screens[i]->SetOverscan = NULL;
- xf86Screens[i]->DriverFunc = NULL;
- xf86Screens[i]->pScreen = NULL;
- scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- if (scr_index == i) {
- /*
- * Hook in our ScrnInfoRec, and initialise some other pScreen
- * fields.
- */
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86ScreenKey, xf86Screens[i]);
- xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
- /* The driver should set this, but make sure it is set anyway */
- xf86Screens[i]->vtSema = TRUE;
- } else {
- /* This shouldn't normally happen */
- FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
- }
-
- DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
- i, xf86Screens[i]->pScreen );
- DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
- i, xf86Screens[i]->pScreen->CreateWindow );
-
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86CreateRootWindowKey,
- xf86Screens[i]->pScreen->CreateWindow);
- xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
-
- if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
- {
- xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
- PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
- DDC ?
- (DDC->features.input_type ?
- SubPixelHorizontalRGB : SubPixelNone) :
- SubPixelUnknown);
- }
-#ifdef RANDR
- if (!xf86Info.disableRandR)
- xf86RandRInit (screenInfo.screens[scr_index]);
- xf86Msg(xf86Info.randRFrom, "RandR %s\n",
- xf86Info.disableRandR ? "disabled" : "enabled");
-#endif
- }
-
- xf86PostScreenInit();
-
- xf86InitOrigins();
-
- xf86Resetting = FALSE;
- xf86Initialising = FALSE;
-
- RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
- NULL);
-}
-
-/*
- * InitInput --
- * Initialize all supported input devices.
- */
-
-void
-InitInput(int argc, char **argv)
-{
- IDevPtr* pDev;
- DeviceIntPtr dev;
-
- xf86Info.vtRequestsPending = FALSE;
-
- mieqInit();
-
- GetEventList(&xf86Events);
-
- /* Call the PreInit function for each input device instance. */
- for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
- strcpy((*pDev)->driver, "kbd");
- }
-
- /* If one fails, the others will too */
- if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
- break;
- }
-
- config_init();
-}
-
-void
-CloseInput (void)
-{
- config_fini();
-}
-
-/*
- * OsVendorInit --
- * OS/Vendor-specific initialisations. Called from OsInit(), which
- * is called by dix before establishing the well known sockets.
- */
-
-void
-OsVendorInit(void)
-{
- static Bool beenHere = FALSE;
-
-#ifdef SIGCHLD
- signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
-#endif
-
- if (!beenHere) {
- umask(022);
- xf86LogInit();
- }
-
- /* Set stderr to non-blocking. */
-#ifndef O_NONBLOCK
-#if defined(FNDELAY)
-#define O_NONBLOCK FNDELAY
-#elif defined(O_NDELAY)
-#define O_NONBLOCK O_NDELAY
-#endif
-
-#ifdef O_NONBLOCK
- if (!beenHere) {
- if (geteuid() == 0 && getuid() != geteuid())
- {
- int status;
-
- status = fcntl(fileno(stderr), F_GETFL, 0);
- if (status != -1) {
- fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
- }
- }
- }
-#endif
-#endif
-
- beenHere = TRUE;
-}
-
-/*
- * ddxGiveUp --
- * Device dependent cleanup. Called by by dix before normal server death.
- * For SYSV386 we must switch the terminal back to normal mode. No error-
- * checking here, since there should be restored as much as possible.
- */
-
-void
-ddxGiveUp(void)
-{
- int i;
-
- xf86VGAarbiterFini();
-
-#ifdef XF86PM
- if (xf86OSPMClose)
- xf86OSPMClose();
- xf86OSPMClose = NULL;
-#endif
-
- for (i = 0; i < xf86NumScreens; i++) {
- /*
- * zero all access functions to
- * trap calls when switched away.
- */
- xf86Screens[i]->vtSema = FALSE;
- }
-
-#ifdef XFreeXDGA
- DGAShutdown();
-#endif
-
- if (xorgHWOpenConsole)
- xf86CloseConsole();
-
- xf86CloseLog();
-
- /* If an unexpected signal was caught, dump a core for debugging */
- if (xf86Info.caughtSignal)
- OsAbort();
-}
-
-
-
-/*
- * AbortDDX --
- * DDX - specific abort routine. Called by AbortServer(). The attempt is
- * made to restore all original setting of the displays. Also all devices
- * are closed.
- */
-
-void
-AbortDDX(void)
-{
- int i;
-
- /*
- * try to restore the original video state
- */
-#ifdef DPMSExtension /* Turn screens back on */
- if (DPMSPowerLevel != DPMSModeOn)
- DPMSSet(serverClient, DPMSModeOn);
-#endif
- if (xf86Screens) {
- if (xf86Screens[0]->vtSema)
- xf86EnterServerState(SETUP);
- for (i = 0; i < xf86NumScreens; i++)
- if (xf86Screens[i]->vtSema) {
- /*
- * if we are aborting before ScreenInit() has finished
- * we might not have been wrapped yet. Therefore enable
- * screen explicitely.
- */
- xf86VGAarbiterLock(xf86Screens[i]);
- (xf86Screens[i]->LeaveVT)(i, 0);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- }
-
- xf86AccessLeave();
-
- /*
- * This is needed for an abnormal server exit, since the normal exit stuff
- * MUST also be performed (i.e. the vt must be left in a defined state)
- */
- ddxGiveUp();
-}
-
-void
-OsVendorFatalError(void)
-{
-#ifdef VENDORSUPPORT
- ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
- "at %s for support on this crash.\n",VENDORSUPPORT);
-#else
- ErrorF("\nPlease consult the "XVENDORNAME" support \n"
- "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
-#endif
- if (xf86LogFile && xf86LogFileWasOpened)
- ErrorF("Please also check the log file at \"%s\" for additional "
- "information.\n", xf86LogFile);
- ErrorF("\n");
-}
-
-int
-xf86SetVerbosity(int verb)
-{
- int save = xf86Verbose;
-
- xf86Verbose = verb;
- LogSetParameter(XLOG_VERBOSITY, verb);
- return save;
-}
-
-int
-xf86SetLogVerbosity(int verb)
-{
- int save = xf86LogVerbose;
-
- xf86LogVerbose = verb;
- LogSetParameter(XLOG_FILE_VERBOSITY, verb);
- return save;
-}
-
-static void
-xf86PrintDefaultModulePath(void)
-{
- ErrorF("%s\n", DEFAULT_MODULE_PATH);
-}
-
-static void
-xf86PrintDefaultLibraryPath(void)
-{
- ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
-}
-
-/*
- * ddxProcessArgument --
- * Process device-dependent command line args. Returns 0 if argument is
- * not device dependent, otherwise Count of number of elements of argv
- * that are part of a device dependent commandline option.
- *
- */
-
-/* ARGSUSED */
-int
-ddxProcessArgument(int argc, char **argv, int i)
-{
- /*
- * Note: can't use xalloc/xfree here because OsInit() hasn't been called
- * yet. Use malloc/free instead.
- */
-
-#define CHECK_FOR_REQUIRED_ARGUMENT() \
- if (((i + 1) >= argc) || (!argv[i + 1])) { \
- ErrorF("Required argument to %s not specified\n", argv[i]); \
- UseMsg(); \
- FatalError("Required argument to %s not specified\n", argv[i]); \
- }
-
- /* First the options that are only allowed for root */
- if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
- if ( (geteuid() == 0) && (getuid() != 0) ) {
- FatalError("The '%s' option can only be used by root.\n", argv[i]);
- }
- else if (!strcmp(argv[i], "-modulepath"))
- {
- char *mp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- mp = malloc(strlen(argv[i + 1]) + 1);
- if (!mp)
- FatalError("Can't allocate memory for ModulePath\n");
- strcpy(mp, argv[i + 1]);
- xf86ModulePath = mp;
- xf86ModPathFrom = X_CMDLINE;
- return 2;
- }
- else if (!strcmp(argv[i], "-logfile"))
- {
- char *lf;
- CHECK_FOR_REQUIRED_ARGUMENT();
- lf = malloc(strlen(argv[i + 1]) + 1);
- if (!lf)
- FatalError("Can't allocate memory for LogFile\n");
- strcpy(lf, argv[i + 1]);
- xf86LogFile = lf;
- xf86LogFileFrom = X_CMDLINE;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGFILE__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigFile = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i], "-configdir"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGDIR__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigDir = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i],"-flipPixels"))
- {
- xf86FlipPixels = TRUE;
- return 1;
- }
-#ifdef XF86VIDMODE
- if (!strcmp(argv[i],"-disableVidMode"))
- {
- xf86VidModeDisabled = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
- {
- xf86VidModeAllowNonLocal = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i],"-allowMouseOpenFail"))
- {
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-ignoreABI"))
- {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- return 1;
- }
- if (!strcmp(argv[i],"-verbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetVerbosity(val);
- return 2;
- }
- }
- xf86SetVerbosity(++xf86Verbose);
- return 1;
- }
- if (!strcmp(argv[i],"-logverbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetLogVerbosity(val);
- return 2;
- }
- }
- xf86SetLogVerbosity(++xf86LogVerbose);
- return 1;
- }
- if (!strcmp(argv[i],"-quiet"))
- {
- xf86SetVerbosity(-1);
- return 1;
- }
- if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
- {
- xf86PrintBanner();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultModulePath"))
- {
- xf86PrintDefaultModulePath();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultLibPath"))
- {
- xf86PrintDefaultLibraryPath();
- exit(0);
- }
- /* Notice the -fp flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-fp"))
- {
- xf86fpFlag = TRUE;
- return 0;
- }
- /* Notice the -bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-bs"))
- {
- xf86bsDisableFlag = TRUE;
- return 0;
- }
- /* Notice the +bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "+bs"))
- {
- xf86bsEnableFlag = TRUE;
- return 0;
- }
- /* Notice the -s flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-s"))
- {
- xf86sFlag = TRUE;
- return 0;
- }
- if (!strcmp(argv[i], "-pixmap24"))
- {
- xf86Pix24 = Pix24Use24;
- return 1;
- }
- if (!strcmp(argv[i], "-pixmap32"))
- {
- xf86Pix24 = Pix24Use32;
- return 1;
- }
- if (!strcmp(argv[i], "-fbbpp"))
- {
- int bpp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &bpp) == 1)
- {
- xf86FbBpp = bpp;
- return 2;
- }
- else
- {
- ErrorF("Invalid fbbpp\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-depth"))
- {
- int depth;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &depth) == 1)
- {
- xf86Depth = depth;
- return 2;
- }
- else
- {
- ErrorF("Invalid depth\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-weight"))
- {
- int red, green, blue;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
- {
- xf86Weight.red = red;
- xf86Weight.green = green;
- xf86Weight.blue = blue;
- return 2;
- }
- else
- {
- ErrorF("Invalid weighting\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
- !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
- {
- double gamma;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%lf", &gamma) == 1) {
- if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
- ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
- " is valid\n", GAMMA_MIN, GAMMA_MAX);
- return 0;
- }
- if (!strcmp(argv[i-1], "-gamma"))
- xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
- else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
- else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
- else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-layout"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86LayoutName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-screen"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86ScreenName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-pointer"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86PointerName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-keyboard"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86KeyboardName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-nosilk"))
- {
- xf86silkenMouseDisableFlag = TRUE;
- return 1;
- }
-#ifdef HAVE_ACPI
- if (!strcmp(argv[i], "-noacpi"))
- {
- xf86acpiDisableFlag = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i], "-configure"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-configure' option can only be used by root.\n");
- exit(1);
- }
- xf86DoConfigure = TRUE;
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-showopts"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-showopts' option can only be used by root.\n");
- exit(1);
- }
- xf86DoShowOptions = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-isolateDevice"))
- {
- int bus, device, func;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (strncmp(argv[++i], "PCI:", 4)) {
- FatalError("Bus types other than PCI not yet isolable\n");
- }
- if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
- xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
- xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
- xf86IsolateDevice.dev = device;
- xf86IsolateDevice.func = func;
- return 2;
- } else {
- FatalError("Invalid isolated device specification\n");
- }
- }
- /* Notice cmdline xkbdir, but pass to dix as well */
- if (!strcmp(argv[i], "-xkbdir"))
- {
- xf86xkbdirFlag = TRUE;
- return 0;
- }
-
- /* OS-specific processing */
- return xf86ProcessArgument(argc, argv, i);
-}
-
-/*
- * ddxUseMsg --
- * Print out correct use of device dependent commandline options.
- * Maybe the user now knows what really to do ...
- */
-
-void
-ddxUseMsg(void)
-{
- ErrorF("\n");
- ErrorF("\n");
- ErrorF("Device Dependent Usage\n");
- if (getuid() == 0 || geteuid() != 0)
- {
- ErrorF("-modulepath paths specify the module search path\n");
- ErrorF("-logfile file specify a log file name\n");
- ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
- ErrorF("-showopts print available options for all installed drivers\n");
- }
- ErrorF("-config file specify a configuration file, relative to the\n");
- ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
- ErrorF("-configdir dir specify a configuration directory, relative to the\n");
- ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
- ErrorF("-verbose [n] verbose startup messages\n");
- ErrorF("-logverbose [n] verbose log messages\n");
- ErrorF("-quiet minimal startup messages\n");
- ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
- ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
- ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
- ErrorF("-depth n set colour depth. Default: 8\n");
- ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
- ErrorF("-rgamma f set gamma value for red phase\n");
- ErrorF("-ggamma f set gamma value for green phase\n");
- ErrorF("-bgamma f set gamma value for blue phase\n");
- ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
- ErrorF("-layout name specify the ServerLayout section name\n");
- ErrorF("-screen name specify the Screen section name\n");
- ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
- ErrorF("-pointer name specify the core pointer InputDevice name\n");
- ErrorF("-nosilk disable Silken Mouse\n");
- ErrorF("-flipPixels swap default black/white Pixel values\n");
-#ifdef XF86VIDMODE
- ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
- ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
-#endif
- ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
- ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
- ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
- ErrorF("-version show the server version\n");
- ErrorF("-showDefaultModulePath show the server default module path\n");
- ErrorF("-showDefaultLibPath show the server default library path\n");
- /* OS-specific usage */
- xf86UseMsg();
- ErrorF("\n");
-}
-
-
-/*
- * xf86LoadModules iterates over a list that is being passed in.
- */
-Bool
-xf86LoadModules(char **list, pointer *optlist)
-{
- int errmaj, errmin;
- pointer opt;
- int i;
- char *name;
- Bool failed = FALSE;
-
- if (!list)
- return TRUE;
-
- for (i = 0; list[i] != NULL; i++) {
-
- /* Normalise the module name */
- name = xf86NormalizeName(list[i]);
-
- /* Skip empty names */
- if (name == NULL || *name == '\0')
- continue;
-
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp(name, "keyboard")) {
- strcpy(name, "kbd");
- }
-
- if (optlist)
- opt = optlist[i];
- else
- opt = NULL;
-
- if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- failed = TRUE;
- }
- xfree(name);
- }
- return !failed;
-}
-
-/* Pixmap format stuff */
-
-PixmapFormatPtr
-xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
-{
- int i;
- static PixmapFormatRec format; /* XXX not reentrant */
-
- /*
- * When the formats[] list initialisation isn't complete, check the
- * depth 24 pixmap config/cmdline options and screen-specified formats.
- */
-
- if (!formatsDone) {
- if (depth == 24) {
- Pix24Flags pix24 = Pix24DontCare;
-
- format.depth = 24;
- format.scanlinePad = BITMAP_SCANLINE_PAD;
- if (xf86Info.pixmap24 != Pix24DontCare)
- pix24 = xf86Info.pixmap24;
- else if (pScrn->pixmap24 != Pix24DontCare)
- pix24 = pScrn->pixmap24;
- if (pix24 == Pix24Use24)
- format.bitsPerPixel = 24;
- else
- format.bitsPerPixel = 32;
- return &format;
- }
- }
-
- for (i = 0; i < numFormats; i++)
- if (formats[i].depth == depth)
- break;
- if (i != numFormats)
- return &formats[i];
- else if (!formatsDone) {
- /* Check for screen-specified formats */
- for (i = 0; i < pScrn->numFormats; i++)
- if (pScrn->formats[i].depth == depth)
- break;
- if (i != pScrn->numFormats)
- return &pScrn->formats[i];
- }
- return NULL;
-}
-
-int
-xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
-{
- PixmapFormatPtr format;
-
-
- format = xf86GetPixFormat(pScrn, depth);
- if (format)
- return format->bitsPerPixel;
- else
- return 0;
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+/*
+ * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+
+#undef HAS_UTSNAME
+#if !defined(WIN32)
+#define HAS_UTSNAME 1
+#include <sys/utsname.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "input.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "site.h"
+#include "mi.h"
+
+#include "compiler.h"
+
+#include "loaderProcs.h"
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#define XF86_OS_PRIVS
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xorgVersion.h"
+#include "xf86Build.h"
+#include "mipointer.h"
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "picturestr.h"
+
+#include "xf86VGAarbiter.h"
+#include "globals.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+#include <pciaccess.h>
+#include "Pci.h"
+#include "xf86Bus.h"
+
+#include <hotplug.h>
+
+/* forward declarations */
+static Bool probe_devices_from_device_sections(DriverPtr drvp);
+static Bool add_matching_devices_to_configure_list(DriverPtr drvp);
+
+#ifdef XF86PM
+void (*xf86OSPMClose)(void) = NULL;
+#endif
+static Bool xorgHWOpenConsole = FALSE;
+
+/* Common pixmap formats */
+
+static PixmapFormatRec formats[MAXFORMATS] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+ { 32, 32, BITMAP_SCANLINE_PAD },
+};
+static int numFormats = 7;
+static Bool formatsDone = FALSE;
+
+#ifndef OSNAME
+#define OSNAME " unknown"
+#endif
+#ifndef OSVENDOR
+#define OSVENDOR ""
+#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XORG_VERSION_SNAP
+#endif
+
+static void
+xf86PrintBanner(void)
+{
+#if PRE_RELEASE
+ xf86ErrorFVerb(0, "\n"
+ "This is a pre-release version of the X server from " XVENDORNAME ".\n"
+ "It is not supported in any way.\n"
+ "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
+ "Select the \"xorg\" product for bugs you find in this release.\n"
+ "Before reporting bugs in pre-release versions please check the\n"
+ "latest version in the X.Org Foundation git repository.\n"
+ "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
+#endif
+ xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
+ XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR,
+ XORG_VERSION_PATCH);
+#if XORG_VERSION_SNAP > 0
+ xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
+#endif
+
+#if XORG_VERSION_SNAP >= 900
+ /* When the minor number is 99, that signifies that the we are making
+ * a release candidate for a major version. (X.0.0)
+ * When the patch number is 99, that signifies that the we are making
+ * a release candidate for a minor version. (X.Y.0)
+ * When the patch number is < 99, then we are making a release
+ * candidate for the next point release. (X.Y.Z)
+ */
+#if XORG_VERSION_MINOR >= 99
+ xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
+ XORG_VERSION_SNAP - 900);
+#elif XORG_VERSION_PATCH == 99
+ xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
+#else
+ xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
+ XORG_VERSION_SNAP - 900);
+#endif
+#endif
+
+#ifdef XORG_CUSTOM_VERSION
+ xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
+#endif
+#ifndef XORG_DATE
+# define XORG_DATE "Unknown"
+#endif
+ xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
+ xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
+ X_PROTOCOL, X_PROTOCOL_REVISION);
+ xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
+#ifdef HAS_UTSNAME
+ {
+ struct utsname name;
+
+ /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
+ and Irix) and Single Unix Spec 3 just say that non-negative is success.
+ All agree that failure is represented by a negative number.
+ */
+ if (uname(&name) >= 0) {
+ xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
+ name.sysname, name.nodename, name.release, name.version, name.machine);
+#ifdef linux
+ do {
+ char buf[80];
+ int fd = open("/proc/cmdline", O_RDONLY);
+ if (fd != -1) {
+ xf86ErrorFVerb(0, "Kernel command line: ");
+ memset(buf, 0, 80);
+ while (read(fd, buf, 80) > 0) {
+ xf86ErrorFVerb(0, "%.80s", buf);
+ memset(buf, 0, 80);
+ }
+ close(fd);
+ }
+ } while (0);
+#endif
+ }
+ }
+#endif
+#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
+ {
+ struct tm t;
+ char buf[100];
+
+ bzero(&t, sizeof(t));
+ bzero(buf, sizeof(buf));
+ t.tm_mday = BUILD_DATE % 100;
+ t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
+ t.tm_year = BUILD_DATE / 10000 - 1900;
+#if defined(BUILD_TIME)
+ t.tm_sec = BUILD_TIME % 100;
+ t.tm_min = (BUILD_TIME / 100) % 100;
+ t.tm_hour = (BUILD_TIME / 10000) % 100;
+ if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#else
+ if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#endif
+ }
+#endif
+#if defined(BUILDERSTRING)
+ xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
+#endif
+ xf86ErrorFVerb(0, "Current version of pixman: %s\n",
+ pixman_version_string());
+ xf86ErrorFVerb(0, "\tBefore reporting problems, check "
+ ""__VENDORDWEBSUPPORT__"\n"
+ "\tto make sure that you have the latest version.\n");
+}
+
+static void
+xf86PrintMarkers(void)
+{
+ LogPrintMarkers();
+}
+
+static Bool
+xf86CreateRootWindow(WindowPtr pWin)
+{
+ int ret = TRUE;
+ int err = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RootWinPropPtr pProp;
+ CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
+ dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
+
+ DebugF("xf86CreateRootWindow(%p)\n", pWin);
+
+ if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
+ /* Can't find hook we are hung on */
+ xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
+ "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
+ (void *)xf86CreateRootWindow,
+ (void *)pScreen->CreateWindow );
+ }
+
+ /* Unhook this function ... */
+ pScreen->CreateWindow = CreateWindow;
+ dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
+
+ /* ... and call the previous CreateWindow fuction, if any */
+ if (NULL!=pScreen->CreateWindow) {
+ ret = (*pScreen->CreateWindow)(pWin);
+ }
+
+ /* Now do our stuff */
+ if (xf86RegisteredPropertiesTable != NULL) {
+ if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
+ for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+ pProp != NULL && err==Success;
+ pProp = pProp->next )
+ {
+ Atom prop;
+
+ prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
+ err = dixChangeWindowProperty(serverClient, pWin,
+ prop, pProp->type,
+ pProp->format, PropModeReplace,
+ pProp->size, pProp->data,
+ FALSE);
+ }
+
+ /* Look at err */
+ ret &= (err==Success);
+
+ } else {
+ xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
+ "non-root window %p (parent %p)\n",
+ (void *)pWin, (void *)pWin->parent);
+ ret = FALSE;
+ }
+ }
+
+ DebugF("xf86CreateRootWindow() returns %d\n", ret);
+ return (ret);
+}
+
+
+static void
+InstallSignalHandlers(void)
+{
+ /*
+ * Install signal handler for unexpected signals
+ */
+ xf86Info.caughtSignal=FALSE;
+ if (!xf86Info.notrapSignals) {
+ OsRegisterSigWrapper(xf86SigWrapper);
+ } else {
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
+#ifdef SIGEMT
+ signal(SIGEMT, SIG_DFL);
+#endif
+ signal(SIGFPE, SIG_DFL);
+#ifdef SIGBUS
+ signal(SIGBUS, SIG_DFL);
+#endif
+#ifdef SIGSYS
+ signal(SIGSYS, SIG_DFL);
+#endif
+#ifdef SIGXCPU
+ signal(SIGXCPU, SIG_DFL);
+#endif
+#ifdef SIGXFSZ
+ signal(SIGXFSZ, SIG_DFL);
+#endif
+ }
+}
+
+
+#define END_OF_MATCHES(m) \
+ (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
+
+Bool
+probe_devices_from_device_sections(DriverPtr drvp)
+{
+ int i, j;
+ struct pci_device * pPci;
+ Bool foundScreen = FALSE;
+ const struct pci_id_match * const devices = drvp->supported_devices;
+ GDevPtr *devList;
+ const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
+
+
+ for ( i = 0 ; i < numDevs ; i++ ) {
+ struct pci_device_iterator *iter;
+ unsigned device_id;
+
+
+ /* Find the pciVideoRec associated with this device section.
+ */
+ iter = pci_id_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ if (devList[i]->busID && *devList[i]->busID) {
+ if (xf86ComparePciBusString(devList[i]->busID,
+ ((pPci->domain << 8)
+ | pPci->bus),
+ pPci->dev,
+ pPci->func)) {
+ break;
+ }
+ }
+ else if (xf86IsPrimaryPci(pPci)) {
+ break;
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+ if (pPci == NULL) {
+ continue;
+ }
+
+ device_id = (devList[i]->chipID > 0)
+ ? devList[i]->chipID : pPci->device_id;
+
+
+ /* Once the pciVideoRec is found, determine if the device is supported
+ * by the driver. If it is, probe it!
+ */
+ for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
+ if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
+ && PCI_ID_COMPARE( devices[j].device_id, device_id )
+ && ((devices[j].device_class_mask & pPci->device_class)
+ == devices[j].device_class) ) {
+ int entry;
+
+ /* Allow the same entity to be used more than once for
+ * devices with multiple screens per entity. This assumes
+ * implicitly that there will be a screen == 0 instance.
+ *
+ * FIXME Need to make sure that two different drivers don't
+ * FIXME claim the same screen > 0 instance.
+ */
+ if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
+ continue;
+
+ DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
+ drvp->driverName, pPci->bus, pPci->dev, pPci->func);
+
+ /* Allocate an entry in the lists to be returned */
+ entry = xf86ClaimPciSlot(pPci, drvp, device_id,
+ devList[i], devList[i]->active);
+
+ if ((entry == -1) && (devList[i]->screen > 0)) {
+ unsigned k;
+
+ for ( k = 0; k < xf86NumEntities; k++ ) {
+ EntityPtr pEnt = xf86Entities[k];
+ if (pEnt->bus.type != BUS_PCI)
+ continue;
+
+ if (pEnt->bus.id.pci == pPci) {
+ entry = k;
+ xf86AddDevToEntity(k, devList[i]);
+ break;
+ }
+ }
+ }
+
+ if (entry != -1) {
+ if ((*drvp->PciProbe)(drvp, entry, pPci,
+ devices[j].match_data)) {
+ foundScreen = TRUE;
+ } else
+ xf86UnclaimPciSlot(pPci);
+ }
+
+ break;
+ }
+ }
+ }
+ free(devList);
+
+ return foundScreen;
+}
+
+
+Bool
+add_matching_devices_to_configure_list(DriverPtr drvp)
+{
+ const struct pci_id_match * const devices = drvp->supported_devices;
+ int j;
+ struct pci_device *pPci;
+ struct pci_device_iterator *iter;
+ int numFound = 0;
+
+
+ iter = pci_id_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ /* Determine if this device is supported by the driver. If it is,
+ * add it to the list of devices to configure.
+ */
+ for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
+ if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
+ && PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
+ && ((devices[j].device_class_mask & pPci->device_class)
+ == devices[j].device_class) ) {
+ if (xf86CheckPciSlot(pPci)) {
+ GDevPtr pGDev = xf86AddBusDeviceToConfigure(
+ drvp->driverName, BUS_PCI, pPci, -1);
+ if (pGDev != NULL) {
+ /* After configure pass 1, chipID and chipRev are
+ * treated as over-rides, so clobber them here.
+ */
+ pGDev->chipID = -1;
+ pGDev->chipRev = -1;
+ }
+
+ numFound++;
+ }
+
+ break;
+ }
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+
+ return (numFound != 0);
+}
+
+/**
+ * Call the driver's correct probe function.
+ *
+ * If the driver implements the \c DriverRec::PciProbe entry-point and an
+ * appropriate PCI device (with matching Device section in the xorg.conf file)
+ * is found, it is called. If \c DriverRec::PciProbe or no devices can be
+ * successfully probed with it (e.g., only non-PCI devices are available),
+ * the driver's \c DriverRec::Probe function is called.
+ *
+ * \param drv Driver to probe
+ *
+ * \return
+ * If a device can be successfully probed by the driver, \c TRUE is
+ * returned. Otherwise, \c FALSE is returned.
+ */
+Bool
+xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
+{
+ Bool foundScreen = FALSE;
+
+ if ( drv->PciProbe != NULL ) {
+ if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
+ assert( detect_only );
+ foundScreen = add_matching_devices_to_configure_list( drv );
+ }
+ else {
+ assert( ! detect_only );
+ foundScreen = probe_devices_from_device_sections( drv );
+ }
+ }
+
+ if ( ! foundScreen && (drv->Probe != NULL) ) {
+ xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
+ drv->driverName );
+ foundScreen = (*drv->Probe)( drv, (detect_only) ? PROBE_DETECT
+ : PROBE_DEFAULT );
+ }
+
+ return foundScreen;
+}
+
+/*
+ * InitOutput --
+ * Initialize screenInfo for all actually accessible framebuffers.
+ * That includes vt-manager setup, querying all possible devices and
+ * collecting the pixmap formats.
+ */
+void
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ int i, j, k, scr_index;
+ char **modulelist;
+ pointer *optionlist;
+ screenLayoutPtr layout;
+ Pix24Flags screenpix24, pix24;
+ MessageType pix24From = X_DEFAULT;
+ Bool pix24Fail = FALSE;
+ Bool autoconfig = FALSE;
+ GDevPtr configured_device;
+
+ xf86Initialising = TRUE;
+
+ if (serverGeneration == 1) {
+ if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
+ xf86ServerName++;
+ else
+ xf86ServerName = argv[0];
+
+ xf86PrintBanner();
+ xf86PrintMarkers();
+ if (xf86LogFile) {
+ time_t t;
+ const char *ct;
+ t = time(NULL);
+ ct = ctime(&t);
+ xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
+ xf86LogFile, ct);
+ }
+
+ /* Read and parse the config file */
+ if (!xf86DoConfigure && !xf86DoShowOptions) {
+ switch (xf86HandleConfigFile(FALSE)) {
+ case CONFIG_OK:
+ break;
+ case CONFIG_PARSE_ERROR:
+ xf86Msg(X_ERROR, "Error parsing the config file\n");
+ return;
+ case CONFIG_NOFILE:
+ autoconfig = TRUE;
+ break;
+ }
+ }
+
+ InstallSignalHandlers();
+
+ /* Initialise the loader */
+ LoaderInit();
+
+ /* Tell the loader the default module search path */
+ LoaderSetPath(xf86ModulePath);
+
+ if (xf86Info.ignoreABI) {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ }
+
+ if (xf86DoShowOptions)
+ DoShowOptions();
+
+ /* Do a general bus probe. This will be a PCI probe for x86 platforms */
+ xf86BusProbe();
+
+ if (xf86DoConfigure)
+ DoConfigure();
+
+ if (autoconfig) {
+ if (!xf86AutoConfig()) {
+ xf86Msg(X_ERROR, "Auto configuration failed\n");
+ return;
+ }
+ }
+
+#ifdef XF86PM
+ xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+ /* Load all modules specified explicitly in the config file */
+ if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
+ xf86LoadModules(modulelist, optionlist);
+ free(modulelist);
+ free(optionlist);
+ }
+
+ /* Load all driver modules specified in the config file */
+ /* If there aren't any specified in the config file, autoconfig them */
+ /* FIXME: Does not handle multiple active screen sections, but I'm not
+ * sure if we really want to handle that case*/
+ configured_device = xf86ConfigLayout.screens->screen->device;
+ if ((!configured_device) || (!configured_device->driver)) {
+ if (!autoConfigDevice(configured_device)) {
+ xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+ return ;
+ }
+ }
+ if ((modulelist = xf86DriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /* Load all input driver modules specified in the config file. */
+ if ((modulelist = xf86InputDriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /*
+ * It is expected that xf86AddDriver()/xf86AddInputDriver will be
+ * called for each driver as it is loaded. Those functions save the
+ * module pointers for drivers.
+ * XXX Nothing keeps track of them for other modules.
+ */
+ /* XXX What do we do if not all of these could be loaded? */
+
+ /*
+ * At this point, xf86DriverList[] is all filled in with entries for
+ * each of the drivers to try and xf86NumDrivers has the number of
+ * drivers. If there are none, return now.
+ */
+
+ if (xf86NumDrivers == 0) {
+ xf86Msg(X_ERROR, "No drivers available.\n");
+ return;
+ }
+
+ /*
+ * Call each of the Identify functions and call the driverFunc to check
+ * if HW access is required. The Identify functions print out some
+ * identifying information, and anything else that might be
+ * needed at this early stage.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->Identify != NULL)
+ xf86DriverList[i]->Identify(0);
+
+ if (!xorgHWAccess || !xorgHWOpenConsole) {
+ xorgHWFlags flags;
+ if(!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags))
+ flags = HW_IO;
+
+ if(NEED_IO_ENABLED(flags))
+ xorgHWAccess = TRUE;
+ if(!(flags & HW_SKIP_CONSOLE))
+ xorgHWOpenConsole = TRUE;
+ }
+ }
+
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+ else
+ xf86Info.dontVTSwitch = TRUE;
+
+ /* Enable full I/O access */
+ if (xorgHWAccess)
+ xorgHWAccess = xf86EnableIO();
+
+ /*
+ * Locate bus slot that had register IO enabled at server startup
+ */
+ if (xorgHWAccess) {
+ xf86AccessInit();
+ xf86FindPrimaryDevice();
+ }
+ /*
+ * Now call each of the Probe functions. Each successful probe will
+ * result in an extra entry added to the xf86Screens[] list for each
+ * instance of the hardware found.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ xorgHWFlags flags;
+ if (!xorgHWAccess) {
+ if (!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags)
+ || NEED_IO_ENABLED(flags))
+ continue;
+ }
+
+ xf86CallDriverProbe( xf86DriverList[i], FALSE );
+ }
+
+ /*
+ * If nothing was detected, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR, "No devices detected.\n");
+ return;
+ }
+
+ xf86VGAarbiterInit();
+
+ /*
+ * Match up the screens found by the probes against those specified
+ * in the config file. Remove the ones that won't be used. Sort
+ * them in the order specified.
+ */
+
+ /*
+ * What is the best way to do this?
+ *
+ * For now, go through the screens allocated by the probes, and
+ * look for screen config entry which refers to the same device
+ * section as picked out by the probe.
+ *
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
+ layout++) {
+ Bool found = FALSE;
+ for (j = 0; j < xf86Screens[i]->numEntities; j++) {
+
+ GDevPtr dev =
+ xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
+ xf86Screens[i]->entityInstanceList[j]);
+
+ if (dev == layout->screen->device) {
+ /* A match has been found */
+ xf86Screens[i]->confScreen = layout->screen;
+ found = TRUE;
+ break;
+ }
+ }
+ if (found) break;
+ }
+ if (layout->screen == NULL) {
+ /* No match found */
+ xf86Msg(X_ERROR,
+ "Screen %d deleted because of no matching config section.\n", i);
+ xf86DeleteScreen(i--, 0);
+ }
+ }
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Device(s) detected, but none match those in the config file.\n");
+ return;
+ }
+
+ xf86PostProbe();
+ xf86EntityInit();
+
+ /*
+ * Sort the drivers to match the requested ording. Using a slow
+ * bubble sort.
+ */
+ for (j = 0; j < xf86NumScreens - 1; j++) {
+ for (i = 0; i < xf86NumScreens - j - 1; i++) {
+ if (xf86Screens[i + 1]->confScreen->screennum <
+ xf86Screens[i]->confScreen->screennum) {
+ ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
+ xf86Screens[i + 1] = xf86Screens[i];
+ xf86Screens[i] = tmpScrn;
+ }
+ }
+ }
+ /* Fix up the indexes */
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86Screens[i]->scrnIndex = i;
+ }
+
+ /*
+ * Call the driver's PreInit()'s to complete initialisation for the first
+ * generation.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterScrnInit(xf86Screens[i]);
+ xf86VGAarbiterLock(xf86Screens[i]);
+ if (xf86Screens[i]->PreInit &&
+ xf86Screens[i]->PreInit(xf86Screens[i], 0))
+ xf86Screens[i]->configured = TRUE;
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ for (i = 0; i < xf86NumScreens; i++)
+ if (!xf86Screens[i]->configured)
+ xf86DeleteScreen(i--, 0);
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Screen(s) found, but none have a usable configuration.\n");
+ return;
+ }
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->name == NULL) {
+ xf86Screens[i]->name = xnfalloc(strlen("screen") + 10 + 1);
+ sprintf(xf86Screens[i]->name, "screen%d", i);
+ xf86MsgVerb(X_WARNING, 0,
+ "Screen driver %d has no name set, using `%s'.\n",
+ i, xf86Screens[i]->name);
+ }
+ }
+
+ /* Remove (unload) drivers that are not required */
+ for (i = 0; i < xf86NumDrivers; i++)
+ if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
+ xf86DeleteDriver(i);
+
+ /*
+ * At this stage we know how many screens there are.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++)
+ xf86InitViewport(xf86Screens[i]);
+
+ /*
+ * Collect all pixmap formats and check for conflicts at the display
+ * level. Should we die here? Or just delete the offending screens?
+ */
+ screenpix24 = Pix24DontCare;
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->imageByteOrder !=
+ xf86Screens[0]->imageByteOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlinePad !=
+ xf86Screens[0]->bitmapScanlinePad)
+ FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlineUnit !=
+ xf86Screens[0]->bitmapScanlineUnit)
+ FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
+ if (xf86Screens[i]->bitmapBitOrder !=
+ xf86Screens[0]->bitmapBitOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+
+ /* Determine the depth 24 pixmap format the screens would like */
+ if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
+ if (screenpix24 == Pix24DontCare)
+ screenpix24 = xf86Screens[i]->pixmap24;
+ else if (screenpix24 != xf86Screens[i]->pixmap24)
+ FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
+ }
+ }
+ /* check if screenpix24 is consistent with the config/cmdline */
+ if (xf86Info.pixmap24 != Pix24DontCare) {
+ pix24 = xf86Info.pixmap24;
+ pix24From = xf86Info.pix24From;
+ if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
+ pix24Fail = TRUE;
+ } else if (screenpix24 != Pix24DontCare) {
+ pix24 = screenpix24;
+ pix24From = X_PROBED;
+ } else
+ pix24 = Pix24Use32;
+
+ if (pix24Fail)
+ FatalError("Screen(s) can't use the required depth 24 pixmap format"
+ " (%d). Exiting\n", PIX24TOBPP(pix24));
+
+ /* Initialise the depth 24 format */
+ for (j = 0; j < numFormats && formats[j].depth != 24; j++)
+ ;
+ formats[j].bitsPerPixel = PIX24TOBPP(pix24);
+
+ /* Collect additional formats */
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numFormats; j++) {
+ for (k = 0; ; k++) {
+ if (k >= numFormats) {
+ if (k >= MAXFORMATS)
+ FatalError("Too many pixmap formats! Exiting\n");
+ formats[k] = xf86Screens[i]->formats[j];
+ numFormats++;
+ break;
+ }
+ if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
+ if ((formats[k].bitsPerPixel ==
+ xf86Screens[i]->formats[j].bitsPerPixel) &&
+ (formats[k].scanlinePad ==
+ xf86Screens[i]->formats[j].scanlinePad))
+ break;
+ FatalError("Inconsistent pixmap format for depth %d."
+ " Exiting\n", formats[k].depth);
+ }
+ }
+ }
+ }
+ formatsDone = TRUE;
+
+ if (xf86Info.vtno >= 0 ) {
+#define VT_ATOM_NAME "XFree86_VT"
+ Atom VTAtom=-1;
+ CARD32 *VT = NULL;
+ int ret;
+
+ /* This memory needs to stay available until the screen has been
+ initialized, and we can create the property for real.
+ */
+ if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
+ FatalError("Unable to make VT property - out of memory. Exiting...\n");
+ }
+ *VT = xf86Info.vtno;
+
+ VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+
+ for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
+ ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
+ VTAtom, XA_INTEGER, 32,
+ 1, VT );
+ if (ret != Success)
+ xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
+ "Failed to register VT property\n");
+ }
+ }
+
+ /* If a screen uses depth 24, show what the pixmap format is */
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->depth == 24) {
+ xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
+ PIX24TOBPP(pix24));
+ break;
+ }
+ }
+ } else {
+ /*
+ * serverGeneration != 1; some OSs have to do things here, too.
+ */
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+
+#ifdef XF86PM
+ /*
+ should we reopen it here? We need to deal with an already opened
+ device. We could leave this to the OS layer. For now we simply
+ close it here
+ */
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
+ xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
+#endif
+
+ /* Make sure full I/O access is enabled */
+ if (xorgHWAccess)
+ xf86EnableIO();
+ }
+
+ /*
+ * Use the previously collected parts to setup pScreenInfo
+ */
+
+ pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
+ pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
+ pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
+ pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
+ pScreenInfo->numPixmapFormats = numFormats;
+ for (i = 0; i < numFormats; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+ /* Make sure the server's VT is active */
+
+ if (serverGeneration != 1) {
+ xf86Resetting = TRUE;
+ /* All screens are in the same state, so just check the first */
+ if (!xf86Screens[0]->vtSema) {
+#ifdef HAS_USL_VTS
+ ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
+#endif
+ xf86AccessEnter();
+ xf86EnterServerState(SETUP);
+ }
+ }
+#ifdef SCO325
+ else {
+ /*
+ * Under SCO we must ack that we got the console at startup,
+ * I think this is the safest way to assure it.
+ */
+ static int once = 1;
+ if (once) {
+ once = 0;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ xf86Msg(X_WARNING, "VT_ACKACQ failed");
+ }
+ }
+#endif /* SCO325 */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterLock(xf86Screens[i]);
+ /*
+ * Almost everything uses these defaults, and many of those that
+ * don't, will wrap them.
+ */
+ xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+#ifdef XFreeXDGA
+ xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
+#endif
+ xf86Screens[i]->DPMSSet = NULL;
+ xf86Screens[i]->LoadPalette = NULL;
+ xf86Screens[i]->SetOverscan = NULL;
+ xf86Screens[i]->DriverFunc = NULL;
+ xf86Screens[i]->pScreen = NULL;
+ scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ if (scr_index == i) {
+ /*
+ * Hook in our ScrnInfoRec, and initialise some other pScreen
+ * fields.
+ */
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86ScreenKey, xf86Screens[i]);
+ xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
+ /* The driver should set this, but make sure it is set anyway */
+ xf86Screens[i]->vtSema = TRUE;
+ } else {
+ /* This shouldn't normally happen */
+ FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
+ }
+
+ DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+ i, xf86Screens[i]->pScreen );
+ DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+ i, xf86Screens[i]->pScreen->CreateWindow );
+
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86CreateRootWindowKey,
+ xf86Screens[i]->pScreen->CreateWindow);
+ xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
+
+ if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
+ {
+ xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
+ PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
+ DDC ?
+ (DDC->features.input_type ?
+ SubPixelHorizontalRGB : SubPixelNone) :
+ SubPixelUnknown);
+ }
+#ifdef RANDR
+ if (!xf86Info.disableRandR)
+ xf86RandRInit (screenInfo.screens[scr_index]);
+ xf86Msg(xf86Info.randRFrom, "RandR %s\n",
+ xf86Info.disableRandR ? "disabled" : "enabled");
+#endif
+ }
+
+ xf86PostScreenInit();
+
+ xf86InitOrigins();
+
+ xf86Resetting = FALSE;
+ xf86Initialising = FALSE;
+
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
+ NULL);
+}
+
+/*
+ * InitInput --
+ * Initialize all supported input devices.
+ */
+
+void
+InitInput(int argc, char **argv)
+{
+ IDevPtr* pDev;
+ DeviceIntPtr dev;
+
+ xf86Info.vtRequestsPending = FALSE;
+
+ mieqInit();
+
+ GetEventList(&xf86Events);
+
+ /* Call the PreInit function for each input device instance. */
+ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
+ strcpy((*pDev)->driver, "kbd");
+ }
+
+ /* If one fails, the others will too */
+ if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
+ break;
+ }
+
+ config_init();
+}
+
+void
+CloseInput (void)
+{
+ config_fini();
+}
+
+/*
+ * OsVendorInit --
+ * OS/Vendor-specific initialisations. Called from OsInit(), which
+ * is called by dix before establishing the well known sockets.
+ */
+
+void
+OsVendorInit(void)
+{
+ static Bool beenHere = FALSE;
+
+#ifdef SIGCHLD
+ signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
+#endif
+
+ if (!beenHere) {
+ umask(022);
+ xf86LogInit();
+ }
+
+ /* Set stderr to non-blocking. */
+#ifndef O_NONBLOCK
+#if defined(FNDELAY)
+#define O_NONBLOCK FNDELAY
+#elif defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
+#ifdef O_NONBLOCK
+ if (!beenHere) {
+ if (geteuid() == 0 && getuid() != geteuid())
+ {
+ int status;
+
+ status = fcntl(fileno(stderr), F_GETFL, 0);
+ if (status != -1) {
+ fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
+ }
+ }
+ }
+#endif
+#endif
+
+ beenHere = TRUE;
+}
+
+/*
+ * ddxGiveUp --
+ * Device dependent cleanup. Called by by dix before normal server death.
+ * For SYSV386 we must switch the terminal back to normal mode. No error-
+ * checking here, since there should be restored as much as possible.
+ */
+
+void
+ddxGiveUp(void)
+{
+ int i;
+
+ xf86VGAarbiterFini();
+
+#ifdef XF86PM
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ xf86OSPMClose = NULL;
+#endif
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ /*
+ * zero all access functions to
+ * trap calls when switched away.
+ */
+ xf86Screens[i]->vtSema = FALSE;
+ }
+
+#ifdef XFreeXDGA
+ DGAShutdown();
+#endif
+
+ if (xorgHWOpenConsole)
+ xf86CloseConsole();
+
+ xf86CloseLog();
+
+ /* If an unexpected signal was caught, dump a core for debugging */
+ if (xf86Info.caughtSignal)
+ OsAbort();
+}
+
+
+
+/*
+ * AbortDDX --
+ * DDX - specific abort routine. Called by AbortServer(). The attempt is
+ * made to restore all original setting of the displays. Also all devices
+ * are closed.
+ */
+
+void
+AbortDDX(void)
+{
+ int i;
+
+ /*
+ * try to restore the original video state
+ */
+#ifdef DPMSExtension /* Turn screens back on */
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(serverClient, DPMSModeOn);
+#endif
+ if (xf86Screens) {
+ if (xf86Screens[0]->vtSema)
+ xf86EnterServerState(SETUP);
+ for (i = 0; i < xf86NumScreens; i++)
+ if (xf86Screens[i]->vtSema) {
+ /*
+ * if we are aborting before ScreenInit() has finished
+ * we might not have been wrapped yet. Therefore enable
+ * screen explicitely.
+ */
+ xf86VGAarbiterLock(xf86Screens[i]);
+ (xf86Screens[i]->LeaveVT)(i, 0);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ }
+
+ xf86AccessLeave();
+
+ /*
+ * This is needed for an abnormal server exit, since the normal exit stuff
+ * MUST also be performed (i.e. the vt must be left in a defined state)
+ */
+ ddxGiveUp();
+}
+
+void
+OsVendorFatalError(void)
+{
+#ifdef VENDORSUPPORT
+ ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
+ "at %s for support on this crash.\n",VENDORSUPPORT);
+#else
+ ErrorF("\nPlease consult the "XVENDORNAME" support \n"
+ "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
+#endif
+ if (xf86LogFile && xf86LogFileWasOpened)
+ ErrorF("Please also check the log file at \"%s\" for additional "
+ "information.\n", xf86LogFile);
+ ErrorF("\n");
+}
+
+int
+xf86SetVerbosity(int verb)
+{
+ int save = xf86Verbose;
+
+ xf86Verbose = verb;
+ LogSetParameter(XLOG_VERBOSITY, verb);
+ return save;
+}
+
+int
+xf86SetLogVerbosity(int verb)
+{
+ int save = xf86LogVerbose;
+
+ xf86LogVerbose = verb;
+ LogSetParameter(XLOG_FILE_VERBOSITY, verb);
+ return save;
+}
+
+static void
+xf86PrintDefaultModulePath(void)
+{
+ ErrorF("%s\n", DEFAULT_MODULE_PATH);
+}
+
+static void
+xf86PrintDefaultLibraryPath(void)
+{
+ ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
+}
+
+/*
+ * ddxProcessArgument --
+ * Process device-dependent command line args. Returns 0 if argument is
+ * not device dependent, otherwise Count of number of elements of argv
+ * that are part of a device dependent commandline option.
+ *
+ */
+
+/* ARGSUSED */
+int
+ddxProcessArgument(int argc, char **argv, int i)
+{
+ /*
+ * Note: can't use xalloc/xfree here because OsInit() hasn't been called
+ * yet. Use malloc/free instead.
+ */
+
+#define CHECK_FOR_REQUIRED_ARGUMENT() \
+ if (((i + 1) >= argc) || (!argv[i + 1])) { \
+ ErrorF("Required argument to %s not specified\n", argv[i]); \
+ UseMsg(); \
+ FatalError("Required argument to %s not specified\n", argv[i]); \
+ }
+
+ /* First the options that are only allowed for root */
+ if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
+ if ( (geteuid() == 0) && (getuid() != 0) ) {
+ FatalError("The '%s' option can only be used by root.\n", argv[i]);
+ }
+ else if (!strcmp(argv[i], "-modulepath"))
+ {
+ char *mp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ mp = malloc(strlen(argv[i + 1]) + 1);
+ if (!mp)
+ FatalError("Can't allocate memory for ModulePath\n");
+ strcpy(mp, argv[i + 1]);
+ xf86ModulePath = mp;
+ xf86ModPathFrom = X_CMDLINE;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-logfile"))
+ {
+ char *lf;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ lf = malloc(strlen(argv[i + 1]) + 1);
+ if (!lf)
+ FatalError("Can't allocate memory for LogFile\n");
+ strcpy(lf, argv[i + 1]);
+ xf86LogFile = lf;
+ xf86LogFileFrom = X_CMDLINE;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGFILE__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigFile = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-configdir"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGDIR__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigDir = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i],"-flipPixels"))
+ {
+ xf86FlipPixels = TRUE;
+ return 1;
+ }
+#ifdef XF86VIDMODE
+ if (!strcmp(argv[i],"-disableVidMode"))
+ {
+ xf86VidModeDisabled = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
+ {
+ xf86VidModeAllowNonLocal = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i],"-allowMouseOpenFail"))
+ {
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-ignoreABI"))
+ {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-verbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetVerbosity(++xf86Verbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-logverbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetLogVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetLogVerbosity(++xf86LogVerbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-quiet"))
+ {
+ xf86SetVerbosity(-1);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
+ {
+ xf86PrintBanner();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultModulePath"))
+ {
+ xf86PrintDefaultModulePath();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultLibPath"))
+ {
+ xf86PrintDefaultLibraryPath();
+ exit(0);
+ }
+ /* Notice the -fp flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-fp"))
+ {
+ xf86fpFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-bs"))
+ {
+ xf86bsDisableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the +bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "+bs"))
+ {
+ xf86bsEnableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -s flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-s"))
+ {
+ xf86sFlag = TRUE;
+ return 0;
+ }
+ if (!strcmp(argv[i], "-pixmap24"))
+ {
+ xf86Pix24 = Pix24Use24;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-pixmap32"))
+ {
+ xf86Pix24 = Pix24Use32;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-fbbpp"))
+ {
+ int bpp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &bpp) == 1)
+ {
+ xf86FbBpp = bpp;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid fbbpp\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-depth"))
+ {
+ int depth;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &depth) == 1)
+ {
+ xf86Depth = depth;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid depth\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-weight"))
+ {
+ int red, green, blue;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
+ {
+ xf86Weight.red = red;
+ xf86Weight.green = green;
+ xf86Weight.blue = blue;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid weighting\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
+ !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
+ {
+ double gamma;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%lf", &gamma) == 1) {
+ if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
+ ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
+ " is valid\n", GAMMA_MIN, GAMMA_MAX);
+ return 0;
+ }
+ if (!strcmp(argv[i-1], "-gamma"))
+ xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
+ else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
+ else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
+ else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-layout"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86LayoutName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-screen"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86ScreenName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-pointer"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86PointerName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-keyboard"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86KeyboardName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-nosilk"))
+ {
+ xf86silkenMouseDisableFlag = TRUE;
+ return 1;
+ }
+#ifdef HAVE_ACPI
+ if (!strcmp(argv[i], "-noacpi"))
+ {
+ xf86acpiDisableFlag = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i], "-configure"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-configure' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoConfigure = TRUE;
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-showopts"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-showopts' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoShowOptions = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-isolateDevice"))
+ {
+ int bus, device, func;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (strncmp(argv[++i], "PCI:", 4)) {
+ FatalError("Bus types other than PCI not yet isolable\n");
+ }
+ if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
+ xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
+ xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
+ xf86IsolateDevice.dev = device;
+ xf86IsolateDevice.func = func;
+ return 2;
+ } else {
+ FatalError("Invalid isolated device specification\n");
+ }
+ }
+ /* Notice cmdline xkbdir, but pass to dix as well */
+ if (!strcmp(argv[i], "-xkbdir"))
+ {
+ xf86xkbdirFlag = TRUE;
+ return 0;
+ }
+
+ /* OS-specific processing */
+ return xf86ProcessArgument(argc, argv, i);
+}
+
+/*
+ * ddxUseMsg --
+ * Print out correct use of device dependent commandline options.
+ * Maybe the user now knows what really to do ...
+ */
+
+void
+ddxUseMsg(void)
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF("Device Dependent Usage\n");
+ if (getuid() == 0 || geteuid() != 0)
+ {
+ ErrorF("-modulepath paths specify the module search path\n");
+ ErrorF("-logfile file specify a log file name\n");
+ ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
+ ErrorF("-showopts print available options for all installed drivers\n");
+ }
+ ErrorF("-config file specify a configuration file, relative to the\n");
+ ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
+ ErrorF("-configdir dir specify a configuration directory, relative to the\n");
+ ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
+ ErrorF("-verbose [n] verbose startup messages\n");
+ ErrorF("-logverbose [n] verbose log messages\n");
+ ErrorF("-quiet minimal startup messages\n");
+ ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
+ ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
+ ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
+ ErrorF("-depth n set colour depth. Default: 8\n");
+ ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
+ ErrorF("-rgamma f set gamma value for red phase\n");
+ ErrorF("-ggamma f set gamma value for green phase\n");
+ ErrorF("-bgamma f set gamma value for blue phase\n");
+ ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
+ ErrorF("-layout name specify the ServerLayout section name\n");
+ ErrorF("-screen name specify the Screen section name\n");
+ ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
+ ErrorF("-pointer name specify the core pointer InputDevice name\n");
+ ErrorF("-nosilk disable Silken Mouse\n");
+ ErrorF("-flipPixels swap default black/white Pixel values\n");
+#ifdef XF86VIDMODE
+ ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
+ ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
+#endif
+ ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
+ ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
+ ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
+ ErrorF("-version show the server version\n");
+ ErrorF("-showDefaultModulePath show the server default module path\n");
+ ErrorF("-showDefaultLibPath show the server default library path\n");
+ /* OS-specific usage */
+ xf86UseMsg();
+ ErrorF("\n");
+}
+
+
+/*
+ * xf86LoadModules iterates over a list that is being passed in.
+ */
+Bool
+xf86LoadModules(char **list, pointer *optlist)
+{
+ int errmaj, errmin;
+ pointer opt;
+ int i;
+ char *name;
+ Bool failed = FALSE;
+
+ if (!list)
+ return TRUE;
+
+ for (i = 0; list[i] != NULL; i++) {
+
+ /* Normalise the module name */
+ name = xf86NormalizeName(list[i]);
+
+ /* Skip empty names */
+ if (name == NULL || *name == '\0')
+ continue;
+
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp(name, "keyboard")) {
+ strcpy(name, "kbd");
+ }
+
+ if (optlist)
+ opt = optlist[i];
+ else
+ opt = NULL;
+
+ if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ failed = TRUE;
+ }
+ free(name);
+ }
+ return !failed;
+}
+
+/* Pixmap format stuff */
+
+PixmapFormatPtr
+xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
+{
+ int i;
+ static PixmapFormatRec format; /* XXX not reentrant */
+
+ /*
+ * When the formats[] list initialisation isn't complete, check the
+ * depth 24 pixmap config/cmdline options and screen-specified formats.
+ */
+
+ if (!formatsDone) {
+ if (depth == 24) {
+ Pix24Flags pix24 = Pix24DontCare;
+
+ format.depth = 24;
+ format.scanlinePad = BITMAP_SCANLINE_PAD;
+ if (xf86Info.pixmap24 != Pix24DontCare)
+ pix24 = xf86Info.pixmap24;
+ else if (pScrn->pixmap24 != Pix24DontCare)
+ pix24 = pScrn->pixmap24;
+ if (pix24 == Pix24Use24)
+ format.bitsPerPixel = 24;
+ else
+ format.bitsPerPixel = 32;
+ return &format;
+ }
+ }
+
+ for (i = 0; i < numFormats; i++)
+ if (formats[i].depth == depth)
+ break;
+ if (i != numFormats)
+ return &formats[i];
+ else if (!formatsDone) {
+ /* Check for screen-specified formats */
+ for (i = 0; i < pScrn->numFormats; i++)
+ if (pScrn->formats[i].depth == depth)
+ break;
+ if (i != pScrn->numFormats)
+ return &pScrn->formats[i];
+ }
+ return NULL;
+}
+
+int
+xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
+{
+ PixmapFormatPtr format;
+
+
+ format = xf86GetPixFormat(pScrn, depth);
+ if (format)
+ return format->bitsPerPixel;
+ else
+ return 0;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Mode.c b/xorg-server/hw/xfree86/common/xf86Mode.c
index 5d30a782c..af738e703 100644
--- a/xorg-server/hw/xfree86/common/xf86Mode.c
+++ b/xorg-server/hw/xfree86/common/xf86Mode.c
@@ -1,2067 +1,2067 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * LCM() and scanLineWidth() are:
- *
- * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
- *
- * 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 Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL MARC AURELE LA FRANCE 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.
- *
- * Copyright 1990,91,92,93 by Thomas Roell, Germany.
- * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
- *
- * 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 nor
- * SGCS be used in advertising or publicity pertaining to distribution
- * of the software without specific, written prior permission.
- * Thomas Roell nor SGCS makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS 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.
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * ... and others
- *
- * This file includes helper functions for mode related things.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86Modes.h"
-#include "os.h"
-#include "servermd.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "edid.h"
-
-static void
-printModeRejectMessage(int index, DisplayModePtr p, int status)
-{
- char *type;
-
- if (p->type & M_T_BUILTIN)
- type = "built-in ";
- else if (p->type & M_T_DEFAULT)
- type = "default ";
- else if (p->type & M_T_DRIVER)
- type = "driver ";
- else
- type = "";
-
- xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name,
- xf86ModeStatusToString(status));
-}
-
-/*
- * xf86GetNearestClock --
- * Find closest clock to given frequency (in kHz). This assumes the
- * number of clocks is greater than zero.
- */
-int
-xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- int DivFactor, int MulFactor, int *divider)
-{
- int nearestClock = 0, nearestDiv = 1;
- int minimumGap = abs(freq - scrp->clock[0]);
- int i, j, k, gap;
-
- if (allowDiv2)
- k = 2;
- else
- k = 1;
-
- /* Must set this here in case the best match is scrp->clock[0] */
- if (divider != NULL)
- *divider = 0;
-
- for (i = 0; i < scrp->numClocks; i++) {
- for (j = 1; j <= k; j++) {
- gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor));
- if ((gap < minimumGap) ||
- ((gap == minimumGap) && (j < nearestDiv))) {
- minimumGap = gap;
- nearestClock = i;
- nearestDiv = j;
- if (divider != NULL)
- *divider = (j - 1) * V_CLKDIV2;
- }
- }
- }
- return nearestClock;
-}
-
-/*
- * xf86ModeStatusToString
- *
- * Convert a ModeStatus value to a printable message
- */
-
-const char *
-xf86ModeStatusToString(ModeStatus status)
-{
- switch (status) {
- case MODE_OK:
- return "Mode OK";
- case MODE_HSYNC:
- return "hsync out of range";
- case MODE_VSYNC:
- return "vrefresh out of range";
- case MODE_H_ILLEGAL:
- return "illegal horizontal timings";
- case MODE_V_ILLEGAL:
- return "illegal vertical timings";
- case MODE_BAD_WIDTH:
- return "width requires unsupported line pitch";
- case MODE_NOMODE:
- return "no mode of this name";
- case MODE_NO_INTERLACE:
- return "interlace mode not supported";
- case MODE_NO_DBLESCAN:
- return "doublescan mode not supported";
- case MODE_NO_VSCAN:
- return "multiscan mode not supported";
- case MODE_MEM:
- return "insufficient memory for mode";
- case MODE_VIRTUAL_X:
- return "width too large for virtual size";
- case MODE_VIRTUAL_Y:
- return "height too large for virtual size";
- case MODE_MEM_VIRT:
- return "insufficient memory given virtual size";
- case MODE_NOCLOCK:
- return "no clock available for mode";
- case MODE_CLOCK_HIGH:
- return "mode clock too high";
- case MODE_CLOCK_LOW:
- return "mode clock too low";
- case MODE_CLOCK_RANGE:
- return "bad mode clock/interlace/doublescan";
- case MODE_BAD_HVALUE:
- return "horizontal timing out of range";
- case MODE_BAD_VVALUE:
- return "vertical timing out of range";
- case MODE_BAD_VSCAN:
- return "VScan value out of range";
- case MODE_HSYNC_NARROW:
- return "horizontal sync too narrow";
- case MODE_HSYNC_WIDE:
- return "horizontal sync too wide";
- case MODE_HBLANK_NARROW:
- return "horizontal blanking too narrow";
- case MODE_HBLANK_WIDE:
- return "horizontal blanking too wide";
- case MODE_VSYNC_NARROW:
- return "vertical sync too narrow";
- case MODE_VSYNC_WIDE:
- return "vertical sync too wide";
- case MODE_VBLANK_NARROW:
- return "vertical blanking too narrow";
- case MODE_VBLANK_WIDE:
- return "vertical blanking too wide";
- case MODE_PANEL:
- return "exceeds panel dimensions";
- case MODE_INTERLACE_WIDTH:
- return "width too large for interlaced mode";
- case MODE_ONE_WIDTH:
- return "all modes must have the same width";
- case MODE_ONE_HEIGHT:
- return "all modes must have the same height";
- case MODE_ONE_SIZE:
- return "all modes must have the same resolution";
- case MODE_NO_REDUCED:
- return "monitor doesn't support reduced blanking";
- case MODE_BANDWIDTH:
- return "mode requires too much memory bandwidth";
- case MODE_BAD:
- return "unknown reason";
- case MODE_ERROR:
- return "internal error";
- default:
- return "unknown";
- }
-}
-
-/*
- * xf86ShowClockRanges() -- Print the clock ranges allowed
- * and the clock values scaled by ClockMulFactor and ClockDivFactor
- */
-void
-xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges)
-{
- ClockRangePtr cp;
- int MulFactor = 1;
- int DivFactor = 1;
- int i, j;
- int scaledClock;
-
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- DivFactor = max(1, cp->ClockDivFactor);
- MulFactor = max(1, cp->ClockMulFactor);
- if (scrp->progClock) {
- if (cp->minClock) {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Clock range: %6.2f to %6.2f MHz\n",
- (double)cp->minClock / 1000.0,
- (double)cp->maxClock / 1000.0);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Minimum clock: %6.2f MHz\n",
- (double)cp->minClock / 1000.0);
- }
- } else {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Maximum clock: %6.2f MHz\n",
- (double)cp->maxClock / 1000.0);
- }
- }
- } else if (DivFactor > 1 || MulFactor > 1) {
- j = 0;
- for (i = 0; i < scrp->numClocks; i++) {
- scaledClock = (scrp->clock[i] * DivFactor) / MulFactor;
- if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) {
- if ((j % 8) == 0) {
- if (j > 0)
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:");
- }
- xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0);
- j++;
- }
- }
- xf86ErrorF("\n");
- }
- }
-}
-
-static Bool
-modeInClockRange(ClockRangePtr cp, DisplayModePtr p)
-{
- return ((p->Clock >= cp->minClock) &&
- (p->Clock <= cp->maxClock) &&
- (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) &&
- (cp->doubleScanAllowed ||
- ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN))));
-}
-
-/*
- * xf86FindClockRangeForMode() [... like the name says ...]
- */
-static ClockRangePtr
-xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p)
-{
- ClockRangePtr cp;
-
- for (cp = clockRanges; ; cp = cp->next)
- if (!cp || modeInClockRange(cp, p))
- return cp;
-}
-
-
-/*
- * xf86HandleBuiltinMode() - handles built-in modes
- */
-static ModeStatus
-xf86HandleBuiltinMode(ScrnInfoPtr scrp,
- DisplayModePtr p,
- DisplayModePtr modep,
- ClockRangePtr clockRanges,
- Bool allowDiv2)
-{
- ClockRangePtr cp;
- int extraFlags = 0;
- int MulFactor = 1;
- int DivFactor = 1;
- int clockIndex;
-
- /* Reject previously rejected modes */
- if (p->status != MODE_OK)
- return p->status;
-
- /* Reject previously considered modes */
- if (p->prev)
- return MODE_NOMODE;
-
- if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) {
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL){
- modep->type = p->type;
- p->status = MODE_CLOCK_RANGE;
- return MODE_CLOCK_RANGE;
- }
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- if (!scrp->progClock) {
- clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor,
- cp->ClockMulFactor, &extraFlags);
- modep->Clock = (scrp->clock[clockIndex] * DivFactor)
- / MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor)
- / DivFactor;
- }
- modep->PrivFlags = cp->PrivFlags;
- } else {
- if(!scrp->progClock) {
- modep->Clock = p->Clock;
- modep->ClockIndex = p->ClockIndex;
- modep->SynthClock = p->SynthClock;
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = p->SynthClock;
- }
- modep->PrivFlags = p->PrivFlags;
- }
- modep->type = p->type;
- modep->HDisplay = p->HDisplay;
- modep->HSyncStart = p->HSyncStart;
- modep->HSyncEnd = p->HSyncEnd;
- modep->HTotal = p->HTotal;
- modep->HSkew = p->HSkew;
- modep->VDisplay = p->VDisplay;
- modep->VSyncStart = p->VSyncStart;
- modep->VSyncEnd = p->VSyncEnd;
- modep->VTotal = p->VTotal;
- modep->VScan = p->VScan;
- modep->Flags = p->Flags | extraFlags;
- modep->CrtcHDisplay = p->CrtcHDisplay;
- modep->CrtcHBlankStart = p->CrtcHBlankStart;
- modep->CrtcHSyncStart = p->CrtcHSyncStart;
- modep->CrtcHSyncEnd = p->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = p->CrtcHBlankEnd;
- modep->CrtcHTotal = p->CrtcHTotal;
- modep->CrtcHSkew = p->CrtcHSkew;
- modep->CrtcVDisplay = p->CrtcVDisplay;
- modep->CrtcVBlankStart = p->CrtcVBlankStart;
- modep->CrtcVSyncStart = p->CrtcVSyncStart;
- modep->CrtcVSyncEnd = p->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = p->CrtcVBlankEnd;
- modep->CrtcVTotal = p->CrtcVTotal;
- modep->CrtcHAdjusted = p->CrtcHAdjusted;
- modep->CrtcVAdjusted = p->CrtcVAdjusted;
- modep->HSync = p->HSync;
- modep->VRefresh = p->VRefresh;
- modep->Private = p->Private;
- modep->PrivSize = p->PrivSize;
-
- p->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86LookupMode
- *
- * This function returns a mode from the given list which matches the
- * given name. When multiple modes with the same name are available,
- * the method of picking the matching mode is determined by the
- * strategy selected.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * modep pointer to the returned mode, which must have the name
- * field filled in.
- * clockRanges a list of clock ranges. This is optional when all the
- * modes are built-in modes.
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * modePool the list of monitor modes compatible with the driver
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- *
- * If a mode was found, its values are filled in to the area pointed to
- * by modep, If a mode was not found the return value indicates the
- * reason.
- */
-
-ModeStatus
-xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- ClockRangePtr clockRanges, LookupModeFlags strategy)
-{
- DisplayModePtr p, bestMode = NULL;
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- double refresh, bestRefresh = 0.0;
- Bool found = FALSE;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int n;
- const int types[] = {
- M_T_BUILTIN | M_T_PREFERRED,
- M_T_BUILTIN,
- M_T_USERDEF | M_T_PREFERRED,
- M_T_USERDEF,
- M_T_DRIVER | M_T_PREFERRED,
- M_T_DRIVER,
- 0
- };
- const int ntypes = sizeof(types) / sizeof(int);
-
- strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES);
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->modePool == NULL ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (modep == NULL || modep->name == NULL) {
- ErrorF("xf86LookupMode: called with invalid modep\n");
- return MODE_ERROR;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- /* Scan the mode pool for matching names */
- for (n = 0; n < ntypes; n++) {
- int type = types[n];
- for (p = scrp->modePool; p != NULL; p = p->next) {
-
- /* scan through the modes in the sort order above */
- if ((p->type & type) != type)
- continue;
-
- if (strcmp(p->name, modep->name) == 0) {
-
- /* Skip over previously rejected modes */
- if (p->status != MODE_OK) {
- if (!found)
- status = p->status;
- continue;
- }
-
- /* Skip over previously considered modes */
- if (p->prev)
- continue;
-
- if (p->type & M_T_BUILTIN) {
- return xf86HandleBuiltinMode(scrp, p,modep, clockRanges,
- allowDiv2);
- }
-
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL) {
- /*
- * XXX Could do more here to provide a more detailed
- * reason for not finding a mode.
- */
- p->status = MODE_CLOCK_RANGE;
- if (!found)
- status = MODE_CLOCK_RANGE;
- continue;
- }
-
- /*
- * If programmable clock and strategy is not
- * LOOKUP_BEST_REFRESH, the required mode has been found,
- * otherwise record the refresh and continue looking.
- */
- if (scrp->progClock) {
- found = TRUE;
- if (strategy != LOOKUP_BEST_REFRESH) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- break;
- }
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- bestRefresh = refresh;
- }
- continue;
- }
-
- /*
- * Clock is in range, so if it is not a programmable clock, find
- * a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((p->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(p->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- p->status = MODE_NOCLOCK;
- if (!found)
- status = MODE_NOCLOCK;
- continue;
- }
- found = TRUE;
-
- if (strategy == LOOKUP_BEST_REFRESH) {
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- bestRefresh = refresh;
- }
- continue;
- }
- if (strategy == LOOKUP_CLOSEST_CLOCK) {
- if (gap < minimumGap) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- minimumGap = gap;
- }
- continue;
- }
- /*
- * If strategy is neither LOOKUP_BEST_REFRESH or
- * LOOKUP_CLOSEST_CLOCK the required mode has been found.
- */
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (found) break;
- }
- if (!found || bestMode == NULL)
- return status;
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- modep->Clock = bestMode->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor) / DivFactor;
- } else {
- modep->Clock = (scrp->clock[clockIndex] * DivFactor) /
- MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- }
- modep->type = bestMode->type;
- modep->PrivFlags = ModePrivFlags;
- modep->HDisplay = bestMode->HDisplay;
- modep->HSyncStart = bestMode->HSyncStart;
- modep->HSyncEnd = bestMode->HSyncEnd;
- modep->HTotal = bestMode->HTotal;
- modep->HSkew = bestMode->HSkew;
- modep->VDisplay = bestMode->VDisplay;
- modep->VSyncStart = bestMode->VSyncStart;
- modep->VSyncEnd = bestMode->VSyncEnd;
- modep->VTotal = bestMode->VTotal;
- modep->VScan = bestMode->VScan;
- modep->Flags = bestMode->Flags | extraFlags;
- modep->CrtcHDisplay = bestMode->CrtcHDisplay;
- modep->CrtcHBlankStart = bestMode->CrtcHBlankStart;
- modep->CrtcHSyncStart = bestMode->CrtcHSyncStart;
- modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd;
- modep->CrtcHTotal = bestMode->CrtcHTotal;
- modep->CrtcHSkew = bestMode->CrtcHSkew;
- modep->CrtcVDisplay = bestMode->CrtcVDisplay;
- modep->CrtcVBlankStart = bestMode->CrtcVBlankStart;
- modep->CrtcVSyncStart = bestMode->CrtcVSyncStart;
- modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd;
- modep->CrtcVTotal = bestMode->CrtcVTotal;
- modep->CrtcHAdjusted = bestMode->CrtcHAdjusted;
- modep->CrtcVAdjusted = bestMode->CrtcVAdjusted;
- modep->HSync = bestMode->HSync;
- modep->VRefresh = bestMode->VRefresh;
- modep->Private = bestMode->Private;
- modep->PrivSize = bestMode->PrivSize;
-
- bestMode->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForMonitor
- *
- * This function takes a mode and monitor description, and determines
- * if the mode is valid for the monitor.
- */
-ModeStatus
-xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
-{
- int i;
-
- /* Sanity checks */
- if (mode == NULL || monitor == NULL) {
- ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
- mode, mode->name, monitor, monitor->id);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (monitor->nHsync > 0) {
- /* Check hsync against the allowed ranges */
- float hsync = xf86ModeHSync(mode);
- for (i = 0; i < monitor->nHsync; i++)
- if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of sync ranges without finding a match */
- if (i == monitor->nHsync)
- return MODE_HSYNC;
- }
-
- if (monitor->nVrefresh > 0) {
- /* Check vrefresh against the allowed ranges */
- float vrefrsh = xf86ModeVRefresh(mode);
- for (i = 0; i < monitor->nVrefresh; i++)
- if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of refresh ranges without finding a match */
- if (i == monitor->nVrefresh)
- return MODE_VSYNC;
- }
-
- /* Force interlaced modes to have an odd VTotal */
- if (mode->Flags & V_INTERLACE)
- mode->CrtcVTotal = mode->VTotal |= 1;
-
- /*
- * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+
- * old CRTs which might, when there is a lot of solar flare activity and
- * when the celestial bodies are unfavourably aligned, implode trying to
- * sync to it. It's called "Protecting the user from doing anything stupid".
- * -- libv
- */
-
- if (xf86ModeIsReduced(mode)) {
- if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
- return MODE_NO_REDUCED;
- }
-
- if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeSize
- *
- * An internal routine to check if a mode fits in video memory. This tries to
- * avoid overflows that would otherwise occur when video memory size is greater
- * than 256MB.
- */
-static Bool
-xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y)
-{
- int bpp = scrp->fbFormat.bitsPerPixel,
- pad = scrp->fbFormat.scanlinePad;
- int lineWidth, lastWidth;
-
- if (scrp->depth == 4)
- pad *= 4; /* 4 planes */
-
- /* Sanity check */
- if ((w < 0) || (x < 0) || (y <= 0))
- return FALSE;
-
- lineWidth = (((w * bpp) + pad - 1) / pad) * pad;
- lastWidth = x * bpp;
-
- /*
- * At this point, we need to compare
- *
- * (lineWidth * (y - 1)) + lastWidth
- *
- * against
- *
- * scrp->videoRam * (1024 * 8)
- *
- * These are bit quantities. To avoid overflows, do the comparison in
- * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD
- * is a power of 2. We currently use 32, which limits us to a video
- * memory size of 8GB.
- */
-
- lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
- lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
-
- if ((lineWidth * (y - 1) + lastWidth) >
- (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD)))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * xf86InitialCheckModeForDriver
- *
- * This function checks if a mode satisfies a driver's initial requirements:
- * - mode size fits within the available pixel area (memory)
- * - width lies within the range of supported line pitches
- * - mode size fits within virtual size (if fixed)
- * - horizontal timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * maxPitch (optional) maximum line pitch
- * virtualX (optional) virtual width requested
- * virtualY (optional) virtual height requested
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * monitor pointer to structure for monitor section
- * fbFormat pixel format for the framebuffer
- * videoRam video memory size (in kB)
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- */
-
-ModeStatus
-xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- ClockRangePtr clockRanges,
- LookupModeFlags strategy,
- int maxPitch, int virtualX, int virtualY)
-{
- ClockRangePtr cp;
- ModeStatus status;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int i, needDiv2;
-
- /* Sanity checks */
- if (!scrp || !mode || !clockRanges) {
- ErrorF("xf86InitialCheckModeForDriver: "
- "called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
- scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay,
- mode->VDisplay))
- return MODE_MEM;
-
- if (maxPitch > 0 && mode->HDisplay > maxPitch)
- return MODE_BAD_WIDTH;
-
- if (virtualX > 0 && mode->HDisplay > virtualX)
- return MODE_VIRTUAL_X;
-
- if (virtualY > 0 && mode->VDisplay > virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- /*
- * The use of the DisplayModeRec's Crtc* and SynthClock elements below is
- * provisional, in that they are later reused by the driver at mode-set
- * time. Here, they are temporarily enlisted to contain the mode timings
- * as seen by the CRT or panel (rather than the CRTC). The driver's
- * ValidMode() is allowed to modify these so it can deal with such things
- * as mode stretching and/or centering. The driver should >NOT< modify the
- * user-supplied values as these are reported back when mode validation is
- * said and done.
- */
- /*
- * NOTE: We (ab)use the mode->Crtc* values here to store timing
- * information for the calculation of Hsync and Vrefresh. Before
- * these values are calculated the driver is given the opportunity
- * to either set these HSync and VRefresh itself or modify the timing
- * values.
- * The difference to the final calculation is small but imortand:
- * here we pass the flag INTERLACE_HALVE_V regardless if the driver
- * sets it or not. This way our calculation of VRefresh has the same
- * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0
- * This dual use of the mode->Crtc* values will certainly create
- * confusion and is bad software design. However since it's part of
- * the driver API it's hard to change.
- */
-
- if (scrp->ValidMode) {
-
- xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
- cp = xf86FindClockRangeForMode(clockRanges, mode);
- if (!cp)
- return MODE_CLOCK_RANGE;
-
- if (cp->ClockMulFactor < 1)
- cp->ClockMulFactor = 1;
- if (cp->ClockDivFactor < 1)
- cp->ClockDivFactor = 1;
-
- /*
- * XXX The effect of clock dividers and multipliers on the monitor's
- * pixel clock needs to be verified.
- */
- if (scrp->progClock) {
- mode->SynthClock = mode->Clock;
- } else {
- i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor,
- &needDiv2);
- mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor;
- if (needDiv2 & V_CLKDIV2)
- mode->SynthClock /= 2;
- }
-
- status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE,
- MODECHECK_INITIAL);
- if (status != MODE_OK)
- return status;
-
- if (mode->HSync <= 0.0)
- mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal;
- if (mode->VRefresh <= 0.0)
- mode->VRefresh = (mode->SynthClock * 1000.0)
- / (mode->CrtcHTotal * mode->CrtcVTotal);
- }
-
- mode->HSync = xf86ModeHSync(mode);
- mode->VRefresh = xf86ModeVRefresh(mode);
-
- /* Assume it is OK */
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForDriver
- *
- * This function is for checking modes while the server is running (for
- * use mainly by the VidMode extension).
- *
- * This function checks if a mode satisfies a driver's requirements:
- * - width lies within the line pitch
- * - mode size fits within virtual size
- * - horizontal/vertical timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * flags not (currently) used
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * virtualX virtual width
- * virtualY virtual height
- * clockRanges allowable clock ranges
- */
-
-ModeStatus
-xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags)
-{
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
-
- /* Some sanity checking */
- if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (mode == NULL) {
- ErrorF("xf86CheckModeForDriver: called with invalid modep\n");
- return MODE_ERROR;
- }
-
- /* Check the mode size */
- if (mode->HDisplay > scrp->virtualX)
- return MODE_VIRTUAL_X;
-
- if (mode->VDisplay > scrp->virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- if (scrp->progClock) {
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode))
- break;
- }
- if (cp == NULL) {
- return MODE_CLOCK_RANGE;
- }
- /*
- * If programmable clock the required mode has been found
- */
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- } else {
- status = MODE_CLOCK_RANGE;
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode)) {
- /*
- * Clock is in range, so if it is not a programmable clock,
- * find a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, mode->Clock, 0,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((mode->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(mode->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- status = MODE_NOCLOCK;
- continue;
- }
-
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (cp == NULL)
- return status;
- }
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- mode->ClockIndex = -1;
- mode->SynthClock = (mode->Clock * MulFactor) / DivFactor;
- } else {
- mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor;
- mode->ClockIndex = clockIndex;
- mode->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- mode->Clock /= 2;
- mode->SynthClock /= 2;
- }
- }
- mode->PrivFlags = ModePrivFlags;
-
- return MODE_OK;
-}
-
-static int
-inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy)
-{
- float aspect = 0.0;
- MonPtr mon = scrp->monitor;
- xf86MonPtr DDC;
- int x = 0, y = 0;
- DisplayModePtr mode;
-
- if (!mon) return 0;
- DDC = mon->DDC;
-
- if (DDC && DDC->ver.revision >= 4) {
- /* For 1.4, we might actually get native pixel format. How novel. */
- if (PREFERRED_TIMING_MODE(DDC->features.msc)) {
- for (mode = modes; mode; mode = mode->next) {
- if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- goto found;
- }
- }
- }
- /*
- * Even if we don't, we might get aspect ratio from extra CVT info
- * or from the monitor size fields. TODO.
- */
- }
-
- /*
- * Technically this triggers if either is zero. That wasn't legal
- * before EDID 1.4, but right now we'll get that wrong. TODO.
- */
- if (!aspect) {
- if (!mon->widthmm || !mon->heightmm)
- aspect = 4.0/3.0;
- else
- aspect = (float)mon->widthmm / (float)mon->heightmm;
- }
-
- /* find the largest M_T_DRIVER mode with that aspect ratio */
- for (mode = modes; mode; mode = mode->next) {
- float mode_aspect, metaspect;
- if (!(mode->type & (M_T_DRIVER|M_T_USERDEF)))
- continue;
- mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay;
- metaspect = aspect / mode_aspect;
- /* 5% slop or so, since we only get size in centimeters */
- if (fabs(1.0 - metaspect) < 0.05) {
- if ((mode->HDisplay > x) && (mode->VDisplay > y)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- }
- }
- }
-
- if (!x || !y) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Unable to estimate virtual size\n");
- return 0;
- }
-
-found:
- *vx = x;
- *vy = y;
-
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Estimated virtual size for aspect ratio %.4f is %dx%d\n",
- aspect, *vx, *vy);
-
- return 1;
-}
-
-/* Least common multiple */
-static unsigned int
-LCM(unsigned int x, unsigned int y)
-{
- unsigned int m = x, n = y, o;
-
- while ((o = m % n))
- {
- m = n;
- n = o;
- }
-
- return (x / n) * y;
-}
-
-/*
- * Given various screen attributes, determine the minimum scanline width such
- * that each scanline is server and DDX padded and any pixels with imbedded
- * bank boundaries are off-screen. This function returns -1 if such a width
- * cannot exist.
- */
-static int
-scanLineWidth(
- unsigned int xsize, /* pixels */
- unsigned int ysize, /* pixels */
- unsigned int width, /* pixels */
- unsigned long BankSize, /* char's */
- PixmapFormatRec *pBankFormat,
- unsigned int nWidthUnit /* bits */
-)
-{
- unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
- unsigned long minBitsPerScanline, maxBitsPerScanline;
-
- /* Sanity checks */
-
- if (!nWidthUnit || !pBankFormat)
- return -1;
-
- nBitsPerBank = BankSize * 8;
- if (nBitsPerBank % pBankFormat->scanlinePad)
- return -1;
-
- if (xsize > width)
- width = xsize;
- nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
- nBitsPerScanline =
- (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
- nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
-
- if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
- return (int)width;
-
- /*
- * Scanlines will be server-pad aligned at this point. They will also be
- * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
- * bank boundaries are off-screen.
- *
- * It seems reasonable to limit total frame buffer size to 1/16 of the
- * theoretical maximum address space size. On a machine with 32-bit
- * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
- * does this provide a simple limiting condition for the loops below, but
- * it also prevents unsigned long wraparounds.
- */
- if (!ysize)
- return -1;
-
- minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
- if (minBitsPerScanline > nBitsPerBank)
- return -1;
-
- if (ysize == 1)
- return (int)width;
-
- maxBitsPerScanline =
- (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
- while (nBitsPerScanline <= maxBitsPerScanline)
- {
- unsigned long BankBase, BankUnit;
-
- BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
- nBitsPerBank;
- if (!(BankUnit % nBitsPerScanline))
- return (int)width;
-
- for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
- {
- unsigned long x, y;
-
- y = BankBase / nBitsPerScanline;
- if (y >= ysize)
- return (int)width;
-
- x = BankBase % nBitsPerScanline;
- if (!(x % pBankFormat->bitsPerPixel))
- continue;
-
- if (x < minBitsPerScanline)
- {
- /*
- * Skip ahead certain widths by dividing the excess scanline
- * amongst the y's.
- */
- y *= nBitsPerScanlinePadUnit;
- nBitsPerScanline +=
- ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
- break;
- }
-
- if (BankBase != BankUnit)
- continue;
-
- if (!(nBitsPerScanline % x))
- return (int)width;
-
- BankBase = ((nBitsPerScanline - minBitsPerScanline) /
- (nBitsPerScanline - x)) * BankUnit;
- }
- }
-
- return -1;
-}
-
-/*
- * xf86ValidateModes
- *
- * This function takes a set of mode names, modes and limiting conditions,
- * and selects a set of modes and parameters based on those conditions.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * availModes the list of modes available for the monitor
- * modeNames (optional) list of mode names that the screen is requesting
- * clockRanges a list of clock ranges
- * linePitches (optional) a list of line pitches
- * minPitch (optional) minimum line pitch (in pixels)
- * maxPitch (optional) maximum line pitch (in pixels)
- * pitchInc (mandatory) pitch increment (in bits)
- * minHeight (optional) minimum virtual height (in pixels)
- * maxHeight (optional) maximum virtual height (in pixels)
- * virtualX (optional) virtual width requested (in pixels)
- * virtualY (optional) virtual height requested (in pixels)
- * apertureSize size of video aperture (in bytes)
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- * monitor pointer to structure for monitor section
- * fbFormat format of the framebuffer
- * videoRam video memory size
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * xInc horizontal timing increment (defaults to 8 pixels)
- *
- * The function fills in the following ScrnInfoRec fields:
- * modePool A subset of the modes available to the monitor which
- * are compatible with the driver.
- * modes one mode entry for each of the requested modes, with the
- * status field filled in to indicate if the mode has been
- * accepted or not.
- * virtualX the resulting virtual width
- * virtualY the resulting virtual height
- * displayWidth the resulting line pitch
- *
- * The function's return value is the number of matching modes found, or -1
- * if an unrecoverable error was encountered.
- */
-
-int
-xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch, int pitchInc,
- int minHeight, int maxHeight, int virtualX, int virtualY,
- int apertureSize, LookupModeFlags strategy)
-{
- DisplayModePtr p, q, r, new, last, *endp;
- int i, numModes = 0;
- ModeStatus status;
- int linePitch = -1, virtX = 0, virtY = 0;
- int newLinePitch, newVirtX, newVirtY;
- int modeSize; /* in pixels */
- Bool validateAllDefaultModes = FALSE;
- Bool userModes = FALSE;
- int saveType;
- PixmapFormatRec *BankFormat;
- ClockRangePtr cp;
- ClockRangePtr storeClockRanges;
- int numTimings = 0;
- range hsync[MAX_HSYNC];
- range vrefresh[MAX_VREFRESH];
- Bool inferred_virtual = FALSE;
-
- DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
- scrp, availModes, modeNames, clockRanges,
- linePitches, minPitch, maxPitch, pitchInc,
- minHeight, maxHeight, virtualX, virtualY,
- apertureSize, strategy
- );
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n");
- return -1;
- }
- if (linePitches != NULL && linePitches[0] <= 0) {
- ErrorF("xf86ValidateModes: called with invalid linePitches\n");
- return -1;
- }
- if (pitchInc <= 0) {
- ErrorF("xf86ValidateModes: called with invalid pitchInc\n");
- return -1;
- }
- if ((virtualX > 0) != (virtualY > 0)) {
- ErrorF("xf86ValidateModes: called with invalid virtual resolution\n");
- return -1;
- }
-
- /*
- * If requested by the driver, allow missing hsync and/or vrefresh ranges
- * in the monitor section.
- */
- if (strategy & LOOKUP_OPTIONAL_TOLERANCES) {
- strategy &= ~LOOKUP_OPTIONAL_TOLERANCES;
- } else {
- const char *type = "";
-
- if (scrp->monitor->nHsync <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nHsync = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->hsync[i].lo = hsync[i].lo;
- scrp->monitor->hsync[i].hi = hsync[i].hi;
- }
- } else {
- scrp->monitor->hsync[0].lo = 31.5;
- scrp->monitor->hsync[0].hi = 37.9;
- scrp->monitor->nHsync = 1;
- }
- type = "default ";
- }
- for (i = 0; i < scrp->monitor->nHsync; i++) {
- if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync value of %.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync range of %.2f-%.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo,
- scrp->monitor->hsync[i].hi);
- }
-
- type = "";
- if (scrp->monitor->nVrefresh <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nVrefresh = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->vrefresh[i].lo = vrefresh[i].lo;
- scrp->monitor->vrefresh[i].hi = vrefresh[i].hi;
- }
- } else {
- scrp->monitor->vrefresh[0].lo = 50;
- scrp->monitor->vrefresh[0].hi = 70;
- scrp->monitor->nVrefresh = 1;
- }
- type = "default ";
- }
- for (i = 0; i < scrp->monitor->nVrefresh; i++) {
- if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh value of %.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh range of %.2f-%.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo,
- scrp->monitor->vrefresh[i].hi);
- }
- if (scrp->monitor->maxPixClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using maximum pixel clock of %.2f MHz\n",
- scrp->monitor->id,
- (float)scrp->monitor->maxPixClock / 1000.0);
- }
- }
-
- /*
- * Store the clockRanges for later use by the VidMode extension.
- */
- storeClockRanges = scrp->clockRanges;
- while (storeClockRanges != NULL) {
- storeClockRanges = storeClockRanges->next;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next,
- storeClockRanges = storeClockRanges->next) {
- storeClockRanges = xnfalloc(sizeof(ClockRange));
- if (scrp->clockRanges == NULL)
- scrp->clockRanges = storeClockRanges;
- memcpy(storeClockRanges, cp, sizeof(ClockRange));
- }
-
- /* Determine which pixmap format to pass to scanLineWidth() */
- if (scrp->depth > 4)
- BankFormat = &scrp->fbFormat;
- else
- BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */
-
- if (scrp->xInc <= 0)
- scrp->xInc = 8; /* Suitable for VGA and others */
-
-#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc)
-
- /*
- * Determine maxPitch if it wasn't given explicitly. Note linePitches
- * always takes precedence if is non-NULL. In that case the minPitch and
- * maxPitch values passed are ignored.
- */
- if (linePitches) {
- minPitch = maxPitch = linePitches[0];
- for (i = 1; linePitches[i] > 0; i++) {
- if (linePitches[i] > maxPitch)
- maxPitch = linePitches[i];
- if (linePitches[i] < minPitch)
- minPitch = linePitches[i];
- }
- }
-
- /* Initial check of virtual size against other constraints */
- scrp->virtualFrom = X_PROBED;
- /*
- * Initialise virtX and virtY if the values are fixed.
- */
- if (virtualY > 0) {
- if (maxHeight > 0 && virtualY > maxHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too large for the hardware "
- "(max %d)\n", virtualY, maxHeight);
- return -1;
- }
-
- if (minHeight > 0 && virtualY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtualY, minHeight);
- return -1;
- }
-
- virtualX = _VIRTUALX(virtualX);
- if (linePitches != NULL) {
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= virtualX) &&
- (linePitches[i] ==
- scanLineWidth(virtualX, virtualY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- linePitch = linePitches[i];
- break;
- }
- }
- } else {
- linePitch = scanLineWidth(virtualX, virtualY, minPitch,
- apertureSize, BankFormat, pitchInc);
- }
-
- if ((linePitch < minPitch) || (linePitch > maxPitch)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual width (%d) is too large for the hardware "
- "(max %d)\n", virtualX, maxPitch);
- return -1;
- }
-
- if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual size (%dx%d) (pitch %d) exceeds video memory\n",
- virtualX, virtualY, linePitch);
- return -1;
- }
-
- virtX = virtualX;
- virtY = virtualY;
- scrp->virtualFrom = X_CONFIG;
- } else if (!modeNames || !*modeNames) {
- /* No virtual size given in the config, try to infer */
- /* XXX this doesn't take m{in,ax}Pitch into account; oh well */
- inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
- if (inferred_virtual)
- linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
- BankFormat, pitchInc);
- }
-
- /* Print clock ranges and scaled clocks */
- xf86ShowClockRanges(scrp, clockRanges);
-
- /*
- * If scrp->modePool hasn't been setup yet, set it up now. This allows the
- * modes that the driver definitely can't use to be weeded out early. Note
- * that a modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- */
- if (scrp->modePool == NULL) {
- q = NULL;
- for (p = availModes; p != NULL; p = p->next) {
- status = xf86InitialCheckModeForDriver(scrp, p, clockRanges,
- strategy, maxPitch,
- virtX, virtY);
-
- if (status == MODE_OK) {
- status = xf86CheckModeForMonitor(p, scrp->monitor);
- }
-
- if (status == MODE_OK) {
- new = xnfalloc(sizeof(DisplayModeRec));
- *new = *p;
- new->next = NULL;
- if (!q) {
- scrp->modePool = new;
- } else {
- q->next = new;
- }
- new->prev = NULL;
- q = new;
- q->name = xnfstrdup(p->name);
- q->status = MODE_OK;
- } else {
- printModeRejectMessage(scrp->scrnIndex, p, status);
- }
- }
-
- if (scrp->modePool == NULL) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n");
- return 0;
- }
- } else {
- for (p = scrp->modePool; p != NULL; p = p->next) {
- p->prev = NULL;
- p->status = MODE_OK;
- }
- }
-
- /*
- * Allocate one entry in scrp->modes for each named mode.
- */
- while (scrp->modes)
- xf86DeleteMode(&scrp->modes, scrp->modes);
- endp = &scrp->modes;
- last = NULL;
- if (modeNames != NULL) {
- for (i = 0; modeNames[i] != NULL; i++) {
- userModes = TRUE;
- new = xnfcalloc(1, sizeof(DisplayModeRec));
- new->prev = last;
- new->type = M_T_USERDEF;
- new->name = xnfalloc(strlen(modeNames[i]) + 1);
- strcpy(new->name, modeNames[i]);
- if (new->prev)
- new->prev->next = new;
- *endp = last = new;
- endp = &new->next;
- }
- }
-
- /* Lookup each mode */
-#ifdef RANDR
- if (!xf86Info.disableRandR
-#ifdef PANORAMIX
- && noPanoramiXExtension
-#endif
- )
- validateAllDefaultModes = TRUE;
-#endif
-
- for (p = scrp->modes; ; p = p->next) {
- Bool repeat;
-
- /*
- * If the supplied mode names don't produce a valid mode, scan through
- * unconsidered modePool members until one survives validation. This
- * is done in decreasing order by mode pixel area.
- */
-
- if (p == NULL) {
- if ((numModes > 0) && !validateAllDefaultModes)
- break;
-
- validateAllDefaultModes = TRUE;
- r = NULL;
- modeSize = 0;
- for (q = scrp->modePool; q != NULL; q = q->next) {
- if ((q->prev == NULL) && (q->status == MODE_OK)) {
- /*
- * Deal with the case where this mode wasn't considered
- * because of a builtin mode of the same name.
- */
- for (p = scrp->modes; p != NULL; p = p->next) {
- if ((p->status != MODE_OK) &&
- !strcmp(p->name, q->name))
- break;
- }
-
- if (p != NULL)
- q->prev = p;
- else {
- /*
- * A quick check to not allow default modes with
- * horizontal timing parameters that CRTs may have
- * problems with.
- */
- if (!scrp->monitor->reducedblanking &&
- (q->type & M_T_DEFAULT) &&
- ((double)q->HTotal / (double)q->HDisplay) < 1.15)
- continue;
-
- if (modeSize < (q->HDisplay * q->VDisplay)) {
- r = q;
- modeSize = q->HDisplay * q->VDisplay;
- }
- }
- }
- }
-
- if (r == NULL)
- break;
-
- p = xnfcalloc(1, sizeof(DisplayModeRec));
- p->prev = last;
- p->name = xnfalloc(strlen(r->name) + 1);
- if (!userModes)
- p->type = M_T_USERDEF;
- strcpy(p->name, r->name);
- if (p->prev)
- p->prev->next = p;
- *endp = last = p;
- endp = &p->next;
- }
-
- repeat = FALSE;
- lookupNext:
- if (repeat && ((status = p->status) != MODE_OK))
- printModeRejectMessage(scrp->scrnIndex, p, status);
- saveType = p->type;
- status = xf86LookupMode(scrp, p, clockRanges, strategy);
- if (repeat && status == MODE_NOMODE)
- continue;
- if (status != MODE_OK)
- printModeRejectMessage(scrp->scrnIndex, p, status);
- if (status == MODE_ERROR) {
- ErrorF("xf86ValidateModes: "
- "unexpected result from xf86LookupMode()\n");
- return -1;
- }
- if (status != MODE_OK) {
- if (p->status == MODE_OK)
- p->status = status;
- continue;
- }
- p->type |= saveType;
- repeat = TRUE;
-
- newLinePitch = linePitch;
- newVirtX = virtX;
- newVirtY = virtY;
-
- /*
- * Don't let non-user defined modes increase the virtual size
- */
- if (!(p->type & M_T_USERDEF) && (numModes > 0)) {
- if (p->HDisplay > virtX) {
- p->status = MODE_VIRTUAL_X;
- goto lookupNext;
- }
- if (p->VDisplay > virtY) {
- p->status = MODE_VIRTUAL_Y;
- goto lookupNext;
- }
- }
- /*
- * Adjust virtual width and height if the mode is too large for the
- * current values and if they are not fixed.
- */
- if (virtualX <= 0 && p->HDisplay > newVirtX)
- newVirtX = _VIRTUALX(p->HDisplay);
- if (virtualY <= 0 && p->VDisplay > newVirtY) {
- if (maxHeight > 0 && p->VDisplay > maxHeight) {
- p->status = MODE_VIRTUAL_Y; /* ? */
- goto lookupNext;
- }
- newVirtY = p->VDisplay;
- }
-
- /*
- * If virtual resolution is to be increased, revalidate it.
- */
- if ((virtX != newVirtX) || (virtY != newVirtY)) {
- if (linePitches != NULL) {
- newLinePitch = -1;
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= newVirtX) &&
- (linePitches[i] >= linePitch) &&
- (linePitches[i] ==
- scanLineWidth(newVirtX, newVirtY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- newLinePitch = linePitches[i];
- break;
- }
- }
- } else {
- if (linePitch < minPitch)
- linePitch = minPitch;
- newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
- apertureSize, BankFormat,
- pitchInc);
- }
- if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
- p->status = MODE_BAD_WIDTH;
- goto lookupNext;
- }
-
- /*
- * Check that the pixel area required by the new virtual height
- * and line pitch isn't too large.
- */
- if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) {
- p->status = MODE_MEM_VIRT;
- goto lookupNext;
- }
- }
-
- if (scrp->ValidMode) {
- /*
- * Give the driver a final say, passing it the proposed virtual
- * geometry.
- */
- scrp->virtualX = newVirtX;
- scrp->virtualY = newVirtY;
- scrp->displayWidth = newLinePitch;
- p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE,
- MODECHECK_FINAL);
-
- if (p->status != MODE_OK) {
- goto lookupNext;
- }
- }
-
- /* Mode has passed all the tests */
- virtX = newVirtX;
- virtY = newVirtY;
- linePitch = newLinePitch;
- p->status = MODE_OK;
- numModes++;
- }
-
-#undef _VIRTUALX
-
- /*
- * If we estimated the virtual size above, we may have filtered away all
- * the modes that maximally match that size; scan again to find out and
- * fix up if so.
- */
- if (inferred_virtual) {
- int vx = 0, vy = 0;
- for (p = scrp->modes; p; p = p->next) {
- if (p->HDisplay > vx && p->VDisplay > vy) {
- vx = p->HDisplay;
- vy = p->VDisplay;
- }
- }
- if (vx < virtX || vy < virtY) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Shrinking virtual size estimate from %dx%d to %dx%d\n",
- virtX, virtY, vx, vy);
- virtX = vx;
- virtY = vy;
- linePitch = scanLineWidth(vx, vy, minPitch, apertureSize,
- BankFormat, pitchInc);
- }
- }
-
- /* Update the ScrnInfoRec parameters */
-
- scrp->virtualX = virtX;
- scrp->virtualY = virtY;
- scrp->displayWidth = linePitch;
-
- if (numModes <= 0)
- return 0;
-
- /* Make the mode list into a circular list by joining up the ends */
- p = scrp->modes;
- while (p->next != NULL)
- p = p->next;
- /* p is now the last mode on the list */
- p->next = scrp->modes;
- scrp->modes->prev = p;
-
- if (minHeight > 0 && virtY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtY, minHeight);
- return -1;
- }
-
- return numModes;
-}
-
-/*
- * xf86DeleteMode
- *
- * This function removes a mode from a list of modes.
- *
- * There are different types of mode lists:
- *
- * - singly linked linear lists, ending in NULL
- * - doubly linked linear lists, starting and ending in NULL
- * - doubly linked circular lists
- *
- */
-
-void
-xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)
-{
- /* Catch the easy/insane cases */
- if (modeList == NULL || *modeList == NULL || mode == NULL)
- return;
-
- /* If the mode is at the start of the list, move the start of the list */
- if (*modeList == mode)
- *modeList = mode->next;
-
- /* If mode is the only one on the list, set the list to NULL */
- if ((mode == mode->prev) && (mode == mode->next)) {
- *modeList = NULL;
- } else {
- if ((mode->prev != NULL) && (mode->prev->next == mode))
- mode->prev->next = mode->next;
- if ((mode->next != NULL) && (mode->next->prev == mode))
- mode->next->prev = mode->prev;
- }
-
- xfree(mode->name);
- xfree(mode);
-}
-
-/*
- * xf86PruneDriverModes
- *
- * Remove modes from the driver's mode list which have been marked as
- * invalid.
- */
-
-void
-xf86PruneDriverModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr first, p, n;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- if (!(first = scrp->modes))
- return;
- n = p->next;
- if (p->status != MODE_OK) {
- xf86DeleteMode(&(scrp->modes), p);
- }
- p = n;
- } while (p != NULL && p != first);
-
- /* modePool is no longer needed, turf it */
- while (scrp->modePool) {
- /*
- * A modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- * Clear that pointer first, otherwise xf86DeleteMode might get
- * confused
- */
- scrp->modePool->prev = NULL;
- xf86DeleteMode(&scrp->modePool, scrp->modePool);
- }
-}
-
-
-/*
- * xf86SetCrtcForModes
- *
- * Goes through the screen's mode list, and initialises the Crtc
- * parameters for each mode. The initialisation includes adjustments
- * for interlaced and double scan modes.
- */
-void
-xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
-{
- DisplayModePtr p;
-
- /*
- * Store adjustFlags for use with the VidMode extension. There is an
- * implicit assumption here that SetCrtcForModes is called once.
- */
- scrp->adjustFlags = adjustFlags;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- xf86SetModeCrtc(p, adjustFlags);
- DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
- (p->type & M_T_DEFAULT) ? "Default " : "",
- p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
- p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
- p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
- p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
- p->CrtcVTotal);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
-
-void
-xf86PrintModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr p;
- float hsync, refresh = 0;
- char *desc, *desc2, *prefix, *uprefix;
-
- if (scrp == NULL)
- return;
-
- xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
- "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
- scrp->displayWidth);
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- desc = desc2 = "";
- hsync = xf86ModeHSync(p);
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE) {
- desc = " (I)";
- }
- if (p->Flags & V_DBLSCAN) {
- desc = " (D)";
- }
- if (p->VScan > 1) {
- desc2 = " (VScan)";
- }
- if (p->type & M_T_BUILTIN)
- prefix = "Built-in mode";
- else if (p->type & M_T_DEFAULT)
- prefix = "Default mode";
- else if (p->type & M_T_DRIVER)
- prefix = "Driver mode";
- else
- prefix = "Mode";
- if (p->type & M_T_USERDEF)
- uprefix = "*";
- else
- uprefix = " ";
- if (hsync == 0 || refresh == 0) {
- if (p->name)
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\"\n", uprefix, prefix, p->name);
- else
- xf86DrvMsg(scrp->scrnIndex, X_PROBED,
- "%s%s %dx%d (unnamed)\n",
- uprefix, prefix, p->HDisplay, p->VDisplay);
- } else if (p->Clock == p->SynthClock) {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- hsync, refresh, desc, desc2);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), "
- "%.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- p->SynthClock / 1000.0, hsync, refresh, desc, desc2);
- }
- if (hsync != 0 && refresh != 0)
- xf86PrintModeline(scrp->scrnIndex,p);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * LCM() and scanLineWidth() are:
+ *
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * 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 Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ *
+ * Copyright 1990,91,92,93 by Thomas Roell, Germany.
+ * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
+ *
+ * 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 nor
+ * SGCS be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Thomas Roell nor SGCS makes no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS 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.
+ */
+
+/*
+ * Authors: Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * Marc La France <tsi@XFree86.Org>
+ * ... and others
+ *
+ * This file includes helper functions for mode related things.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "xf86Modes.h"
+#include "os.h"
+#include "servermd.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "edid.h"
+
+static void
+printModeRejectMessage(int index, DisplayModePtr p, int status)
+{
+ char *type;
+
+ if (p->type & M_T_BUILTIN)
+ type = "built-in ";
+ else if (p->type & M_T_DEFAULT)
+ type = "default ";
+ else if (p->type & M_T_DRIVER)
+ type = "driver ";
+ else
+ type = "";
+
+ xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name,
+ xf86ModeStatusToString(status));
+}
+
+/*
+ * xf86GetNearestClock --
+ * Find closest clock to given frequency (in kHz). This assumes the
+ * number of clocks is greater than zero.
+ */
+int
+xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ int DivFactor, int MulFactor, int *divider)
+{
+ int nearestClock = 0, nearestDiv = 1;
+ int minimumGap = abs(freq - scrp->clock[0]);
+ int i, j, k, gap;
+
+ if (allowDiv2)
+ k = 2;
+ else
+ k = 1;
+
+ /* Must set this here in case the best match is scrp->clock[0] */
+ if (divider != NULL)
+ *divider = 0;
+
+ for (i = 0; i < scrp->numClocks; i++) {
+ for (j = 1; j <= k; j++) {
+ gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor));
+ if ((gap < minimumGap) ||
+ ((gap == minimumGap) && (j < nearestDiv))) {
+ minimumGap = gap;
+ nearestClock = i;
+ nearestDiv = j;
+ if (divider != NULL)
+ *divider = (j - 1) * V_CLKDIV2;
+ }
+ }
+ }
+ return nearestClock;
+}
+
+/*
+ * xf86ModeStatusToString
+ *
+ * Convert a ModeStatus value to a printable message
+ */
+
+const char *
+xf86ModeStatusToString(ModeStatus status)
+{
+ switch (status) {
+ case MODE_OK:
+ return "Mode OK";
+ case MODE_HSYNC:
+ return "hsync out of range";
+ case MODE_VSYNC:
+ return "vrefresh out of range";
+ case MODE_H_ILLEGAL:
+ return "illegal horizontal timings";
+ case MODE_V_ILLEGAL:
+ return "illegal vertical timings";
+ case MODE_BAD_WIDTH:
+ return "width requires unsupported line pitch";
+ case MODE_NOMODE:
+ return "no mode of this name";
+ case MODE_NO_INTERLACE:
+ return "interlace mode not supported";
+ case MODE_NO_DBLESCAN:
+ return "doublescan mode not supported";
+ case MODE_NO_VSCAN:
+ return "multiscan mode not supported";
+ case MODE_MEM:
+ return "insufficient memory for mode";
+ case MODE_VIRTUAL_X:
+ return "width too large for virtual size";
+ case MODE_VIRTUAL_Y:
+ return "height too large for virtual size";
+ case MODE_MEM_VIRT:
+ return "insufficient memory given virtual size";
+ case MODE_NOCLOCK:
+ return "no clock available for mode";
+ case MODE_CLOCK_HIGH:
+ return "mode clock too high";
+ case MODE_CLOCK_LOW:
+ return "mode clock too low";
+ case MODE_CLOCK_RANGE:
+ return "bad mode clock/interlace/doublescan";
+ case MODE_BAD_HVALUE:
+ return "horizontal timing out of range";
+ case MODE_BAD_VVALUE:
+ return "vertical timing out of range";
+ case MODE_BAD_VSCAN:
+ return "VScan value out of range";
+ case MODE_HSYNC_NARROW:
+ return "horizontal sync too narrow";
+ case MODE_HSYNC_WIDE:
+ return "horizontal sync too wide";
+ case MODE_HBLANK_NARROW:
+ return "horizontal blanking too narrow";
+ case MODE_HBLANK_WIDE:
+ return "horizontal blanking too wide";
+ case MODE_VSYNC_NARROW:
+ return "vertical sync too narrow";
+ case MODE_VSYNC_WIDE:
+ return "vertical sync too wide";
+ case MODE_VBLANK_NARROW:
+ return "vertical blanking too narrow";
+ case MODE_VBLANK_WIDE:
+ return "vertical blanking too wide";
+ case MODE_PANEL:
+ return "exceeds panel dimensions";
+ case MODE_INTERLACE_WIDTH:
+ return "width too large for interlaced mode";
+ case MODE_ONE_WIDTH:
+ return "all modes must have the same width";
+ case MODE_ONE_HEIGHT:
+ return "all modes must have the same height";
+ case MODE_ONE_SIZE:
+ return "all modes must have the same resolution";
+ case MODE_NO_REDUCED:
+ return "monitor doesn't support reduced blanking";
+ case MODE_BANDWIDTH:
+ return "mode requires too much memory bandwidth";
+ case MODE_BAD:
+ return "unknown reason";
+ case MODE_ERROR:
+ return "internal error";
+ default:
+ return "unknown";
+ }
+}
+
+/*
+ * xf86ShowClockRanges() -- Print the clock ranges allowed
+ * and the clock values scaled by ClockMulFactor and ClockDivFactor
+ */
+void
+xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges)
+{
+ ClockRangePtr cp;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int i, j;
+ int scaledClock;
+
+ for (cp = clockRanges; cp != NULL; cp = cp->next) {
+ DivFactor = max(1, cp->ClockDivFactor);
+ MulFactor = max(1, cp->ClockMulFactor);
+ if (scrp->progClock) {
+ if (cp->minClock) {
+ if (cp->maxClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Clock range: %6.2f to %6.2f MHz\n",
+ (double)cp->minClock / 1000.0,
+ (double)cp->maxClock / 1000.0);
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Minimum clock: %6.2f MHz\n",
+ (double)cp->minClock / 1000.0);
+ }
+ } else {
+ if (cp->maxClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Maximum clock: %6.2f MHz\n",
+ (double)cp->maxClock / 1000.0);
+ }
+ }
+ } else if (DivFactor > 1 || MulFactor > 1) {
+ j = 0;
+ for (i = 0; i < scrp->numClocks; i++) {
+ scaledClock = (scrp->clock[i] * DivFactor) / MulFactor;
+ if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) {
+ if ((j % 8) == 0) {
+ if (j > 0)
+ xf86ErrorF("\n");
+ xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:");
+ }
+ xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0);
+ j++;
+ }
+ }
+ xf86ErrorF("\n");
+ }
+ }
+}
+
+static Bool
+modeInClockRange(ClockRangePtr cp, DisplayModePtr p)
+{
+ return ((p->Clock >= cp->minClock) &&
+ (p->Clock <= cp->maxClock) &&
+ (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) &&
+ (cp->doubleScanAllowed ||
+ ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN))));
+}
+
+/*
+ * xf86FindClockRangeForMode() [... like the name says ...]
+ */
+static ClockRangePtr
+xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p)
+{
+ ClockRangePtr cp;
+
+ for (cp = clockRanges; ; cp = cp->next)
+ if (!cp || modeInClockRange(cp, p))
+ return cp;
+}
+
+
+/*
+ * xf86HandleBuiltinMode() - handles built-in modes
+ */
+static ModeStatus
+xf86HandleBuiltinMode(ScrnInfoPtr scrp,
+ DisplayModePtr p,
+ DisplayModePtr modep,
+ ClockRangePtr clockRanges,
+ Bool allowDiv2)
+{
+ ClockRangePtr cp;
+ int extraFlags = 0;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int clockIndex;
+
+ /* Reject previously rejected modes */
+ if (p->status != MODE_OK)
+ return p->status;
+
+ /* Reject previously considered modes */
+ if (p->prev)
+ return MODE_NOMODE;
+
+ if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) {
+ /* Check clock is in range */
+ cp = xf86FindClockRangeForMode(clockRanges, p);
+ if (cp == NULL){
+ modep->type = p->type;
+ p->status = MODE_CLOCK_RANGE;
+ return MODE_CLOCK_RANGE;
+ }
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ if (!scrp->progClock) {
+ clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
+ cp->ClockDivFactor,
+ cp->ClockMulFactor, &extraFlags);
+ modep->Clock = (scrp->clock[clockIndex] * DivFactor)
+ / MulFactor;
+ modep->ClockIndex = clockIndex;
+ modep->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ modep->Clock /= 2;
+ modep->SynthClock /= 2;
+ }
+ } else {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = (modep->Clock * MulFactor)
+ / DivFactor;
+ }
+ modep->PrivFlags = cp->PrivFlags;
+ } else {
+ if(!scrp->progClock) {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = p->ClockIndex;
+ modep->SynthClock = p->SynthClock;
+ } else {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = p->SynthClock;
+ }
+ modep->PrivFlags = p->PrivFlags;
+ }
+ modep->type = p->type;
+ modep->HDisplay = p->HDisplay;
+ modep->HSyncStart = p->HSyncStart;
+ modep->HSyncEnd = p->HSyncEnd;
+ modep->HTotal = p->HTotal;
+ modep->HSkew = p->HSkew;
+ modep->VDisplay = p->VDisplay;
+ modep->VSyncStart = p->VSyncStart;
+ modep->VSyncEnd = p->VSyncEnd;
+ modep->VTotal = p->VTotal;
+ modep->VScan = p->VScan;
+ modep->Flags = p->Flags | extraFlags;
+ modep->CrtcHDisplay = p->CrtcHDisplay;
+ modep->CrtcHBlankStart = p->CrtcHBlankStart;
+ modep->CrtcHSyncStart = p->CrtcHSyncStart;
+ modep->CrtcHSyncEnd = p->CrtcHSyncEnd;
+ modep->CrtcHBlankEnd = p->CrtcHBlankEnd;
+ modep->CrtcHTotal = p->CrtcHTotal;
+ modep->CrtcHSkew = p->CrtcHSkew;
+ modep->CrtcVDisplay = p->CrtcVDisplay;
+ modep->CrtcVBlankStart = p->CrtcVBlankStart;
+ modep->CrtcVSyncStart = p->CrtcVSyncStart;
+ modep->CrtcVSyncEnd = p->CrtcVSyncEnd;
+ modep->CrtcVBlankEnd = p->CrtcVBlankEnd;
+ modep->CrtcVTotal = p->CrtcVTotal;
+ modep->CrtcHAdjusted = p->CrtcHAdjusted;
+ modep->CrtcVAdjusted = p->CrtcVAdjusted;
+ modep->HSync = p->HSync;
+ modep->VRefresh = p->VRefresh;
+ modep->Private = p->Private;
+ modep->PrivSize = p->PrivSize;
+
+ p->prev = modep;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86LookupMode
+ *
+ * This function returns a mode from the given list which matches the
+ * given name. When multiple modes with the same name are available,
+ * the method of picking the matching mode is determined by the
+ * strategy selected.
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * modep pointer to the returned mode, which must have the name
+ * field filled in.
+ * clockRanges a list of clock ranges. This is optional when all the
+ * modes are built-in modes.
+ * strategy how to decide which mode to use from multiple modes with
+ * the same name
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * modePool the list of monitor modes compatible with the driver
+ * clocks a list of discrete clocks
+ * numClocks number of discrete clocks
+ * progClock clock is programmable
+ *
+ * If a mode was found, its values are filled in to the area pointed to
+ * by modep, If a mode was not found the return value indicates the
+ * reason.
+ */
+
+ModeStatus
+xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ ClockRangePtr clockRanges, LookupModeFlags strategy)
+{
+ DisplayModePtr p, bestMode = NULL;
+ ClockRangePtr cp;
+ int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
+ double refresh, bestRefresh = 0.0;
+ Bool found = FALSE;
+ int extraFlags = 0;
+ int clockIndex = -1;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int ModePrivFlags = 0;
+ ModeStatus status = MODE_NOMODE;
+ Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
+ int n;
+ const int types[] = {
+ M_T_BUILTIN | M_T_PREFERRED,
+ M_T_BUILTIN,
+ M_T_USERDEF | M_T_PREFERRED,
+ M_T_USERDEF,
+ M_T_DRIVER | M_T_PREFERRED,
+ M_T_DRIVER,
+ 0
+ };
+ const int ntypes = sizeof(types) / sizeof(int);
+
+ strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES);
+
+ /* Some sanity checking */
+ if (scrp == NULL || scrp->modePool == NULL ||
+ (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n");
+ return MODE_ERROR;
+ }
+ if (modep == NULL || modep->name == NULL) {
+ ErrorF("xf86LookupMode: called with invalid modep\n");
+ return MODE_ERROR;
+ }
+ for (cp = clockRanges; cp != NULL; cp = cp->next) {
+ /* DivFactor and MulFactor must be > 0 */
+ cp->ClockDivFactor = max(1, cp->ClockDivFactor);
+ cp->ClockMulFactor = max(1, cp->ClockMulFactor);
+ }
+
+ /* Scan the mode pool for matching names */
+ for (n = 0; n < ntypes; n++) {
+ int type = types[n];
+ for (p = scrp->modePool; p != NULL; p = p->next) {
+
+ /* scan through the modes in the sort order above */
+ if ((p->type & type) != type)
+ continue;
+
+ if (strcmp(p->name, modep->name) == 0) {
+
+ /* Skip over previously rejected modes */
+ if (p->status != MODE_OK) {
+ if (!found)
+ status = p->status;
+ continue;
+ }
+
+ /* Skip over previously considered modes */
+ if (p->prev)
+ continue;
+
+ if (p->type & M_T_BUILTIN) {
+ return xf86HandleBuiltinMode(scrp, p,modep, clockRanges,
+ allowDiv2);
+ }
+
+ /* Check clock is in range */
+ cp = xf86FindClockRangeForMode(clockRanges, p);
+ if (cp == NULL) {
+ /*
+ * XXX Could do more here to provide a more detailed
+ * reason for not finding a mode.
+ */
+ p->status = MODE_CLOCK_RANGE;
+ if (!found)
+ status = MODE_CLOCK_RANGE;
+ continue;
+ }
+
+ /*
+ * If programmable clock and strategy is not
+ * LOOKUP_BEST_REFRESH, the required mode has been found,
+ * otherwise record the refresh and continue looking.
+ */
+ if (scrp->progClock) {
+ found = TRUE;
+ if (strategy != LOOKUP_BEST_REFRESH) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ break;
+ }
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE)
+ refresh /= INTERLACE_REFRESH_WEIGHT;
+ if (refresh > bestRefresh) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ bestRefresh = refresh;
+ }
+ continue;
+ }
+
+ /*
+ * Clock is in range, so if it is not a programmable clock, find
+ * a matching clock.
+ */
+
+ i = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
+ cp->ClockDivFactor, cp->ClockMulFactor, &k);
+ /*
+ * If the clock is too far from the requested clock, this
+ * mode is no good.
+ */
+ if (k & V_CLKDIV2)
+ gap = abs((p->Clock * 2) -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ else
+ gap = abs(p->Clock -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ if (gap > minimumGap) {
+ p->status = MODE_NOCLOCK;
+ if (!found)
+ status = MODE_NOCLOCK;
+ continue;
+ }
+ found = TRUE;
+
+ if (strategy == LOOKUP_BEST_REFRESH) {
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE)
+ refresh /= INTERLACE_REFRESH_WEIGHT;
+ if (refresh > bestRefresh) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ bestRefresh = refresh;
+ }
+ continue;
+ }
+ if (strategy == LOOKUP_CLOSEST_CLOCK) {
+ if (gap < minimumGap) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ minimumGap = gap;
+ }
+ continue;
+ }
+ /*
+ * If strategy is neither LOOKUP_BEST_REFRESH or
+ * LOOKUP_CLOSEST_CLOCK the required mode has been found.
+ */
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ break;
+ }
+ }
+ if (found) break;
+ }
+ if (!found || bestMode == NULL)
+ return status;
+
+ /* Fill in the mode parameters */
+ if (scrp->progClock) {
+ modep->Clock = bestMode->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = (modep->Clock * MulFactor) / DivFactor;
+ } else {
+ modep->Clock = (scrp->clock[clockIndex] * DivFactor) /
+ MulFactor;
+ modep->ClockIndex = clockIndex;
+ modep->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ modep->Clock /= 2;
+ modep->SynthClock /= 2;
+ }
+ }
+ modep->type = bestMode->type;
+ modep->PrivFlags = ModePrivFlags;
+ modep->HDisplay = bestMode->HDisplay;
+ modep->HSyncStart = bestMode->HSyncStart;
+ modep->HSyncEnd = bestMode->HSyncEnd;
+ modep->HTotal = bestMode->HTotal;
+ modep->HSkew = bestMode->HSkew;
+ modep->VDisplay = bestMode->VDisplay;
+ modep->VSyncStart = bestMode->VSyncStart;
+ modep->VSyncEnd = bestMode->VSyncEnd;
+ modep->VTotal = bestMode->VTotal;
+ modep->VScan = bestMode->VScan;
+ modep->Flags = bestMode->Flags | extraFlags;
+ modep->CrtcHDisplay = bestMode->CrtcHDisplay;
+ modep->CrtcHBlankStart = bestMode->CrtcHBlankStart;
+ modep->CrtcHSyncStart = bestMode->CrtcHSyncStart;
+ modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd;
+ modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd;
+ modep->CrtcHTotal = bestMode->CrtcHTotal;
+ modep->CrtcHSkew = bestMode->CrtcHSkew;
+ modep->CrtcVDisplay = bestMode->CrtcVDisplay;
+ modep->CrtcVBlankStart = bestMode->CrtcVBlankStart;
+ modep->CrtcVSyncStart = bestMode->CrtcVSyncStart;
+ modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd;
+ modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd;
+ modep->CrtcVTotal = bestMode->CrtcVTotal;
+ modep->CrtcHAdjusted = bestMode->CrtcHAdjusted;
+ modep->CrtcVAdjusted = bestMode->CrtcVAdjusted;
+ modep->HSync = bestMode->HSync;
+ modep->VRefresh = bestMode->VRefresh;
+ modep->Private = bestMode->Private;
+ modep->PrivSize = bestMode->PrivSize;
+
+ bestMode->prev = modep;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeForMonitor
+ *
+ * This function takes a mode and monitor description, and determines
+ * if the mode is valid for the monitor.
+ */
+ModeStatus
+xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
+{
+ int i;
+
+ /* Sanity checks */
+ if (mode == NULL || monitor == NULL) {
+ ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n");
+ return MODE_ERROR;
+ }
+
+ DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
+ mode, mode->name, monitor, monitor->id);
+
+ /* Some basic mode validity checks */
+ if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
+ mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
+ return MODE_H_ILLEGAL;
+
+ if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
+ mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
+ return MODE_V_ILLEGAL;
+
+ if (monitor->nHsync > 0) {
+ /* Check hsync against the allowed ranges */
+ float hsync = xf86ModeHSync(mode);
+ for (i = 0; i < monitor->nHsync; i++)
+ if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) &&
+ (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE)))
+ break;
+
+ /* Now see whether we ran out of sync ranges without finding a match */
+ if (i == monitor->nHsync)
+ return MODE_HSYNC;
+ }
+
+ if (monitor->nVrefresh > 0) {
+ /* Check vrefresh against the allowed ranges */
+ float vrefrsh = xf86ModeVRefresh(mode);
+ for (i = 0; i < monitor->nVrefresh; i++)
+ if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) &&
+ (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE)))
+ break;
+
+ /* Now see whether we ran out of refresh ranges without finding a match */
+ if (i == monitor->nVrefresh)
+ return MODE_VSYNC;
+ }
+
+ /* Force interlaced modes to have an odd VTotal */
+ if (mode->Flags & V_INTERLACE)
+ mode->CrtcVTotal = mode->VTotal |= 1;
+
+ /*
+ * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+
+ * old CRTs which might, when there is a lot of solar flare activity and
+ * when the celestial bodies are unfavourably aligned, implode trying to
+ * sync to it. It's called "Protecting the user from doing anything stupid".
+ * -- libv
+ */
+
+ if (xf86ModeIsReduced(mode)) {
+ if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
+ return MODE_NO_REDUCED;
+ }
+
+ if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeSize
+ *
+ * An internal routine to check if a mode fits in video memory. This tries to
+ * avoid overflows that would otherwise occur when video memory size is greater
+ * than 256MB.
+ */
+static Bool
+xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y)
+{
+ int bpp = scrp->fbFormat.bitsPerPixel,
+ pad = scrp->fbFormat.scanlinePad;
+ int lineWidth, lastWidth;
+
+ if (scrp->depth == 4)
+ pad *= 4; /* 4 planes */
+
+ /* Sanity check */
+ if ((w < 0) || (x < 0) || (y <= 0))
+ return FALSE;
+
+ lineWidth = (((w * bpp) + pad - 1) / pad) * pad;
+ lastWidth = x * bpp;
+
+ /*
+ * At this point, we need to compare
+ *
+ * (lineWidth * (y - 1)) + lastWidth
+ *
+ * against
+ *
+ * scrp->videoRam * (1024 * 8)
+ *
+ * These are bit quantities. To avoid overflows, do the comparison in
+ * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD
+ * is a power of 2. We currently use 32, which limits us to a video
+ * memory size of 8GB.
+ */
+
+ lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
+ lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
+
+ if ((lineWidth * (y - 1) + lastWidth) >
+ (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * xf86InitialCheckModeForDriver
+ *
+ * This function checks if a mode satisfies a driver's initial requirements:
+ * - mode size fits within the available pixel area (memory)
+ * - width lies within the range of supported line pitches
+ * - mode size fits within virtual size (if fixed)
+ * - horizontal timings are in range
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * mode mode to check
+ * maxPitch (optional) maximum line pitch
+ * virtualX (optional) virtual width requested
+ * virtualY (optional) virtual height requested
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * monitor pointer to structure for monitor section
+ * fbFormat pixel format for the framebuffer
+ * videoRam video memory size (in kB)
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ */
+
+ModeStatus
+xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ ClockRangePtr clockRanges,
+ LookupModeFlags strategy,
+ int maxPitch, int virtualX, int virtualY)
+{
+ ClockRangePtr cp;
+ ModeStatus status;
+ Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
+ int i, needDiv2;
+
+ /* Sanity checks */
+ if (!scrp || !mode || !clockRanges) {
+ ErrorF("xf86InitialCheckModeForDriver: "
+ "called with invalid parameters\n");
+ return MODE_ERROR;
+ }
+
+ DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
+ scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY);
+
+ /* Some basic mode validity checks */
+ if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
+ mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
+ return MODE_H_ILLEGAL;
+
+ if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
+ mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
+ return MODE_V_ILLEGAL;
+
+ if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay,
+ mode->VDisplay))
+ return MODE_MEM;
+
+ if (maxPitch > 0 && mode->HDisplay > maxPitch)
+ return MODE_BAD_WIDTH;
+
+ if (virtualX > 0 && mode->HDisplay > virtualX)
+ return MODE_VIRTUAL_X;
+
+ if (virtualY > 0 && mode->VDisplay > virtualY)
+ return MODE_VIRTUAL_Y;
+
+ if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
+ return MODE_BAD_HVALUE;
+
+ if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
+ return MODE_BAD_VVALUE;
+
+ /*
+ * The use of the DisplayModeRec's Crtc* and SynthClock elements below is
+ * provisional, in that they are later reused by the driver at mode-set
+ * time. Here, they are temporarily enlisted to contain the mode timings
+ * as seen by the CRT or panel (rather than the CRTC). The driver's
+ * ValidMode() is allowed to modify these so it can deal with such things
+ * as mode stretching and/or centering. The driver should >NOT< modify the
+ * user-supplied values as these are reported back when mode validation is
+ * said and done.
+ */
+ /*
+ * NOTE: We (ab)use the mode->Crtc* values here to store timing
+ * information for the calculation of Hsync and Vrefresh. Before
+ * these values are calculated the driver is given the opportunity
+ * to either set these HSync and VRefresh itself or modify the timing
+ * values.
+ * The difference to the final calculation is small but imortand:
+ * here we pass the flag INTERLACE_HALVE_V regardless if the driver
+ * sets it or not. This way our calculation of VRefresh has the same
+ * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0
+ * This dual use of the mode->Crtc* values will certainly create
+ * confusion and is bad software design. However since it's part of
+ * the driver API it's hard to change.
+ */
+
+ if (scrp->ValidMode) {
+
+ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+ cp = xf86FindClockRangeForMode(clockRanges, mode);
+ if (!cp)
+ return MODE_CLOCK_RANGE;
+
+ if (cp->ClockMulFactor < 1)
+ cp->ClockMulFactor = 1;
+ if (cp->ClockDivFactor < 1)
+ cp->ClockDivFactor = 1;
+
+ /*
+ * XXX The effect of clock dividers and multipliers on the monitor's
+ * pixel clock needs to be verified.
+ */
+ if (scrp->progClock) {
+ mode->SynthClock = mode->Clock;
+ } else {
+ i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2,
+ cp->ClockDivFactor, cp->ClockMulFactor,
+ &needDiv2);
+ mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor;
+ if (needDiv2 & V_CLKDIV2)
+ mode->SynthClock /= 2;
+ }
+
+ status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE,
+ MODECHECK_INITIAL);
+ if (status != MODE_OK)
+ return status;
+
+ if (mode->HSync <= 0.0)
+ mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal;
+ if (mode->VRefresh <= 0.0)
+ mode->VRefresh = (mode->SynthClock * 1000.0)
+ / (mode->CrtcHTotal * mode->CrtcVTotal);
+ }
+
+ mode->HSync = xf86ModeHSync(mode);
+ mode->VRefresh = xf86ModeVRefresh(mode);
+
+ /* Assume it is OK */
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeForDriver
+ *
+ * This function is for checking modes while the server is running (for
+ * use mainly by the VidMode extension).
+ *
+ * This function checks if a mode satisfies a driver's requirements:
+ * - width lies within the line pitch
+ * - mode size fits within virtual size
+ * - horizontal/vertical timings are in range
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * mode mode to check
+ * flags not (currently) used
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ * virtualX virtual width
+ * virtualY virtual height
+ * clockRanges allowable clock ranges
+ */
+
+ModeStatus
+xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags)
+{
+ ClockRangePtr cp;
+ int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
+ int extraFlags = 0;
+ int clockIndex = -1;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int ModePrivFlags = 0;
+ ModeStatus status = MODE_NOMODE;
+
+ /* Some sanity checking */
+ if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n");
+ return MODE_ERROR;
+ }
+ if (mode == NULL) {
+ ErrorF("xf86CheckModeForDriver: called with invalid modep\n");
+ return MODE_ERROR;
+ }
+
+ /* Check the mode size */
+ if (mode->HDisplay > scrp->virtualX)
+ return MODE_VIRTUAL_X;
+
+ if (mode->VDisplay > scrp->virtualY)
+ return MODE_VIRTUAL_Y;
+
+ if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
+ return MODE_BAD_HVALUE;
+
+ if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
+ return MODE_BAD_VVALUE;
+
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ /* DivFactor and MulFactor must be > 0 */
+ cp->ClockDivFactor = max(1, cp->ClockDivFactor);
+ cp->ClockMulFactor = max(1, cp->ClockMulFactor);
+ }
+
+ if (scrp->progClock) {
+ /* Check clock is in range */
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ if (modeInClockRange(cp, mode))
+ break;
+ }
+ if (cp == NULL) {
+ return MODE_CLOCK_RANGE;
+ }
+ /*
+ * If programmable clock the required mode has been found
+ */
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ } else {
+ status = MODE_CLOCK_RANGE;
+ /* Check clock is in range */
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ if (modeInClockRange(cp, mode)) {
+ /*
+ * Clock is in range, so if it is not a programmable clock,
+ * find a matching clock.
+ */
+
+ i = xf86GetNearestClock(scrp, mode->Clock, 0,
+ cp->ClockDivFactor, cp->ClockMulFactor, &k);
+ /*
+ * If the clock is too far from the requested clock, this
+ * mode is no good.
+ */
+ if (k & V_CLKDIV2)
+ gap = abs((mode->Clock * 2) -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ else
+ gap = abs(mode->Clock -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ if (gap > minimumGap) {
+ status = MODE_NOCLOCK;
+ continue;
+ }
+
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ break;
+ }
+ }
+ if (cp == NULL)
+ return status;
+ }
+
+ /* Fill in the mode parameters */
+ if (scrp->progClock) {
+ mode->ClockIndex = -1;
+ mode->SynthClock = (mode->Clock * MulFactor) / DivFactor;
+ } else {
+ mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor;
+ mode->ClockIndex = clockIndex;
+ mode->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ mode->Clock /= 2;
+ mode->SynthClock /= 2;
+ }
+ }
+ mode->PrivFlags = ModePrivFlags;
+
+ return MODE_OK;
+}
+
+static int
+inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy)
+{
+ float aspect = 0.0;
+ MonPtr mon = scrp->monitor;
+ xf86MonPtr DDC;
+ int x = 0, y = 0;
+ DisplayModePtr mode;
+
+ if (!mon) return 0;
+ DDC = mon->DDC;
+
+ if (DDC && DDC->ver.revision >= 4) {
+ /* For 1.4, we might actually get native pixel format. How novel. */
+ if (PREFERRED_TIMING_MODE(DDC->features.msc)) {
+ for (mode = modes; mode; mode = mode->next) {
+ if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
+ x = mode->HDisplay;
+ y = mode->VDisplay;
+ goto found;
+ }
+ }
+ }
+ /*
+ * Even if we don't, we might get aspect ratio from extra CVT info
+ * or from the monitor size fields. TODO.
+ */
+ }
+
+ /*
+ * Technically this triggers if either is zero. That wasn't legal
+ * before EDID 1.4, but right now we'll get that wrong. TODO.
+ */
+ if (!aspect) {
+ if (!mon->widthmm || !mon->heightmm)
+ aspect = 4.0/3.0;
+ else
+ aspect = (float)mon->widthmm / (float)mon->heightmm;
+ }
+
+ /* find the largest M_T_DRIVER mode with that aspect ratio */
+ for (mode = modes; mode; mode = mode->next) {
+ float mode_aspect, metaspect;
+ if (!(mode->type & (M_T_DRIVER|M_T_USERDEF)))
+ continue;
+ mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay;
+ metaspect = aspect / mode_aspect;
+ /* 5% slop or so, since we only get size in centimeters */
+ if (fabs(1.0 - metaspect) < 0.05) {
+ if ((mode->HDisplay > x) && (mode->VDisplay > y)) {
+ x = mode->HDisplay;
+ y = mode->VDisplay;
+ }
+ }
+ }
+
+ if (!x || !y) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING,
+ "Unable to estimate virtual size\n");
+ return 0;
+ }
+
+found:
+ *vx = x;
+ *vy = y;
+
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Estimated virtual size for aspect ratio %.4f is %dx%d\n",
+ aspect, *vx, *vy);
+
+ return 1;
+}
+
+/* Least common multiple */
+static unsigned int
+LCM(unsigned int x, unsigned int y)
+{
+ unsigned int m = x, n = y, o;
+
+ while ((o = m % n))
+ {
+ m = n;
+ n = o;
+ }
+
+ return (x / n) * y;
+}
+
+/*
+ * Given various screen attributes, determine the minimum scanline width such
+ * that each scanline is server and DDX padded and any pixels with imbedded
+ * bank boundaries are off-screen. This function returns -1 if such a width
+ * cannot exist.
+ */
+static int
+scanLineWidth(
+ unsigned int xsize, /* pixels */
+ unsigned int ysize, /* pixels */
+ unsigned int width, /* pixels */
+ unsigned long BankSize, /* char's */
+ PixmapFormatRec *pBankFormat,
+ unsigned int nWidthUnit /* bits */
+)
+{
+ unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
+ unsigned long minBitsPerScanline, maxBitsPerScanline;
+
+ /* Sanity checks */
+
+ if (!nWidthUnit || !pBankFormat)
+ return -1;
+
+ nBitsPerBank = BankSize * 8;
+ if (nBitsPerBank % pBankFormat->scanlinePad)
+ return -1;
+
+ if (xsize > width)
+ width = xsize;
+ nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
+ nBitsPerScanline =
+ (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
+ nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+
+ if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
+ return (int)width;
+
+ /*
+ * Scanlines will be server-pad aligned at this point. They will also be
+ * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
+ * bank boundaries are off-screen.
+ *
+ * It seems reasonable to limit total frame buffer size to 1/16 of the
+ * theoretical maximum address space size. On a machine with 32-bit
+ * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
+ * does this provide a simple limiting condition for the loops below, but
+ * it also prevents unsigned long wraparounds.
+ */
+ if (!ysize)
+ return -1;
+
+ minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
+ if (minBitsPerScanline > nBitsPerBank)
+ return -1;
+
+ if (ysize == 1)
+ return (int)width;
+
+ maxBitsPerScanline =
+ (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
+ while (nBitsPerScanline <= maxBitsPerScanline)
+ {
+ unsigned long BankBase, BankUnit;
+
+ BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
+ nBitsPerBank;
+ if (!(BankUnit % nBitsPerScanline))
+ return (int)width;
+
+ for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
+ {
+ unsigned long x, y;
+
+ y = BankBase / nBitsPerScanline;
+ if (y >= ysize)
+ return (int)width;
+
+ x = BankBase % nBitsPerScanline;
+ if (!(x % pBankFormat->bitsPerPixel))
+ continue;
+
+ if (x < minBitsPerScanline)
+ {
+ /*
+ * Skip ahead certain widths by dividing the excess scanline
+ * amongst the y's.
+ */
+ y *= nBitsPerScanlinePadUnit;
+ nBitsPerScanline +=
+ ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+ break;
+ }
+
+ if (BankBase != BankUnit)
+ continue;
+
+ if (!(nBitsPerScanline % x))
+ return (int)width;
+
+ BankBase = ((nBitsPerScanline - minBitsPerScanline) /
+ (nBitsPerScanline - x)) * BankUnit;
+ }
+ }
+
+ return -1;
+}
+
+/*
+ * xf86ValidateModes
+ *
+ * This function takes a set of mode names, modes and limiting conditions,
+ * and selects a set of modes and parameters based on those conditions.
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * availModes the list of modes available for the monitor
+ * modeNames (optional) list of mode names that the screen is requesting
+ * clockRanges a list of clock ranges
+ * linePitches (optional) a list of line pitches
+ * minPitch (optional) minimum line pitch (in pixels)
+ * maxPitch (optional) maximum line pitch (in pixels)
+ * pitchInc (mandatory) pitch increment (in bits)
+ * minHeight (optional) minimum virtual height (in pixels)
+ * maxHeight (optional) maximum virtual height (in pixels)
+ * virtualX (optional) virtual width requested (in pixels)
+ * virtualY (optional) virtual height requested (in pixels)
+ * apertureSize size of video aperture (in bytes)
+ * strategy how to decide which mode to use from multiple modes with
+ * the same name
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * clocks a list of discrete clocks
+ * numClocks number of discrete clocks
+ * progClock clock is programmable
+ * monitor pointer to structure for monitor section
+ * fbFormat format of the framebuffer
+ * videoRam video memory size
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ * xInc horizontal timing increment (defaults to 8 pixels)
+ *
+ * The function fills in the following ScrnInfoRec fields:
+ * modePool A subset of the modes available to the monitor which
+ * are compatible with the driver.
+ * modes one mode entry for each of the requested modes, with the
+ * status field filled in to indicate if the mode has been
+ * accepted or not.
+ * virtualX the resulting virtual width
+ * virtualY the resulting virtual height
+ * displayWidth the resulting line pitch
+ *
+ * The function's return value is the number of matching modes found, or -1
+ * if an unrecoverable error was encountered.
+ */
+
+int
+xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch, int pitchInc,
+ int minHeight, int maxHeight, int virtualX, int virtualY,
+ int apertureSize, LookupModeFlags strategy)
+{
+ DisplayModePtr p, q, r, new, last, *endp;
+ int i, numModes = 0;
+ ModeStatus status;
+ int linePitch = -1, virtX = 0, virtY = 0;
+ int newLinePitch, newVirtX, newVirtY;
+ int modeSize; /* in pixels */
+ Bool validateAllDefaultModes = FALSE;
+ Bool userModes = FALSE;
+ int saveType;
+ PixmapFormatRec *BankFormat;
+ ClockRangePtr cp;
+ ClockRangePtr storeClockRanges;
+ int numTimings = 0;
+ range hsync[MAX_HSYNC];
+ range vrefresh[MAX_VREFRESH];
+ Bool inferred_virtual = FALSE;
+
+ DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
+ scrp, availModes, modeNames, clockRanges,
+ linePitches, minPitch, maxPitch, pitchInc,
+ minHeight, maxHeight, virtualX, virtualY,
+ apertureSize, strategy
+ );
+
+ /* Some sanity checking */
+ if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
+ (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n");
+ return -1;
+ }
+ if (linePitches != NULL && linePitches[0] <= 0) {
+ ErrorF("xf86ValidateModes: called with invalid linePitches\n");
+ return -1;
+ }
+ if (pitchInc <= 0) {
+ ErrorF("xf86ValidateModes: called with invalid pitchInc\n");
+ return -1;
+ }
+ if ((virtualX > 0) != (virtualY > 0)) {
+ ErrorF("xf86ValidateModes: called with invalid virtual resolution\n");
+ return -1;
+ }
+
+ /*
+ * If requested by the driver, allow missing hsync and/or vrefresh ranges
+ * in the monitor section.
+ */
+ if (strategy & LOOKUP_OPTIONAL_TOLERANCES) {
+ strategy &= ~LOOKUP_OPTIONAL_TOLERANCES;
+ } else {
+ const char *type = "";
+
+ if (scrp->monitor->nHsync <= 0) {
+ if (numTimings > 0) {
+ scrp->monitor->nHsync = numTimings;
+ for (i = 0; i < numTimings; i++) {
+ scrp->monitor->hsync[i].lo = hsync[i].lo;
+ scrp->monitor->hsync[i].hi = hsync[i].hi;
+ }
+ } else {
+ scrp->monitor->hsync[0].lo = 31.5;
+ scrp->monitor->hsync[0].hi = 37.9;
+ scrp->monitor->nHsync = 1;
+ }
+ type = "default ";
+ }
+ for (i = 0; i < scrp->monitor->nHsync; i++) {
+ if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi)
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %shsync value of %.2f kHz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->hsync[i].lo);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %shsync range of %.2f-%.2f kHz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->hsync[i].lo,
+ scrp->monitor->hsync[i].hi);
+ }
+
+ type = "";
+ if (scrp->monitor->nVrefresh <= 0) {
+ if (numTimings > 0) {
+ scrp->monitor->nVrefresh = numTimings;
+ for (i = 0; i < numTimings; i++) {
+ scrp->monitor->vrefresh[i].lo = vrefresh[i].lo;
+ scrp->monitor->vrefresh[i].hi = vrefresh[i].hi;
+ }
+ } else {
+ scrp->monitor->vrefresh[0].lo = 50;
+ scrp->monitor->vrefresh[0].hi = 70;
+ scrp->monitor->nVrefresh = 1;
+ }
+ type = "default ";
+ }
+ for (i = 0; i < scrp->monitor->nVrefresh; i++) {
+ if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi)
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %svrefresh value of %.2f Hz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->vrefresh[i].lo);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %svrefresh range of %.2f-%.2f Hz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->vrefresh[i].lo,
+ scrp->monitor->vrefresh[i].hi);
+ }
+ if (scrp->monitor->maxPixClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using maximum pixel clock of %.2f MHz\n",
+ scrp->monitor->id,
+ (float)scrp->monitor->maxPixClock / 1000.0);
+ }
+ }
+
+ /*
+ * Store the clockRanges for later use by the VidMode extension.
+ */
+ storeClockRanges = scrp->clockRanges;
+ while (storeClockRanges != NULL) {
+ storeClockRanges = storeClockRanges->next;
+ }
+ for (cp = clockRanges; cp != NULL; cp = cp->next,
+ storeClockRanges = storeClockRanges->next) {
+ storeClockRanges = xnfalloc(sizeof(ClockRange));
+ if (scrp->clockRanges == NULL)
+ scrp->clockRanges = storeClockRanges;
+ memcpy(storeClockRanges, cp, sizeof(ClockRange));
+ }
+
+ /* Determine which pixmap format to pass to scanLineWidth() */
+ if (scrp->depth > 4)
+ BankFormat = &scrp->fbFormat;
+ else
+ BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */
+
+ if (scrp->xInc <= 0)
+ scrp->xInc = 8; /* Suitable for VGA and others */
+
+#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc)
+
+ /*
+ * Determine maxPitch if it wasn't given explicitly. Note linePitches
+ * always takes precedence if is non-NULL. In that case the minPitch and
+ * maxPitch values passed are ignored.
+ */
+ if (linePitches) {
+ minPitch = maxPitch = linePitches[0];
+ for (i = 1; linePitches[i] > 0; i++) {
+ if (linePitches[i] > maxPitch)
+ maxPitch = linePitches[i];
+ if (linePitches[i] < minPitch)
+ minPitch = linePitches[i];
+ }
+ }
+
+ /* Initial check of virtual size against other constraints */
+ scrp->virtualFrom = X_PROBED;
+ /*
+ * Initialise virtX and virtY if the values are fixed.
+ */
+ if (virtualY > 0) {
+ if (maxHeight > 0 && virtualY > maxHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too large for the hardware "
+ "(max %d)\n", virtualY, maxHeight);
+ return -1;
+ }
+
+ if (minHeight > 0 && virtualY < minHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too small for the hardware "
+ "(min %d)\n", virtualY, minHeight);
+ return -1;
+ }
+
+ virtualX = _VIRTUALX(virtualX);
+ if (linePitches != NULL) {
+ for (i = 0; linePitches[i] != 0; i++) {
+ if ((linePitches[i] >= virtualX) &&
+ (linePitches[i] ==
+ scanLineWidth(virtualX, virtualY, linePitches[i],
+ apertureSize, BankFormat, pitchInc))) {
+ linePitch = linePitches[i];
+ break;
+ }
+ }
+ } else {
+ linePitch = scanLineWidth(virtualX, virtualY, minPitch,
+ apertureSize, BankFormat, pitchInc);
+ }
+
+ if ((linePitch < minPitch) || (linePitch > maxPitch)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual width (%d) is too large for the hardware "
+ "(max %d)\n", virtualX, maxPitch);
+ return -1;
+ }
+
+ if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual size (%dx%d) (pitch %d) exceeds video memory\n",
+ virtualX, virtualY, linePitch);
+ return -1;
+ }
+
+ virtX = virtualX;
+ virtY = virtualY;
+ scrp->virtualFrom = X_CONFIG;
+ } else if (!modeNames || !*modeNames) {
+ /* No virtual size given in the config, try to infer */
+ /* XXX this doesn't take m{in,ax}Pitch into account; oh well */
+ inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
+ if (inferred_virtual)
+ linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
+ BankFormat, pitchInc);
+ }
+
+ /* Print clock ranges and scaled clocks */
+ xf86ShowClockRanges(scrp, clockRanges);
+
+ /*
+ * If scrp->modePool hasn't been setup yet, set it up now. This allows the
+ * modes that the driver definitely can't use to be weeded out early. Note
+ * that a modePool mode's prev field is used to hold a pointer to the
+ * member of the scrp->modes list for which a match was considered.
+ */
+ if (scrp->modePool == NULL) {
+ q = NULL;
+ for (p = availModes; p != NULL; p = p->next) {
+ status = xf86InitialCheckModeForDriver(scrp, p, clockRanges,
+ strategy, maxPitch,
+ virtX, virtY);
+
+ if (status == MODE_OK) {
+ status = xf86CheckModeForMonitor(p, scrp->monitor);
+ }
+
+ if (status == MODE_OK) {
+ new = xnfalloc(sizeof(DisplayModeRec));
+ *new = *p;
+ new->next = NULL;
+ if (!q) {
+ scrp->modePool = new;
+ } else {
+ q->next = new;
+ }
+ new->prev = NULL;
+ q = new;
+ q->name = xnfstrdup(p->name);
+ q->status = MODE_OK;
+ } else {
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ }
+ }
+
+ if (scrp->modePool == NULL) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n");
+ return 0;
+ }
+ } else {
+ for (p = scrp->modePool; p != NULL; p = p->next) {
+ p->prev = NULL;
+ p->status = MODE_OK;
+ }
+ }
+
+ /*
+ * Allocate one entry in scrp->modes for each named mode.
+ */
+ while (scrp->modes)
+ xf86DeleteMode(&scrp->modes, scrp->modes);
+ endp = &scrp->modes;
+ last = NULL;
+ if (modeNames != NULL) {
+ for (i = 0; modeNames[i] != NULL; i++) {
+ userModes = TRUE;
+ new = xnfcalloc(1, sizeof(DisplayModeRec));
+ new->prev = last;
+ new->type = M_T_USERDEF;
+ new->name = xnfalloc(strlen(modeNames[i]) + 1);
+ strcpy(new->name, modeNames[i]);
+ if (new->prev)
+ new->prev->next = new;
+ *endp = last = new;
+ endp = &new->next;
+ }
+ }
+
+ /* Lookup each mode */
+#ifdef RANDR
+ if (!xf86Info.disableRandR
+#ifdef PANORAMIX
+ && noPanoramiXExtension
+#endif
+ )
+ validateAllDefaultModes = TRUE;
+#endif
+
+ for (p = scrp->modes; ; p = p->next) {
+ Bool repeat;
+
+ /*
+ * If the supplied mode names don't produce a valid mode, scan through
+ * unconsidered modePool members until one survives validation. This
+ * is done in decreasing order by mode pixel area.
+ */
+
+ if (p == NULL) {
+ if ((numModes > 0) && !validateAllDefaultModes)
+ break;
+
+ validateAllDefaultModes = TRUE;
+ r = NULL;
+ modeSize = 0;
+ for (q = scrp->modePool; q != NULL; q = q->next) {
+ if ((q->prev == NULL) && (q->status == MODE_OK)) {
+ /*
+ * Deal with the case where this mode wasn't considered
+ * because of a builtin mode of the same name.
+ */
+ for (p = scrp->modes; p != NULL; p = p->next) {
+ if ((p->status != MODE_OK) &&
+ !strcmp(p->name, q->name))
+ break;
+ }
+
+ if (p != NULL)
+ q->prev = p;
+ else {
+ /*
+ * A quick check to not allow default modes with
+ * horizontal timing parameters that CRTs may have
+ * problems with.
+ */
+ if (!scrp->monitor->reducedblanking &&
+ (q->type & M_T_DEFAULT) &&
+ ((double)q->HTotal / (double)q->HDisplay) < 1.15)
+ continue;
+
+ if (modeSize < (q->HDisplay * q->VDisplay)) {
+ r = q;
+ modeSize = q->HDisplay * q->VDisplay;
+ }
+ }
+ }
+ }
+
+ if (r == NULL)
+ break;
+
+ p = xnfcalloc(1, sizeof(DisplayModeRec));
+ p->prev = last;
+ p->name = xnfalloc(strlen(r->name) + 1);
+ if (!userModes)
+ p->type = M_T_USERDEF;
+ strcpy(p->name, r->name);
+ if (p->prev)
+ p->prev->next = p;
+ *endp = last = p;
+ endp = &p->next;
+ }
+
+ repeat = FALSE;
+ lookupNext:
+ if (repeat && ((status = p->status) != MODE_OK))
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ saveType = p->type;
+ status = xf86LookupMode(scrp, p, clockRanges, strategy);
+ if (repeat && status == MODE_NOMODE)
+ continue;
+ if (status != MODE_OK)
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ if (status == MODE_ERROR) {
+ ErrorF("xf86ValidateModes: "
+ "unexpected result from xf86LookupMode()\n");
+ return -1;
+ }
+ if (status != MODE_OK) {
+ if (p->status == MODE_OK)
+ p->status = status;
+ continue;
+ }
+ p->type |= saveType;
+ repeat = TRUE;
+
+ newLinePitch = linePitch;
+ newVirtX = virtX;
+ newVirtY = virtY;
+
+ /*
+ * Don't let non-user defined modes increase the virtual size
+ */
+ if (!(p->type & M_T_USERDEF) && (numModes > 0)) {
+ if (p->HDisplay > virtX) {
+ p->status = MODE_VIRTUAL_X;
+ goto lookupNext;
+ }
+ if (p->VDisplay > virtY) {
+ p->status = MODE_VIRTUAL_Y;
+ goto lookupNext;
+ }
+ }
+ /*
+ * Adjust virtual width and height if the mode is too large for the
+ * current values and if they are not fixed.
+ */
+ if (virtualX <= 0 && p->HDisplay > newVirtX)
+ newVirtX = _VIRTUALX(p->HDisplay);
+ if (virtualY <= 0 && p->VDisplay > newVirtY) {
+ if (maxHeight > 0 && p->VDisplay > maxHeight) {
+ p->status = MODE_VIRTUAL_Y; /* ? */
+ goto lookupNext;
+ }
+ newVirtY = p->VDisplay;
+ }
+
+ /*
+ * If virtual resolution is to be increased, revalidate it.
+ */
+ if ((virtX != newVirtX) || (virtY != newVirtY)) {
+ if (linePitches != NULL) {
+ newLinePitch = -1;
+ for (i = 0; linePitches[i] != 0; i++) {
+ if ((linePitches[i] >= newVirtX) &&
+ (linePitches[i] >= linePitch) &&
+ (linePitches[i] ==
+ scanLineWidth(newVirtX, newVirtY, linePitches[i],
+ apertureSize, BankFormat, pitchInc))) {
+ newLinePitch = linePitches[i];
+ break;
+ }
+ }
+ } else {
+ if (linePitch < minPitch)
+ linePitch = minPitch;
+ newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
+ apertureSize, BankFormat,
+ pitchInc);
+ }
+ if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
+ p->status = MODE_BAD_WIDTH;
+ goto lookupNext;
+ }
+
+ /*
+ * Check that the pixel area required by the new virtual height
+ * and line pitch isn't too large.
+ */
+ if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) {
+ p->status = MODE_MEM_VIRT;
+ goto lookupNext;
+ }
+ }
+
+ if (scrp->ValidMode) {
+ /*
+ * Give the driver a final say, passing it the proposed virtual
+ * geometry.
+ */
+ scrp->virtualX = newVirtX;
+ scrp->virtualY = newVirtY;
+ scrp->displayWidth = newLinePitch;
+ p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE,
+ MODECHECK_FINAL);
+
+ if (p->status != MODE_OK) {
+ goto lookupNext;
+ }
+ }
+
+ /* Mode has passed all the tests */
+ virtX = newVirtX;
+ virtY = newVirtY;
+ linePitch = newLinePitch;
+ p->status = MODE_OK;
+ numModes++;
+ }
+
+#undef _VIRTUALX
+
+ /*
+ * If we estimated the virtual size above, we may have filtered away all
+ * the modes that maximally match that size; scan again to find out and
+ * fix up if so.
+ */
+ if (inferred_virtual) {
+ int vx = 0, vy = 0;
+ for (p = scrp->modes; p; p = p->next) {
+ if (p->HDisplay > vx && p->VDisplay > vy) {
+ vx = p->HDisplay;
+ vy = p->VDisplay;
+ }
+ }
+ if (vx < virtX || vy < virtY) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING,
+ "Shrinking virtual size estimate from %dx%d to %dx%d\n",
+ virtX, virtY, vx, vy);
+ virtX = vx;
+ virtY = vy;
+ linePitch = scanLineWidth(vx, vy, minPitch, apertureSize,
+ BankFormat, pitchInc);
+ }
+ }
+
+ /* Update the ScrnInfoRec parameters */
+
+ scrp->virtualX = virtX;
+ scrp->virtualY = virtY;
+ scrp->displayWidth = linePitch;
+
+ if (numModes <= 0)
+ return 0;
+
+ /* Make the mode list into a circular list by joining up the ends */
+ p = scrp->modes;
+ while (p->next != NULL)
+ p = p->next;
+ /* p is now the last mode on the list */
+ p->next = scrp->modes;
+ scrp->modes->prev = p;
+
+ if (minHeight > 0 && virtY < minHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too small for the hardware "
+ "(min %d)\n", virtY, minHeight);
+ return -1;
+ }
+
+ return numModes;
+}
+
+/*
+ * xf86DeleteMode
+ *
+ * This function removes a mode from a list of modes.
+ *
+ * There are different types of mode lists:
+ *
+ * - singly linked linear lists, ending in NULL
+ * - doubly linked linear lists, starting and ending in NULL
+ * - doubly linked circular lists
+ *
+ */
+
+void
+xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)
+{
+ /* Catch the easy/insane cases */
+ if (modeList == NULL || *modeList == NULL || mode == NULL)
+ return;
+
+ /* If the mode is at the start of the list, move the start of the list */
+ if (*modeList == mode)
+ *modeList = mode->next;
+
+ /* If mode is the only one on the list, set the list to NULL */
+ if ((mode == mode->prev) && (mode == mode->next)) {
+ *modeList = NULL;
+ } else {
+ if ((mode->prev != NULL) && (mode->prev->next == mode))
+ mode->prev->next = mode->next;
+ if ((mode->next != NULL) && (mode->next->prev == mode))
+ mode->next->prev = mode->prev;
+ }
+
+ free(mode->name);
+ free(mode);
+}
+
+/*
+ * xf86PruneDriverModes
+ *
+ * Remove modes from the driver's mode list which have been marked as
+ * invalid.
+ */
+
+void
+xf86PruneDriverModes(ScrnInfoPtr scrp)
+{
+ DisplayModePtr first, p, n;
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ if (!(first = scrp->modes))
+ return;
+ n = p->next;
+ if (p->status != MODE_OK) {
+ xf86DeleteMode(&(scrp->modes), p);
+ }
+ p = n;
+ } while (p != NULL && p != first);
+
+ /* modePool is no longer needed, turf it */
+ while (scrp->modePool) {
+ /*
+ * A modePool mode's prev field is used to hold a pointer to the
+ * member of the scrp->modes list for which a match was considered.
+ * Clear that pointer first, otherwise xf86DeleteMode might get
+ * confused
+ */
+ scrp->modePool->prev = NULL;
+ xf86DeleteMode(&scrp->modePool, scrp->modePool);
+ }
+}
+
+
+/*
+ * xf86SetCrtcForModes
+ *
+ * Goes through the screen's mode list, and initialises the Crtc
+ * parameters for each mode. The initialisation includes adjustments
+ * for interlaced and double scan modes.
+ */
+void
+xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
+{
+ DisplayModePtr p;
+
+ /*
+ * Store adjustFlags for use with the VidMode extension. There is an
+ * implicit assumption here that SetCrtcForModes is called once.
+ */
+ scrp->adjustFlags = adjustFlags;
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ xf86SetModeCrtc(p, adjustFlags);
+ DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
+ (p->type & M_T_DEFAULT) ? "Default " : "",
+ p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
+ p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
+ p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
+ p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
+ p->CrtcVTotal);
+ p = p->next;
+ } while (p != NULL && p != scrp->modes);
+}
+
+void
+xf86PrintModes(ScrnInfoPtr scrp)
+{
+ DisplayModePtr p;
+ float hsync, refresh = 0;
+ char *desc, *desc2, *prefix, *uprefix;
+
+ if (scrp == NULL)
+ return;
+
+ xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
+ "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
+ scrp->displayWidth);
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ desc = desc2 = "";
+ hsync = xf86ModeHSync(p);
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE) {
+ desc = " (I)";
+ }
+ if (p->Flags & V_DBLSCAN) {
+ desc = " (D)";
+ }
+ if (p->VScan > 1) {
+ desc2 = " (VScan)";
+ }
+ if (p->type & M_T_BUILTIN)
+ prefix = "Built-in mode";
+ else if (p->type & M_T_DEFAULT)
+ prefix = "Default mode";
+ else if (p->type & M_T_DRIVER)
+ prefix = "Driver mode";
+ else
+ prefix = "Mode";
+ if (p->type & M_T_USERDEF)
+ uprefix = "*";
+ else
+ uprefix = " ";
+ if (hsync == 0 || refresh == 0) {
+ if (p->name)
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\"\n", uprefix, prefix, p->name);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_PROBED,
+ "%s%s %dx%d (unnamed)\n",
+ uprefix, prefix, p->HDisplay, p->VDisplay);
+ } else if (p->Clock == p->SynthClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n",
+ uprefix, prefix, p->name, p->Clock / 1000.0,
+ hsync, refresh, desc, desc2);
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), "
+ "%.1f kHz, %.1f Hz%s%s\n",
+ uprefix, prefix, p->name, p->Clock / 1000.0,
+ p->SynthClock / 1000.0, hsync, refresh, desc, desc2);
+ }
+ if (hsync != 0 && refresh != 0)
+ xf86PrintModeline(scrp->scrnIndex,p);
+ p = p->next;
+ } while (p != NULL && p != scrp->modes);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c
index a2868bf21..965ce4c7d 100644
--- a/xorg-server/hw/xfree86/common/xf86Option.c
+++ b/xorg-server/hw/xfree86/common/xf86Option.c
@@ -1,862 +1,862 @@
-/*
- * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * Author: David Dawes <dawes@xfree86.org>
- *
- * This file includes public option handling functions.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Xinput.h"
-#include "xf86Optrec.h"
-#include "xf86Parser.h"
-
-static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed);
-
-/*
- * xf86CollectOptions collects the options from each of the config file
- * sections used by the screen and puts the combined list in pScrn->options.
- * This function requires that the following have been initialised:
- *
- * pScrn->confScreen
- * pScrn->Entities[i]->device
- * pScrn->display
- * pScrn->monitor
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- * extraOpts, display, confScreen, monitor, device
- */
-
-void
-xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
-{
- XF86OptionPtr tmp;
- XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
- GDevPtr device;
-
- int i;
-
- pScrn->options = NULL;
-
- for (i=pScrn->numEntities - 1; i >= 0; i--) {
- device = xf86GetDevFromEntity(pScrn->entityList[i],
- pScrn->entityInstanceList[i]);
- if (device && device->options) {
- tmp = xf86optionListDup(device->options);
- if (pScrn->options)
- xf86optionListMerge(pScrn->options,tmp);
- else
- pScrn->options = tmp;
- }
- }
- if (pScrn->monitor->options) {
- tmp = xf86optionListDup(pScrn->monitor->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->confScreen->options) {
- tmp = xf86optionListDup(pScrn->confScreen->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->display->options) {
- tmp = xf86optionListDup(pScrn->display->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (extras) {
- tmp = xf86optionListDup(extras);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
-}
-
-/*
- * xf86CollectInputOptions collects the options for an InputDevice.
- * This function requires that the following has been initialised:
- *
- * pInfo->conf_idev
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- * extraOpts, pInfo->conf_idev->extraOptions,
- * pInfo->conf_idev->commonOptions, defaultOpts
- */
-
-void
-xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
- pointer extraOpts)
-{
- XF86OptionPtr tmp;
- XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
-
- pInfo->options = NULL;
- if (defaultOpts) {
- pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
- }
- if (pInfo->conf_idev && pInfo->conf_idev->commonOptions) {
- tmp = xf86optionListDup(pInfo->conf_idev->commonOptions);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
- if (pInfo->conf_idev && pInfo->conf_idev->extraOptions) {
- tmp = xf86optionListDup(pInfo->conf_idev->extraOptions);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
- if (extras) {
- tmp = xf86optionListDup(extras);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
-}
-
-/* Created for new XInput stuff -- essentially extensions to the parser */
-
-static int
-LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_INTEGER;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.num;
- return deflt;
-}
-
-
-static double
-LookupRealOption(pointer optlist, const char *name, double deflt,
- Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_REAL;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.realnum;
- return deflt;
-}
-
-
-static char *
-LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_STRING;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.str;
- if (deflt)
- return xstrdup(deflt);
- else
- return NULL;
-}
-
-
-static int
-LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_BOOLEAN;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.bool;
- return deflt;
-}
-
-/* These xf86Set* functions are intended for use by non-screen specific code */
-
-int
-xf86SetIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, TRUE);
-}
-
-
-double
-xf86SetRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, TRUE);
-}
-
-
-char *
-xf86SetStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, TRUE);
-}
-
-
-int
-xf86SetBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, TRUE);
-}
-
-/*
- * These are like the Set*Option functions, but they don't mark the options
- * as used.
- */
-int
-xf86CheckIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, FALSE);
-}
-
-
-double
-xf86CheckRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, FALSE);
-}
-
-
-char *
-xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, FALSE);
-}
-
-
-int
-xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, FALSE);
-}
-
-/*
- * addNewOption() has the required property of replacing the option value
- * if the option is already present.
- */
-pointer
-xf86ReplaceIntOption(pointer optlist, const char *name, const int val)
-{
- char tmp[16];
- sprintf(tmp,"%i",val);
- return xf86AddNewOption(optlist,name,tmp);
-}
-
-pointer
-xf86ReplaceRealOption(pointer optlist, const char *name, const double val)
-{
- char tmp[32];
- snprintf(tmp,32,"%f",val);
- return xf86AddNewOption(optlist,name,tmp);
-}
-
-pointer
-xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
-{
- return xf86AddNewOption(optlist,name,val?"True":"False");
-}
-
-pointer
-xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
-{
- return xf86AddNewOption(optlist,name,val);
-}
-
-pointer
-xf86AddNewOption(pointer head, const char *name, const char *val)
-{
- /* XXX These should actually be allocated in the parser library. */
- char *tmp = strdup(val);
- char *tmp_name = strdup(name);
-
- return xf86addNewOption(head, tmp_name, tmp);
-}
-
-
-pointer
-xf86NewOption(char *name, char *value)
-{
- return xf86newOption(name, value);
-}
-
-
-pointer
-xf86NextOption(pointer list)
-{
- return xf86nextOption(list);
-}
-
-pointer
-xf86OptionListCreate(const char **options, int count, int used)
-{
- return xf86optionListCreate(options, count, used);
-}
-
-pointer
-xf86OptionListMerge(pointer head, pointer tail)
-{
- return xf86optionListMerge(head, tail);
-}
-
-void
-xf86OptionListFree(pointer opt)
-{
- xf86optionListFree(opt);
-}
-
-char *
-xf86OptionName(pointer opt)
-{
- return xf86optionName(opt);
-}
-
-char *
-xf86OptionValue(pointer opt)
-{
- return xf86optionValue(opt);
-}
-
-void
-xf86OptionListReport(pointer parm)
-{
- XF86OptionPtr opts = parm;
-
- while(opts) {
- if (xf86optionValue(opts))
- xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
- xf86optionName(opts), xf86optionValue(opts));
- else
- xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
- opts = xf86nextOption(opts);
- }
-}
-
-/* End of XInput-caused section */
-
-pointer
-xf86FindOption(pointer options, const char *name)
-{
- return xf86findOption(options, name);
-}
-
-
-char *
-xf86FindOptionValue(pointer options, const char *name)
-{
- return xf86findOptionValue(options, name);
-}
-
-
-void
-xf86MarkOptionUsed(pointer option)
-{
- if (option != NULL)
- ((XF86OptionPtr)option)->opt_used = TRUE;
-}
-
-
-void
-xf86MarkOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- opt->opt_used = TRUE;
-}
-
-Bool
-xf86CheckIfOptionUsed(pointer option)
-{
- if (option != NULL)
- return ((XF86OptionPtr)option)->opt_used;
- else
- return FALSE;
-}
-
-Bool
-xf86CheckIfOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- return opt->opt_used;
- else
- return FALSE;
-}
-
-void
-xf86ShowUnusedOptions(int scrnIndex, pointer options)
-{
- XF86OptionPtr opt = options;
-
- while (opt) {
- if (opt->opt_name && !opt->opt_used) {
- xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
- opt->opt_name);
- }
- opt = opt->list.next;
- }
-}
-
-
-static Bool
-GetBoolValue(OptionInfoPtr p, const char *s)
-{
- return xf86getBoolValue(&p->value.bool, s);
-}
-
-static Bool
-ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed)
-{
- char *s, *end;
- Bool wasUsed = FALSE;
-
- if ((s = xf86findOptionValue(options, p->name)) != NULL) {
- if (markUsed) {
- wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
- xf86MarkOptionUsedByName(options, p->name);
- }
- switch (p->type) {
- case OPTV_INTEGER:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.num = strtoul(s, &end, 0);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_STRING:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an string value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.str = s;
- p->found = TRUE;
- }
- break;
- case OPTV_ANYSTR:
- p->value.str = s;
- p->found = TRUE;
- break;
- case OPTV_REAL:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.realnum = strtod(s, &end);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_BOOLEAN:
- if (GetBoolValue(p, s)) {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n", p->name);
- p->found = FALSE;
- }
- break;
- case OPTV_FREQ:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- } else {
- double freq = strtod(s, &end);
- int units = 0;
-
- if (end != s) {
- p->found = TRUE;
- if (!xf86NameCmp(end, "Hz"))
- units = 1;
- else if (!xf86NameCmp(end, "kHz") ||
- !xf86NameCmp(end, "k"))
- units = 1000;
- else if (!xf86NameCmp(end, "MHz") ||
- !xf86NameCmp(end, "M"))
- units = 1000000;
- else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found)
- freq *= (double)units;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found) {
- p->value.freq.freq = freq;
- p->value.freq.units = units;
- }
- }
- break;
- case OPTV_NONE:
- /* Should never get here */
- p->found = FALSE;
- break;
- }
- if (p->found && markUsed) {
- int verb = 2;
- if (wasUsed)
- verb = 4;
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
- if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
- xf86ErrorFVerb(verb, " \"%s\"", s);
- }
- xf86ErrorFVerb(verb, "\n");
- }
- } else if (p->type == OPTV_BOOLEAN) {
- /* Look for matches with options with or without a "No" prefix. */
- char *n, *newn;
- OptionInfoRec opt;
-
- n = xf86NormalizeName(p->name);
- if (!n) {
- p->found = FALSE;
- return FALSE;
- }
- if (strncmp(n, "no", 2) == 0) {
- newn = n + 2;
- } else {
- xfree(n);
- n = xalloc(strlen(p->name) + 2 + 1);
- if (!n) {
- p->found = FALSE;
- return FALSE;
- }
- strcpy(n, "No");
- strcat(n, p->name);
- newn = n;
- }
- if ((s = xf86findOptionValue(options, newn)) != NULL) {
- if (markUsed)
- xf86MarkOptionUsedByName(options, newn);
- if (GetBoolValue(&opt, s)) {
- p->value.bool = !opt.value.bool;
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n", newn);
- p->found = FALSE;
- }
- } else {
- p->found = FALSE;
- }
- if (p->found && markUsed) {
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
- if (*s != 0) {
- xf86ErrorFVerb(2, " \"%s\"", s);
- }
- xf86ErrorFVerb(2, "\n");
- }
- xfree(n);
- } else {
- p->found = FALSE;
- }
- return p->found;
-}
-
-
-void
-xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
-{
- OptionInfoPtr p;
-
- for (p = optinfo; p->name != NULL; p++) {
- ParseOptionValue(scrnIndex, options, p, TRUE);
- }
-}
-
-
-OptionInfoPtr
-xf86TokenToOptinfo(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p, *match = NULL, *set = NULL;
-
- if (!table) {
- ErrorF("xf86TokenToOptinfo: table is NULL\n");
- return NULL;
- }
-
- for (p = table; p->token >= 0; p++) {
- if (p->token == token) {
- match = p;
- if (p->found)
- set = p;
- }
- }
-
- if (set)
- return (OptionInfoPtr)set;
- else if (match)
- return (OptionInfoPtr)match;
- else
- return NULL;
-}
-
-
-const char *
-xf86TokenToOptName(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p;
-
- p = xf86TokenToOptinfo(table, token);
- return p->name;
-}
-
-
-Bool
-xf86IsOptionSet(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- return (p && p->found);
-}
-
-
-char *
-xf86GetOptValString(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found)
- return p->value.str;
- else
- return NULL;
-}
-
-
-Bool
-xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.realnum;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValFreq(const OptionInfoRec *table, int token,
- OptFreqUnits expectedUnits, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- if (p->value.freq.units > 0) {
- /* Units give, so the scaling is known. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- *value = p->value.freq.freq / 1000.0;
- break;
- case OPTUNITS_MHZ:
- *value = p->value.freq.freq / 1000000.0;
- break;
- }
- } else {
- /* No units given, so try to guess the scaling. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_MHZ:
- if (p->value.freq.freq > 1000000.0)
- *value = p->value.freq.freq / 1000000.0;
- else if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- }
- }
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.bool;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- return p->value.bool;
- } else
- return def;
-}
-
-
-int
-xf86NameCmp(const char *s1, const char *s2)
-{
- return xf86nameCompare(s1, s2);
-}
-
-char *
-xf86NormalizeName(const char *s)
-{
- char *ret, *q;
- const char *p;
-
- if (s == NULL)
- return NULL;
-
- ret = xalloc(strlen(s) + 1);
- for (p = s, q = ret; *p != 0; p++) {
- switch (*p) {
- case '_':
- case ' ':
- case '\t':
- continue;
- default:
- if (isupper(*p))
- *q++ = tolower(*p);
- else
- *q++ = *p;
- }
- }
- *q = '\0';
- return ret;
-}
+/*
+ * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * Author: David Dawes <dawes@xfree86.org>
+ *
+ * This file includes public option handling functions.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86Optrec.h"
+#include "xf86Parser.h"
+
+static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed);
+
+/*
+ * xf86CollectOptions collects the options from each of the config file
+ * sections used by the screen and puts the combined list in pScrn->options.
+ * This function requires that the following have been initialised:
+ *
+ * pScrn->confScreen
+ * pScrn->Entities[i]->device
+ * pScrn->display
+ * pScrn->monitor
+ *
+ * The extraOpts parameter may optionally contain a list of additional options
+ * to include.
+ *
+ * The order of precedence for options is:
+ *
+ * extraOpts, display, confScreen, monitor, device
+ */
+
+void
+xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
+{
+ XF86OptionPtr tmp;
+ XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
+ GDevPtr device;
+
+ int i;
+
+ pScrn->options = NULL;
+
+ for (i=pScrn->numEntities - 1; i >= 0; i--) {
+ device = xf86GetDevFromEntity(pScrn->entityList[i],
+ pScrn->entityInstanceList[i]);
+ if (device && device->options) {
+ tmp = xf86optionListDup(device->options);
+ if (pScrn->options)
+ xf86optionListMerge(pScrn->options,tmp);
+ else
+ pScrn->options = tmp;
+ }
+ }
+ if (pScrn->monitor->options) {
+ tmp = xf86optionListDup(pScrn->monitor->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->confScreen->options) {
+ tmp = xf86optionListDup(pScrn->confScreen->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->display->options) {
+ tmp = xf86optionListDup(pScrn->display->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (extras) {
+ tmp = xf86optionListDup(extras);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+}
+
+/*
+ * xf86CollectInputOptions collects the options for an InputDevice.
+ * This function requires that the following has been initialised:
+ *
+ * pInfo->conf_idev
+ *
+ * The extraOpts parameter may optionally contain a list of additional options
+ * to include.
+ *
+ * The order of precedence for options is:
+ *
+ * extraOpts, pInfo->conf_idev->extraOptions,
+ * pInfo->conf_idev->commonOptions, defaultOpts
+ */
+
+void
+xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
+ pointer extraOpts)
+{
+ XF86OptionPtr tmp;
+ XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
+
+ pInfo->options = NULL;
+ if (defaultOpts) {
+ pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
+ }
+ if (pInfo->conf_idev && pInfo->conf_idev->commonOptions) {
+ tmp = xf86optionListDup(pInfo->conf_idev->commonOptions);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+ if (pInfo->conf_idev && pInfo->conf_idev->extraOptions) {
+ tmp = xf86optionListDup(pInfo->conf_idev->extraOptions);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+ if (extras) {
+ tmp = xf86optionListDup(extras);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+}
+
+/* Created for new XInput stuff -- essentially extensions to the parser */
+
+static int
+LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_INTEGER;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.num;
+ return deflt;
+}
+
+
+static double
+LookupRealOption(pointer optlist, const char *name, double deflt,
+ Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_REAL;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.realnum;
+ return deflt;
+}
+
+
+static char *
+LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_STRING;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.str;
+ if (deflt)
+ return xstrdup(deflt);
+ else
+ return NULL;
+}
+
+
+static int
+LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_BOOLEAN;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.bool;
+ return deflt;
+}
+
+/* These xf86Set* functions are intended for use by non-screen specific code */
+
+int
+xf86SetIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, TRUE);
+}
+
+
+double
+xf86SetRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, TRUE);
+}
+
+
+char *
+xf86SetStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, TRUE);
+}
+
+
+int
+xf86SetBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, TRUE);
+}
+
+/*
+ * These are like the Set*Option functions, but they don't mark the options
+ * as used.
+ */
+int
+xf86CheckIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, FALSE);
+}
+
+
+double
+xf86CheckRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, FALSE);
+}
+
+
+char *
+xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, FALSE);
+}
+
+
+int
+xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, FALSE);
+}
+
+/*
+ * addNewOption() has the required property of replacing the option value
+ * if the option is already present.
+ */
+pointer
+xf86ReplaceIntOption(pointer optlist, const char *name, const int val)
+{
+ char tmp[16];
+ sprintf(tmp,"%i",val);
+ return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
+xf86ReplaceRealOption(pointer optlist, const char *name, const double val)
+{
+ char tmp[32];
+ snprintf(tmp,32,"%f",val);
+ return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
+xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
+{
+ return xf86AddNewOption(optlist,name,val?"True":"False");
+}
+
+pointer
+xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
+{
+ return xf86AddNewOption(optlist,name,val);
+}
+
+pointer
+xf86AddNewOption(pointer head, const char *name, const char *val)
+{
+ /* XXX These should actually be allocated in the parser library. */
+ char *tmp = strdup(val);
+ char *tmp_name = strdup(name);
+
+ return xf86addNewOption(head, tmp_name, tmp);
+}
+
+
+pointer
+xf86NewOption(char *name, char *value)
+{
+ return xf86newOption(name, value);
+}
+
+
+pointer
+xf86NextOption(pointer list)
+{
+ return xf86nextOption(list);
+}
+
+pointer
+xf86OptionListCreate(const char **options, int count, int used)
+{
+ return xf86optionListCreate(options, count, used);
+}
+
+pointer
+xf86OptionListMerge(pointer head, pointer tail)
+{
+ return xf86optionListMerge(head, tail);
+}
+
+void
+xf86OptionListFree(pointer opt)
+{
+ xf86optionListFree(opt);
+}
+
+char *
+xf86OptionName(pointer opt)
+{
+ return xf86optionName(opt);
+}
+
+char *
+xf86OptionValue(pointer opt)
+{
+ return xf86optionValue(opt);
+}
+
+void
+xf86OptionListReport(pointer parm)
+{
+ XF86OptionPtr opts = parm;
+
+ while(opts) {
+ if (xf86optionValue(opts))
+ xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
+ xf86optionName(opts), xf86optionValue(opts));
+ else
+ xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
+ opts = xf86nextOption(opts);
+ }
+}
+
+/* End of XInput-caused section */
+
+pointer
+xf86FindOption(pointer options, const char *name)
+{
+ return xf86findOption(options, name);
+}
+
+
+char *
+xf86FindOptionValue(pointer options, const char *name)
+{
+ return xf86findOptionValue(options, name);
+}
+
+
+void
+xf86MarkOptionUsed(pointer option)
+{
+ if (option != NULL)
+ ((XF86OptionPtr)option)->opt_used = TRUE;
+}
+
+
+void
+xf86MarkOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ opt->opt_used = TRUE;
+}
+
+Bool
+xf86CheckIfOptionUsed(pointer option)
+{
+ if (option != NULL)
+ return ((XF86OptionPtr)option)->opt_used;
+ else
+ return FALSE;
+}
+
+Bool
+xf86CheckIfOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ return opt->opt_used;
+ else
+ return FALSE;
+}
+
+void
+xf86ShowUnusedOptions(int scrnIndex, pointer options)
+{
+ XF86OptionPtr opt = options;
+
+ while (opt) {
+ if (opt->opt_name && !opt->opt_used) {
+ xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
+ opt->opt_name);
+ }
+ opt = opt->list.next;
+ }
+}
+
+
+static Bool
+GetBoolValue(OptionInfoPtr p, const char *s)
+{
+ return xf86getBoolValue(&p->value.bool, s);
+}
+
+static Bool
+ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed)
+{
+ char *s, *end;
+ Bool wasUsed = FALSE;
+
+ if ((s = xf86findOptionValue(options, p->name)) != NULL) {
+ if (markUsed) {
+ wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
+ xf86MarkOptionUsedByName(options, p->name);
+ }
+ switch (p->type) {
+ case OPTV_INTEGER:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.num = strtoul(s, &end, 0);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_STRING:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an string value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.str = s;
+ p->found = TRUE;
+ }
+ break;
+ case OPTV_ANYSTR:
+ p->value.str = s;
+ p->found = TRUE;
+ break;
+ case OPTV_REAL:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.realnum = strtod(s, &end);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_BOOLEAN:
+ if (GetBoolValue(p, s)) {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n", p->name);
+ p->found = FALSE;
+ }
+ break;
+ case OPTV_FREQ:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ double freq = strtod(s, &end);
+ int units = 0;
+
+ if (end != s) {
+ p->found = TRUE;
+ if (!xf86NameCmp(end, "Hz"))
+ units = 1;
+ else if (!xf86NameCmp(end, "kHz") ||
+ !xf86NameCmp(end, "k"))
+ units = 1000;
+ else if (!xf86NameCmp(end, "MHz") ||
+ !xf86NameCmp(end, "M"))
+ units = 1000000;
+ else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found)
+ freq *= (double)units;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found) {
+ p->value.freq.freq = freq;
+ p->value.freq.units = units;
+ }
+ }
+ break;
+ case OPTV_NONE:
+ /* Should never get here */
+ p->found = FALSE;
+ break;
+ }
+ if (p->found && markUsed) {
+ int verb = 2;
+ if (wasUsed)
+ verb = 4;
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
+ if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
+ xf86ErrorFVerb(verb, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(verb, "\n");
+ }
+ } else if (p->type == OPTV_BOOLEAN) {
+ /* Look for matches with options with or without a "No" prefix. */
+ char *n, *newn;
+ OptionInfoRec opt;
+
+ n = xf86NormalizeName(p->name);
+ if (!n) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ if (strncmp(n, "no", 2) == 0) {
+ newn = n + 2;
+ } else {
+ free(n);
+ n = malloc(strlen(p->name) + 2 + 1);
+ if (!n) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ strcpy(n, "No");
+ strcat(n, p->name);
+ newn = n;
+ }
+ if ((s = xf86findOptionValue(options, newn)) != NULL) {
+ if (markUsed)
+ xf86MarkOptionUsedByName(options, newn);
+ if (GetBoolValue(&opt, s)) {
+ p->value.bool = !opt.value.bool;
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n", newn);
+ p->found = FALSE;
+ }
+ } else {
+ p->found = FALSE;
+ }
+ if (p->found && markUsed) {
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
+ if (*s != 0) {
+ xf86ErrorFVerb(2, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(2, "\n");
+ }
+ free(n);
+ } else {
+ p->found = FALSE;
+ }
+ return p->found;
+}
+
+
+void
+xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
+{
+ OptionInfoPtr p;
+
+ for (p = optinfo; p->name != NULL; p++) {
+ ParseOptionValue(scrnIndex, options, p, TRUE);
+ }
+}
+
+
+OptionInfoPtr
+xf86TokenToOptinfo(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p, *match = NULL, *set = NULL;
+
+ if (!table) {
+ ErrorF("xf86TokenToOptinfo: table is NULL\n");
+ return NULL;
+ }
+
+ for (p = table; p->token >= 0; p++) {
+ if (p->token == token) {
+ match = p;
+ if (p->found)
+ set = p;
+ }
+ }
+
+ if (set)
+ return (OptionInfoPtr)set;
+ else if (match)
+ return (OptionInfoPtr)match;
+ else
+ return NULL;
+}
+
+
+const char *
+xf86TokenToOptName(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return p->name;
+}
+
+
+Bool
+xf86IsOptionSet(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return (p && p->found);
+}
+
+
+char *
+xf86GetOptValString(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found)
+ return p->value.str;
+ else
+ return NULL;
+}
+
+
+Bool
+xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.realnum;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValFreq(const OptionInfoRec *table, int token,
+ OptFreqUnits expectedUnits, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ if (p->value.freq.units > 0) {
+ /* Units give, so the scaling is known. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ *value = p->value.freq.freq / 1000.0;
+ break;
+ case OPTUNITS_MHZ:
+ *value = p->value.freq.freq / 1000000.0;
+ break;
+ }
+ } else {
+ /* No units given, so try to guess the scaling. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_MHZ:
+ if (p->value.freq.freq > 1000000.0)
+ *value = p->value.freq.freq / 1000000.0;
+ else if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ }
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.bool;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ return p->value.bool;
+ } else
+ return def;
+}
+
+
+int
+xf86NameCmp(const char *s1, const char *s2)
+{
+ return xf86nameCompare(s1, s2);
+}
+
+char *
+xf86NormalizeName(const char *s)
+{
+ char *ret, *q;
+ const char *p;
+
+ if (s == NULL)
+ return NULL;
+
+ ret = malloc(strlen(s) + 1);
+ for (p = s, q = ret; *p != 0; p++) {
+ switch (*p) {
+ case '_':
+ case ' ':
+ case '\t':
+ continue;
+ default:
+ if (isupper(*p))
+ *q++ = tolower(*p);
+ else
+ *q++ = *p;
+ }
+ }
+ *q = '\0';
+ return ret;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Privstr.h b/xorg-server/hw/xfree86/common/xf86Privstr.h
index b2095aab1..6138b6bec 100644
--- a/xorg-server/hw/xfree86/common/xf86Privstr.h
+++ b/xorg-server/hw/xfree86/common/xf86Privstr.h
@@ -1,173 +1,170 @@
-
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains definitions of the private XFree86 data structures/types.
- * None of the data structures here should be used by video drivers.
- */
-
-#ifndef _XF86PRIVSTR_H
-#define _XF86PRIVSTR_H
-
-#include "xf86str.h"
-
-typedef enum {
- LogNone,
- LogFlush,
- LogSync
-} Log;
-
-typedef enum {
- XF86_GlxVisualsMinimal,
- XF86_GlxVisualsTypical,
- XF86_GlxVisualsAll,
-} XF86_GlxVisuals;
-
-/*
- * xf86InfoRec contains global parameters which the video drivers never
- * need to access. Global parameters which the video drivers do need
- * should be individual globals.
- */
-
-typedef struct {
- int consoleFd;
- int vtno;
- Bool vtSysreq;
-
- /* event handler part */
- int lastEventTime;
- Bool vtRequestsPending;
-#ifdef sun
- int vtPendingNum;
-#endif
- Bool dontVTSwitch;
- Bool dontZap;
- Bool dontZoom;
- Bool notrapSignals; /* don't exit cleanly - die at fault */
- Bool caughtSignal;
-
- /* graphics part */
- ScreenPtr currentScreen;
-#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
- int screenFd; /* fd for memory mapped access to
- * vga card */
- int consType; /* Which console driver? */
-#endif
-
- /* Other things */
- Bool allowMouseOpenFail;
- Bool vidModeEnabled; /* VidMode extension enabled */
- Bool vidModeAllowNonLocal; /* allow non-local VidMode
- * connections */
- Bool miscModInDevEnabled; /* Allow input devices to be
- * changed */
- Bool miscModInDevAllowNonLocal;
- Bool useSIGIO; /* Use SIGIO for handling
- input device events */
- Pix24Flags pixmap24;
- MessageType pix24From;
-#ifdef SUPPORT_PC98
- Bool pc98;
-#endif
- Bool pmFlag;
- Log log;
- Bool kbdCustomKeycodes;
- Bool disableRandR;
- MessageType randRFrom;
- Bool aiglx;
- MessageType aiglxFrom;
- XF86_GlxVisuals glxVisuals;
- MessageType glxVisualsFrom;
-
- Bool useDefaultFontPath;
- MessageType useDefaultFontPathFrom;
- Bool ignoreABI;
-
- Bool allowEmptyInput; /* Allow the server to start with no input
- * devices. */
- Bool autoAddDevices; /* Whether to succeed NIDR, or ignore. */
- Bool autoEnableDevices; /* Whether to enable, or let the client
- * control. */
-
- Bool dri2;
- MessageType dri2From;
-} xf86InfoRec, *xf86InfoPtr;
-
-#ifdef DPMSExtension
-/* Private info for DPMS */
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- Bool Enabled;
- int Flags;
-} DPMSRec, *DPMSPtr;
-#endif
-
-#ifdef XF86VIDMODE
-/* Private info for Video Mode Extentsion */
-typedef struct {
- DisplayModePtr First;
- DisplayModePtr Next;
- int Flags;
- CloseScreenProcPtr CloseScreen;
-} VidModeRec, *VidModePtr;
-#endif
-
-/* Information for root window properties. */
-typedef struct _RootWinProp {
- struct _RootWinProp * next;
- char * name;
- Atom type;
- short format;
- long size;
- pointer data;
-} RootWinProp, *RootWinPropPtr;
-
-/* private resource types */
-#define ResNoAvoid ResBios
-
-/* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
-#define XLED1 ((unsigned long) 0x00000001)
-#define XLED2 ((unsigned long) 0x00000002)
-#define XLED3 ((unsigned long) 0x00000004)
-#define XLED4 ((unsigned long) 0x00000008)
-#define XCAPS ((unsigned long) 0x20000000)
-#define XNUM ((unsigned long) 0x40000000)
-#define XSCR ((unsigned long) 0x80000000)
-#define XCOMP ((unsigned long) 0x00008000)
-
-/* BSD console driver types (consType) */
-#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
-#define PCCONS 0
-#define CODRV011 1
-#define CODRV01X 2
-#define SYSCONS 8
-#define PCVT 16
-#define WSCONS 32
-#endif
-
-#endif /* _XF86PRIVSTR_H */
+
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains definitions of the private XFree86 data structures/types.
+ * None of the data structures here should be used by video drivers.
+ */
+
+#ifndef _XF86PRIVSTR_H
+#define _XF86PRIVSTR_H
+
+#include "xf86str.h"
+
+typedef enum {
+ LogNone,
+ LogFlush,
+ LogSync
+} Log;
+
+typedef enum {
+ XF86_GlxVisualsMinimal,
+ XF86_GlxVisualsTypical,
+ XF86_GlxVisualsAll,
+} XF86_GlxVisuals;
+
+/*
+ * xf86InfoRec contains global parameters which the video drivers never
+ * need to access. Global parameters which the video drivers do need
+ * should be individual globals.
+ */
+
+typedef struct {
+ int consoleFd;
+ int vtno;
+ Bool vtSysreq;
+
+ /* event handler part */
+ int lastEventTime;
+ Bool vtRequestsPending;
+#ifdef sun
+ int vtPendingNum;
+#endif
+ Bool dontVTSwitch;
+ Bool dontZap;
+ Bool dontZoom;
+ Bool notrapSignals; /* don't exit cleanly - die at fault */
+ Bool caughtSignal;
+
+ /* graphics part */
+ ScreenPtr currentScreen;
+#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
+ int screenFd; /* fd for memory mapped access to
+ * vga card */
+ int consType; /* Which console driver? */
+#endif
+
+ /* Other things */
+ Bool allowMouseOpenFail;
+ Bool vidModeEnabled; /* VidMode extension enabled */
+ Bool vidModeAllowNonLocal; /* allow non-local VidMode
+ * connections */
+ Bool miscModInDevEnabled; /* Allow input devices to be
+ * changed */
+ Bool miscModInDevAllowNonLocal;
+ Bool useSIGIO; /* Use SIGIO for handling
+ input device events */
+ Pix24Flags pixmap24;
+ MessageType pix24From;
+#ifdef SUPPORT_PC98
+ Bool pc98;
+#endif
+ Bool pmFlag;
+ Log log;
+ Bool kbdCustomKeycodes;
+ Bool disableRandR;
+ MessageType randRFrom;
+ Bool aiglx;
+ MessageType aiglxFrom;
+ XF86_GlxVisuals glxVisuals;
+ MessageType glxVisualsFrom;
+
+ Bool useDefaultFontPath;
+ MessageType useDefaultFontPathFrom;
+ Bool ignoreABI;
+
+ Bool allowEmptyInput; /* Allow the server to start with no input
+ * devices. */
+ Bool autoAddDevices; /* Whether to succeed NIDR, or ignore. */
+ Bool autoEnableDevices; /* Whether to enable, or let the client
+ * control. */
+
+ Bool dri2;
+ MessageType dri2From;
+} xf86InfoRec, *xf86InfoPtr;
+
+#ifdef DPMSExtension
+/* Private info for DPMS */
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ Bool Enabled;
+ int Flags;
+} DPMSRec, *DPMSPtr;
+#endif
+
+#ifdef XF86VIDMODE
+/* Private info for Video Mode Extentsion */
+typedef struct {
+ DisplayModePtr First;
+ DisplayModePtr Next;
+ int Flags;
+ CloseScreenProcPtr CloseScreen;
+} VidModeRec, *VidModePtr;
+#endif
+
+/* Information for root window properties. */
+typedef struct _RootWinProp {
+ struct _RootWinProp * next;
+ char * name;
+ Atom type;
+ short format;
+ long size;
+ pointer data;
+} RootWinProp, *RootWinPropPtr;
+
+/* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
+#define XLED1 ((unsigned long) 0x00000001)
+#define XLED2 ((unsigned long) 0x00000002)
+#define XLED3 ((unsigned long) 0x00000004)
+#define XLED4 ((unsigned long) 0x00000008)
+#define XCAPS ((unsigned long) 0x20000000)
+#define XNUM ((unsigned long) 0x40000000)
+#define XSCR ((unsigned long) 0x80000000)
+#define XCOMP ((unsigned long) 0x00008000)
+
+/* BSD console driver types (consType) */
+#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
+#define PCCONS 0
+#define CODRV011 1
+#define CODRV01X 2
+#define SYSCONS 8
+#define PCVT 16
+#define WSCONS 32
+#endif
+
+#endif /* _XF86PRIVSTR_H */
diff --git a/xorg-server/hw/xfree86/common/xf86RandR.c b/xorg-server/hw/xfree86/common/xf86RandR.c
index 86c7bde79..1893974e2 100644
--- a/xorg-server/hw/xfree86/common/xf86RandR.c
+++ b/xorg-server/hw/xfree86/common/xf86RandR.c
@@ -1,459 +1,459 @@
-/*
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86str.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include <randrstr.h>
-#include "inputstr.h"
-
-typedef struct _xf86RandRInfo {
- CreateScreenResourcesProcPtr CreateScreenResources;
- CloseScreenProcPtr CloseScreen;
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- Rotation rotation;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-static int xf86RandRKeyIndex;
-static DevPrivateKey xf86RandRKey;
-
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
-
-static int
-xf86RandRModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else if (mode->Clock == 0)
- return 0;
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- xorgRRModeMM RRModeMM;
-
- *rotations = RR_Rotate_0;
-
- for (mode = scrp->modes; mode != NULL ; mode = mode->next)
- {
- int refresh = xf86RandRModeRefresh (mode);
-
- if (mode == scrp->modes)
- refresh0 = refresh;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
- if (mode == scrp->currentMode &&
- mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- if (mode->next == scrp->modes)
- break;
- }
- if (scrp->currentMode->HDisplay != randrp->virtualX ||
- scrp->currentMode->VDisplay != randrp->virtualY)
- {
- mode = scrp->modes;
-
- RRModeMM.mode = NULL;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- randrp->virtualX, randrp->virtualY,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh0);
- if (scrp->virtualX == randrp->virtualX &&
- scrp->virtualY == randrp->virtualY)
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
- }
- }
-
- /* If there is driver support for randr, let it set our supported rotations */
- if(scrp->DriverFunc) {
- xorgRRRotation RRRotation;
-
- RRRotation.RRRotations = *rotations;
- if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
- return TRUE;
- *rotations = RRRotation.RRRotations;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandRSetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- int oldVirtualX = scrp->virtualX;
- int oldVirtualY = scrp->virtualY;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- Bool ret = TRUE;
-
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- /*
- * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
- * reconstruct them if possible.
- */
- if(scrp->DriverFunc) {
- xorgRRModeMM RRModeMM;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = scrp->virtualX;
- RRModeMM.virtY = scrp->virtualY;
- RRModeMM.mmWidth = mmWidth;
- RRModeMM.mmHeight = mmHeight;
-
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
-
- mmWidth = RRModeMM.mmWidth;
- mmHeight = RRModeMM.mmHeight;
- }
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (!xf86SwitchMode (pScreen, mode))
- {
- pScreen->width = oldWidth;
- pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->virtualX = oldVirtualX;
- scrp->virtualY = oldVirtualY;
- ret = FALSE;
- }
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-static Bool
-xf86RandRSetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int px, py;
- Bool useVirtual = FALSE;
- Rotation oldRotation = randrp->rotation;
-
- miPointerGetPosition(inputInfo.pointer, &px, &py);
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandRModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- return FALSE;
- }
- }
-
- if (randrp->rotation != rotation) {
-
- /* Have the driver do its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = rotation;
- RRRotation.RRConfig.rate = rate;
- RRRotation.RRConfig.width = pSize->width;
- RRRotation.RRConfig.height = pSize->height;
-
- /*
- * Currently we need to rely on HW support for rotation.
- */
- if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
- return FALSE;
- } else
- return FALSE;
-
- randrp->rotation = rotation;
- }
-
- if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
- if(randrp->rotation != oldRotation) {
- /* Have the driver undo its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = oldRotation;
- RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
- RRRotation.RRConfig.width = scrp->virtualX;
- RRRotation.RRConfig.height = scrp->virtualY;
- (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
- }
-
- randrp->rotation = oldRotation;
- }
- return FALSE;
- }
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- */
- if (pScreen == miPointerCurrentScreen ())
- {
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- xf86SetViewport(pScreen, px, py);
-
- (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
- }
-
- return TRUE;
-}
-
-/*
- * Wait until the screen is initialized before whacking the
- * sizes around; otherwise the screen pixmap will be allocated
- * at the current mode size rather than the maximum size
- */
-static Bool
-xf86RandRCreateScreenResources (ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-#if 0
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- DisplayModePtr mode;
-#endif
-
- pScreen->CreateScreenResources = randrp->CreateScreenResources;
- if (!(*pScreen->CreateScreenResources) (pScreen))
- return FALSE;
-
-#if 0
- mode = scrp->currentMode;
- if (mode)
- xf86RandRSetMode (pScreen, mode, TRUE);
-#endif
-
- return TRUE;
-}
-
-/*
- * Reset size back to original
- */
-static Bool
-xf86RandRCloseScreen (int index, ScreenPtr pScreen)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- scrp->virtualX = pScreen->width = randrp->virtualX;
- scrp->virtualY = pScreen->height = randrp->virtualY;
- scrp->currentMode = scrp->modes;
- pScreen->CloseScreen = randrp->CloseScreen;
- xfree (randrp);
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
- return (*pScreen->CloseScreen) (index, pScreen);
-}
-
-Rotation
-xf86GetRotation(ScreenPtr pScreen)
-{
- if (xf86RandRKey == NULL)
- return RR_Rotate_0;
-
- return XF86RANDRINFO(pScreen)->rotation;
-}
-
-/* Function to change RandR's idea of the virtual screen size */
-Bool
-xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
- int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
- Bool resetMode)
-{
- XF86RandRInfoPtr randrp;
-
- if (xf86RandRKey == NULL)
- return FALSE;
-
- randrp = XF86RANDRINFO(pScreen);
- if (randrp == NULL)
- return FALSE;
-
- if (newvirtX > 0)
- randrp->virtualX = newvirtX;
-
- if (newvirtY > 0)
- randrp->virtualY = newvirtY;
-
- if (newmmWidth > 0)
- randrp->mmWidth = newmmWidth;
-
- if (newmmHeight > 0)
- randrp->mmHeight = newmmHeight;
-
- /* This is only for during server start */
- if (resetMode) {
- return (xf86RandRSetMode(pScreen,
- XF86SCRNINFO(pScreen)->currentMode,
- TRUE,
- pScreen->mmWidth, pScreen->mmHeight));
- }
-
- return TRUE;
-}
-
-Bool
-xf86RandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- xf86RandRKey = &xf86RandRKeyIndex;
-
- randrp = xalloc (sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit (pScreen))
- {
- xfree (randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandRGetInfo;
- rp->rrSetConfig = xf86RandRSetConfig;
-
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->CreateScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
-
- randrp->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86RandRCloseScreen;
-
- randrp->rotation = RR_Rotate_0;
-
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
- return TRUE;
-}
-
-
+/*
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include <randrstr.h>
+#include "inputstr.h"
+
+typedef struct _xf86RandRInfo {
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ Rotation rotation;
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+static int xf86RandRKeyIndex;
+static DevPrivateKey xf86RandRKey;
+
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
+
+static int
+xf86RandRModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else if (mode->Clock == 0)
+ return 0;
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ xorgRRModeMM RRModeMM;
+
+ *rotations = RR_Rotate_0;
+
+ for (mode = scrp->modes; mode != NULL ; mode = mode->next)
+ {
+ int refresh = xf86RandRModeRefresh (mode);
+
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+ if (mode == scrp->currentMode &&
+ mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ if (mode->next == scrp->modes)
+ break;
+ }
+ if (scrp->currentMode->HDisplay != randrp->virtualX ||
+ scrp->currentMode->VDisplay != randrp->virtualY)
+ {
+ mode = scrp->modes;
+
+ RRModeMM.mode = NULL;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ randrp->virtualX, randrp->virtualY,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh0);
+ if (scrp->virtualX == randrp->virtualX &&
+ scrp->virtualY == randrp->virtualY)
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+ }
+ }
+
+ /* If there is driver support for randr, let it set our supported rotations */
+ if(scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+
+ RRRotation.RRRotations = *rotations;
+ if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
+ return TRUE;
+ *rotations = RRRotation.RRRotations;
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandRSetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ int oldVirtualX = scrp->virtualX;
+ int oldVirtualY = scrp->virtualY;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ Bool ret = TRUE;
+
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+
+ /*
+ * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
+ * reconstruct them if possible.
+ */
+ if(scrp->DriverFunc) {
+ xorgRRModeMM RRModeMM;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = scrp->virtualX;
+ RRModeMM.virtY = scrp->virtualY;
+ RRModeMM.mmWidth = mmWidth;
+ RRModeMM.mmHeight = mmHeight;
+
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+
+ mmWidth = RRModeMM.mmWidth;
+ mmHeight = RRModeMM.mmHeight;
+ }
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ pScreen->width = oldWidth;
+ pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->virtualX = oldVirtualX;
+ scrp->virtualY = oldVirtualY;
+ ret = FALSE;
+ }
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+static Bool
+xf86RandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int px, py;
+ Bool useVirtual = FALSE;
+ Rotation oldRotation = randrp->rotation;
+
+ miPointerGetPosition(inputInfo.pointer, &px, &py);
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || xf86RandRModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->rotation != rotation) {
+
+ /* Have the driver do its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = rotation;
+ RRRotation.RRConfig.rate = rate;
+ RRRotation.RRConfig.width = pSize->width;
+ RRRotation.RRConfig.height = pSize->height;
+
+ /*
+ * Currently we need to rely on HW support for rotation.
+ */
+ if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
+ return FALSE;
+ } else
+ return FALSE;
+
+ randrp->rotation = rotation;
+ }
+
+ if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+ if(randrp->rotation != oldRotation) {
+ /* Have the driver undo its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = oldRotation;
+ RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
+ RRRotation.RRConfig.width = scrp->virtualX;
+ RRRotation.RRConfig.height = scrp->virtualY;
+ (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
+ }
+
+ randrp->rotation = oldRotation;
+ }
+ return FALSE;
+ }
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ */
+ if (pScreen == miPointerCurrentScreen ())
+ {
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ xf86SetViewport(pScreen, px, py);
+
+ (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Wait until the screen is initialized before whacking the
+ * sizes around; otherwise the screen pixmap will be allocated
+ * at the current mode size rather than the maximum size
+ */
+static Bool
+xf86RandRCreateScreenResources (ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+#if 0
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ DisplayModePtr mode;
+#endif
+
+ pScreen->CreateScreenResources = randrp->CreateScreenResources;
+ if (!(*pScreen->CreateScreenResources) (pScreen))
+ return FALSE;
+
+#if 0
+ mode = scrp->currentMode;
+ if (mode)
+ xf86RandRSetMode (pScreen, mode, TRUE);
+#endif
+
+ return TRUE;
+}
+
+/*
+ * Reset size back to original
+ */
+static Bool
+xf86RandRCloseScreen (int index, ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ scrp->virtualX = pScreen->width = randrp->virtualX;
+ scrp->virtualY = pScreen->height = randrp->virtualY;
+ scrp->currentMode = scrp->modes;
+ pScreen->CloseScreen = randrp->CloseScreen;
+ free(randrp);
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
+ return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+Rotation
+xf86GetRotation(ScreenPtr pScreen)
+{
+ if (xf86RandRKey == NULL)
+ return RR_Rotate_0;
+
+ return XF86RANDRINFO(pScreen)->rotation;
+}
+
+/* Function to change RandR's idea of the virtual screen size */
+Bool
+xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
+ int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
+ Bool resetMode)
+{
+ XF86RandRInfoPtr randrp;
+
+ if (xf86RandRKey == NULL)
+ return FALSE;
+
+ randrp = XF86RANDRINFO(pScreen);
+ if (randrp == NULL)
+ return FALSE;
+
+ if (newvirtX > 0)
+ randrp->virtualX = newvirtX;
+
+ if (newvirtY > 0)
+ randrp->virtualY = newvirtY;
+
+ if (newmmWidth > 0)
+ randrp->mmWidth = newmmWidth;
+
+ if (newmmHeight > 0)
+ randrp->mmHeight = newmmHeight;
+
+ /* This is only for during server start */
+ if (resetMode) {
+ return (xf86RandRSetMode(pScreen,
+ XF86SCRNINFO(pScreen)->currentMode,
+ TRUE,
+ pScreen->mmWidth, pScreen->mmHeight));
+ }
+
+ return TRUE;
+}
+
+Bool
+xf86RandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+
+ xf86RandRKey = &xf86RandRKeyIndex;
+
+ randrp = malloc(sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit (pScreen))
+ {
+ free(randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = xf86RandRGetInfo;
+ rp->rrSetConfig = xf86RandRSetConfig;
+
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
+
+ randrp->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86RandRCloseScreen;
+
+ randrp->rotation = RR_Rotate_0;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
+ return TRUE;
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86ShowOpts.c b/xorg-server/hw/xfree86/common/xf86ShowOpts.c
index 04a9a8b1c..77f156486 100644
--- a/xorg-server/hw/xfree86/common/xf86ShowOpts.c
+++ b/xorg-server/hw/xfree86/common/xf86ShowOpts.c
@@ -1,128 +1,128 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * 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 Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE 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.
- *
- * Author: Marcus Schaefer, ms@suse.de
- *
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include "os.h"
-#ifdef XFree86LOADER
-#include "loaderProcs.h"
-#endif
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-/* #include "xf86PciData.h" */
-#define IN_XSERVER
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "Configint.h"
-#include "xf86DDC.h"
-#if defined(__sparc__) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-#include "globals.h"
-
-static const char*
-optionTypeToSting(OptionValueType type)
-{
- switch (type) {
- case OPTV_NONE:
- return "";
- case OPTV_INTEGER:
- return "<int>";
- case OPTV_STRING:
- return "<str>";
- case OPTV_ANYSTR:
- return "<str>";
- case OPTV_REAL:
- return "<real>";
- case OPTV_BOOLEAN:
- return "<bool>";
- case OPTV_FREQ:
- return "<freq>";
- default:
- return "<undef>";
- }
-}
-
-void DoShowOptions (void) {
- int i = 0;
- char **vlist = 0;
- char *pSymbol = 0;
- XF86ModuleData *initData = 0;
- if (! (vlist = xf86DriverlistFromCompile())) {
- ErrorF("Missing output drivers\n");
- goto bail;
- }
- xf86LoadModules (vlist,0);
- xfree (vlist);
- for (i = 0; i < xf86NumDrivers; i++) {
- if (xf86DriverList[i]->AvailableOptions) {
- OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0);
- if (! pOption) {
- ErrorF ("(EE) Couldn't read option table for %s driver\n",
- xf86DriverList[i]->driverName
- );
- continue;
- }
- pSymbol = xalloc (
- strlen(xf86DriverList[i]->driverName) + strlen("ModuleData") + 1
- );
- strcpy (pSymbol, xf86DriverList[i]->driverName);
- strcat (pSymbol, "ModuleData");
- initData = LoaderSymbol (pSymbol);
- if (initData) {
- XF86ModuleVersionInfo *vers = initData->vers;
- OptionInfoPtr p;
- ErrorF ("Driver[%d]:%s[%s] {\n",
- i,xf86DriverList[i]->driverName,vers->vendor
- );
- for (p = pOption; p->name != NULL; p++) {
- const char *opttype = optionTypeToSting(p->type);
- char *optname = xalloc(strlen(p->name) + 2 + 1);
- if (!optname) {
- continue;
- }
- sprintf(optname, "%s", p->name);
- ErrorF ("\t%s:%s\n", optname,opttype);
- }
- ErrorF ("}\n");
- }
- }
- }
- bail:
- OsCleanup (TRUE);
- AbortDDX ();
- fflush (stderr);
- exit (0);
-}
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * 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 Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Author: Marcus Schaefer, ms@suse.de
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "os.h"
+#ifdef XFree86LOADER
+#include "loaderProcs.h"
+#endif
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+/* #include "xf86PciData.h" */
+#define IN_XSERVER
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include "xf86DDC.h"
+#if defined(__sparc__) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+#include "globals.h"
+
+static const char*
+optionTypeToSting(OptionValueType type)
+{
+ switch (type) {
+ case OPTV_NONE:
+ return "";
+ case OPTV_INTEGER:
+ return "<int>";
+ case OPTV_STRING:
+ return "<str>";
+ case OPTV_ANYSTR:
+ return "<str>";
+ case OPTV_REAL:
+ return "<real>";
+ case OPTV_BOOLEAN:
+ return "<bool>";
+ case OPTV_FREQ:
+ return "<freq>";
+ default:
+ return "<undef>";
+ }
+}
+
+void DoShowOptions (void) {
+ int i = 0;
+ char **vlist = 0;
+ char *pSymbol = 0;
+ XF86ModuleData *initData = 0;
+ if (! (vlist = xf86DriverlistFromCompile())) {
+ ErrorF("Missing output drivers\n");
+ goto bail;
+ }
+ xf86LoadModules (vlist,0);
+ free(vlist);
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->AvailableOptions) {
+ OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0);
+ if (! pOption) {
+ ErrorF ("(EE) Couldn't read option table for %s driver\n",
+ xf86DriverList[i]->driverName
+ );
+ continue;
+ }
+ pSymbol = malloc(
+ strlen(xf86DriverList[i]->driverName) + strlen("ModuleData") + 1
+ );
+ strcpy (pSymbol, xf86DriverList[i]->driverName);
+ strcat (pSymbol, "ModuleData");
+ initData = LoaderSymbol (pSymbol);
+ if (initData) {
+ XF86ModuleVersionInfo *vers = initData->vers;
+ OptionInfoPtr p;
+ ErrorF ("Driver[%d]:%s[%s] {\n",
+ i,xf86DriverList[i]->driverName,vers->vendor
+ );
+ for (p = pOption; p->name != NULL; p++) {
+ const char *opttype = optionTypeToSting(p->type);
+ char *optname = malloc(strlen(p->name) + 2 + 1);
+ if (!optname) {
+ continue;
+ }
+ sprintf(optname, "%s", p->name);
+ ErrorF ("\t%s:%s\n", optname,opttype);
+ }
+ ErrorF ("}\n");
+ }
+ }
+ }
+ bail:
+ OsCleanup (TRUE);
+ AbortDDX ();
+ fflush (stderr);
+ exit (0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
index 52a8b9a60..ac44c5e67 100644
--- a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
+++ b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
@@ -1,1101 +1,1101 @@
-/*
- * This code was stolen from RAC and adapted to control the legacy vga
- * interface.
- *
- *
- * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "xorg-config.h"
-
-#include "xf86VGAarbiter.h"
-
-#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
-#include "xf86VGAarbiterPriv.h"
-#include "xf86Bus.h"
-#include "xf86Priv.h"
-#include "pciaccess.h"
-
-
-static GCFuncs VGAarbiterGCFuncs = {
- VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
- VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
- VGAarbiterCopyClip
-};
-
-static GCOps VGAarbiterGCOps = {
- VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
- VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
- VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
- VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
- VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
- VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
- VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
- {NULL} /* devPrivate */
-};
-
-static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
- VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
- VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
- VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
-};
-
-static int VGAarbiterKeyIndex;
-static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
-static int VGAarbiterGCIndex;
-static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
-
-static int vga_no_arb = 0;
-void
-xf86VGAarbiterInit(void)
-{
- if (pci_device_vgaarb_init() != 0) {
- vga_no_arb = 1;
- xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
- }
-}
-
-void
-xf86VGAarbiterFini(void)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_fini();
-}
-
-void
-xf86VGAarbiterLock(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_set_target(pScrn->vgaDev);
- pci_device_vgaarb_lock();
-}
-
-void
-xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_unlock();
-}
-
-Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
-{
- int vga_count;
- int rsrc_decodes;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (vga_no_arb)
- return TRUE;
-
- pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
- if (vga_count > 1) {
- if (rsrc_decodes) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void
-xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
-{
- struct pci_device *dev;
- EntityPtr pEnt;
-
- if (vga_no_arb)
- return;
-
- pEnt = xf86Entities[pScrn->entityList[0]];
- if (pEnt->bus.type != BUS_PCI)
- return;
-
- dev = pEnt->bus.id.pci;
- pScrn->vgaDev = dev;
-}
-
-void
-xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
-}
-
-Bool
-xf86VGAarbiterWrapFunctions(void)
-{
- ScrnInfoPtr pScrn;
- VGAarbiterScreenPtr pScreenPriv;
- miPointerScreenPtr PointPriv;
- PictureScreenPtr ps;
- ScreenPtr pScreen;
- int vga_count, i;
-
- if (vga_no_arb)
- return FALSE;
-
- /*
- * we need to wrap the arbiter if we have more than
- * one VGA card - hotplug cries.
- */
- pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
- if (vga_count < 2 || !xf86Screens)
- return FALSE;
-
- xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n",
- vga_count);
-
- for (i = 0; i < xf86NumScreens; i++) {
- pScreen = xf86Screens[i]->pScreen;
- ps = GetPictureScreenIfSet(pScreen);
- pScrn = xf86Screens[pScreen->myNum];
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- if (!dixRequestPrivate(VGAarbiterGCKey, sizeof(VGAarbiterGCRec)))
- return FALSE;
-
- if (!(pScreenPriv = xalloc(sizeof(VGAarbiterScreenRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
-
- WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
- WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
- WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
- WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
- WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
- WRAP_SCREEN(GetImage, VGAarbiterGetImage);
- WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
- WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
- WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
- WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
- WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
- WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
- WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
- WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
- WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
- WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
- WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
- WRAP_PICT(Composite,VGAarbiterComposite);
- WRAP_PICT(Glyphs,VGAarbiterGlyphs);
- WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
- WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
- WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
- WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
- WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
- WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
- WRAP_SPRITE;
- }
-
- return TRUE;
-}
-
-/* Screen funcs */
-static Bool
-VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
-{
- Bool val;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- UNWRAP_SCREEN(CreateGC);
- UNWRAP_SCREEN(CloseScreen);
- UNWRAP_SCREEN(GetImage);
- UNWRAP_SCREEN(GetSpans);
- UNWRAP_SCREEN(SourceValidate);
- UNWRAP_SCREEN(CopyWindow);
- UNWRAP_SCREEN(ClearToBackground);
- UNWRAP_SCREEN(SaveScreen);
- UNWRAP_SCREEN(StoreColors);
- UNWRAP_SCREEN(DisplayCursor);
- UNWRAP_SCREEN(RealizeCursor);
- UNWRAP_SCREEN(UnrealizeCursor);
- UNWRAP_SCREEN(RecolorCursor);
- UNWRAP_SCREEN(SetCursorPosition);
- UNWRAP_PICT(Composite);
- UNWRAP_PICT(Glyphs);
- UNWRAP_PICT(CompositeRects);
- UNWRAP_SCREEN_INFO(AdjustFrame);
- UNWRAP_SCREEN_INFO(SwitchMode);
- UNWRAP_SCREEN_INFO(EnterVT);
- UNWRAP_SCREEN_INFO(LeaveVT);
- UNWRAP_SCREEN_INFO(FreeScreen);
- UNWRAP_SPRITE;
-
- xfree ((pointer) pScreenPriv);
- xf86VGAarbiterLock(xf86Screens[i]);
- val = (*pScreen->CloseScreen) (i, pScreen);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- return val;
-}
-
-static void
-VGAarbiterBlockHandler(int i,
- pointer blockData, pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- SCREEN_PROLOG(BlockHandler);
- VGAGet();
- pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
- VGAPut();
- SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
-}
-
-static void
-VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- SCREEN_PROLOG(WakeupHandler);
- VGAGet();
- pScreen->WakeupHandler(i, blockData, result, pReadmask);
- VGAPut();
- SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
-}
-
-static void
-VGAarbiterGetImage (
- DrawablePtr pDrawable,
- int sx, int sy, int w, int h,
- unsigned int format,
- unsigned long planemask,
- char *pdstLine
- )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- SCREEN_PROLOG(GetImage);
-// if (xf86Screens[pScreen->myNum]->vtSema) {
- VGAGet();
-// }
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
- format, planemask, pdstLine);
- VGAPut();
- SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
-}
-
-static void
-VGAarbiterGetSpans (
- DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart
- )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- SCREEN_PROLOG (GetSpans);
- VGAGet();
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
- VGAPut();
- SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
-}
-
-static void
-VGAarbiterSourceValidate (
- DrawablePtr pDrawable,
- int x, int y, int width, int height )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- SCREEN_PROLOG (SourceValidate);
- VGAGet();
- if (pScreen->SourceValidate)
- (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
- VGAPut();
- SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
-}
-
-static void
-VGAarbiterCopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc )
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOG (CopyWindow);
- VGAGet();
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- VGAPut();
- SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
-}
-
-static void
-VGAarbiterClearToBackground (
- WindowPtr pWin,
- int x, int y,
- int w, int h,
- Bool generateExposures )
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOG ( ClearToBackground);
- VGAGet();
- (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
- VGAPut();
- SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
-}
-
-static PixmapPtr
-VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
-{
- PixmapPtr pPix;
-
- SCREEN_PROLOG ( CreatePixmap);
- VGAGet();
- pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
- VGAPut();
- SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
-
- return pPix;
-}
-
-static Bool
-VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
-{
- Bool val;
-
- SCREEN_PROLOG (SaveScreen);
- VGAGet();
- val = (*pScreen->SaveScreen) (pScreen, unblank);
- VGAPut();
- SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
-
- return val;
-}
-
-static void
-VGAarbiterStoreColors (
- ColormapPtr pmap,
- int ndef,
- xColorItem *pdefs)
-{
- ScreenPtr pScreen = pmap->pScreen;
-
- SCREEN_PROLOG (StoreColors);
- VGAGet();
- (*pScreen->StoreColors) (pmap,ndef,pdefs);
- VGAPut();
- SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
-}
-
-static void
-VGAarbiterRecolorCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCurs,
- Bool displayed
- )
-{
- SCREEN_PROLOG (RecolorCursor);
- VGAGet();
- (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
- VGAPut();
- SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
-}
-
-static Bool
-VGAarbiterRealizeCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (RealizeCursor);
- VGAGet();
- val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
- VGAPut();
- SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
- return val;
-}
-
-static Bool
-VGAarbiterUnrealizeCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (UnrealizeCursor);
- VGAGet();
- val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
- VGAPut();
- SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
- return val;
-}
-
-static Bool
-VGAarbiterDisplayCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (DisplayCursor);
- VGAGet();
- val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
- VGAPut();
- SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
- return val;
-}
-
-static Bool
-VGAarbiterSetCursorPosition (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- int x, int y,
- Bool generateEvent)
-{
- Bool val;
-
- SCREEN_PROLOG (SetCursorPosition);
- VGAGet();
- val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
- VGAPut();
- SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
- return val;
-}
-
-static void
-VGAarbiterAdjustFrame(int index, int x, int y, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->AdjustFrame)(index, x, y, flags);
- VGAPut();
-}
-
-static Bool
-VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- Bool val;
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- val = (*pScreenPriv->SwitchMode)(index, mode, flags);
- VGAPut();
- return val;
-}
-
-static Bool
-VGAarbiterEnterVT(int index, int flags)
-{
- Bool val;
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- val = (*pScreenPriv->EnterVT)(index, flags);
- VGAPut();
- return val;
-}
-
-static void
-VGAarbiterLeaveVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->LeaveVT)(index, flags);
- VGAPut();
-}
-
-static void
-VGAarbiterFreeScreen(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->FreeScreen)(index, flags);
- VGAPut();
-}
-
-static Bool
-VGAarbiterCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
- Bool ret;
-
- SCREEN_PROLOG(CreateGC);
- VGAGet();
- ret = (*pScreen->CreateGC)(pGC);
- VGAPut();
- GC_WRAP(pGC);
- SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
-
- return ret;
-}
-
-/* GC funcs */
-static void
-VGAarbiterValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw )
-{
- GC_UNWRAP(pGC);
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterDestroyGC(GCPtr pGC)
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->DestroyGC)(pGC);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterChangeGC (
- GCPtr pGC,
- unsigned long mask)
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterCopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst)
-{
- GC_UNWRAP (pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- GC_WRAP (pGCDst);
-}
-
-static void
-VGAarbiterChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects )
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- GC_UNWRAP (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- GC_WRAP (pgcDst);
-}
-
-static void
-VGAarbiterDestroyClip(GCPtr pGC)
-{
- GC_UNWRAP (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- GC_WRAP (pGC);
-}
-
-/* GC Ops */
-static void
-VGAarbiterFillSpans(
- DrawablePtr pDraw,
- GC *pGC,
- int nInit,
- DDXPointPtr pptInit,
- int *pwidthInit,
- int fSorted )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterSetSpans(
- DrawablePtr pDraw,
- GCPtr pGC,
- char *pcharsrc,
- register DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- int fSorted )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x, int y, int w, int h,
- int leftPad,
- int format,
- char *pImage )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static RegionPtr
-VGAarbiterCopyArea(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty )
-{
- RegionPtr ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->CopyArea)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static RegionPtr
-VGAarbiterCopyPlane(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane )
-{
- RegionPtr ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
- width, height, dstx, dsty, bitPlane);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static void
-VGAarbiterPolyPoint(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- xPoint *pptInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterPolylines(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pptInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolySegment(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyRectangle(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterFillPolygon(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyFillRect(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit)
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyFillArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static int
-VGAarbiterPolyText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars )
-{
- int ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static int
-VGAarbiterPolyText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars )
-{
- int ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static void
-VGAarbiterImageText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterImageText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterImageGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
- nglyph, ppci, pglyphBase);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
- nglyph, ppci, pglyphBase);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPushPixels(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy, int xOrg, int yOrg )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-/* miSpriteFuncs */
-static Bool
-VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static Bool
-VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static void
-VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static void
-VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static Bool
-VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static void
-VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static void
-VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
- PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
- INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(Composite);
-
- VGAGet();
- (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
- yDst, width, height);
- VGAPut();
- PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
-}
-
-static void
-VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(Glyphs);
-
- VGAGet();
- (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
- VGAPut();
- PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
-}
-
-static void
-VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
- xRectangle *rects)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(CompositeRects);
-
- VGAGet();
- (*ps->CompositeRects)(op, pDst, color, nRect, rects);
- VGAPut();
- PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
-}
-#else
-/* dummy functions */
-void xf86VGAarbiterInit(void) {}
-void xf86VGAarbiterFini(void) {}
-
-void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
-void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
-Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
-void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
-void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
-Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
-
-#endif
+/*
+ * This code was stolen from RAC and adapted to control the legacy vga
+ * interface.
+ *
+ *
+ * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "xorg-config.h"
+
+#include "xf86VGAarbiter.h"
+
+#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
+#include "xf86VGAarbiterPriv.h"
+#include "xf86Bus.h"
+#include "xf86Priv.h"
+#include "pciaccess.h"
+
+
+static GCFuncs VGAarbiterGCFuncs = {
+ VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
+ VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
+ VGAarbiterCopyClip
+};
+
+static GCOps VGAarbiterGCOps = {
+ VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
+ VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
+ VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
+ VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
+ VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
+ VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
+ VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
+ {NULL} /* devPrivate */
+};
+
+static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
+ VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
+ VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
+ VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
+};
+
+static int VGAarbiterKeyIndex;
+static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
+static int VGAarbiterGCIndex;
+static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
+
+static int vga_no_arb = 0;
+void
+xf86VGAarbiterInit(void)
+{
+ if (pci_device_vgaarb_init() != 0) {
+ vga_no_arb = 1;
+ xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
+ }
+}
+
+void
+xf86VGAarbiterFini(void)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_fini();
+}
+
+void
+xf86VGAarbiterLock(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_set_target(pScrn->vgaDev);
+ pci_device_vgaarb_lock();
+}
+
+void
+xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_unlock();
+}
+
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
+{
+ int vga_count;
+ int rsrc_decodes;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (vga_no_arb)
+ return TRUE;
+
+ pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
+ if (vga_count > 1) {
+ if (rsrc_decodes) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void
+xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
+{
+ struct pci_device *dev;
+ EntityPtr pEnt;
+
+ if (vga_no_arb)
+ return;
+
+ pEnt = xf86Entities[pScrn->entityList[0]];
+ if (pEnt->bus.type != BUS_PCI)
+ return;
+
+ dev = pEnt->bus.id.pci;
+ pScrn->vgaDev = dev;
+}
+
+void
+xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
+}
+
+Bool
+xf86VGAarbiterWrapFunctions(void)
+{
+ ScrnInfoPtr pScrn;
+ VGAarbiterScreenPtr pScreenPriv;
+ miPointerScreenPtr PointPriv;
+ PictureScreenPtr ps;
+ ScreenPtr pScreen;
+ int vga_count, i;
+
+ if (vga_no_arb)
+ return FALSE;
+
+ /*
+ * we need to wrap the arbiter if we have more than
+ * one VGA card - hotplug cries.
+ */
+ pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
+ if (vga_count < 2 || !xf86Screens)
+ return FALSE;
+
+ xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n",
+ vga_count);
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScreen = xf86Screens[i]->pScreen;
+ ps = GetPictureScreenIfSet(pScreen);
+ pScrn = xf86Screens[pScreen->myNum];
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ if (!dixRequestPrivate(VGAarbiterGCKey, sizeof(VGAarbiterGCRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = malloc(sizeof(VGAarbiterScreenRec))))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
+
+ WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
+ WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
+ WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
+ WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
+ WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
+ WRAP_SCREEN(GetImage, VGAarbiterGetImage);
+ WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
+ WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
+ WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
+ WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
+ WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
+ WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
+ WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
+ WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
+ WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
+ WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
+ WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
+ WRAP_PICT(Composite,VGAarbiterComposite);
+ WRAP_PICT(Glyphs,VGAarbiterGlyphs);
+ WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
+ WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
+ WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
+ WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
+ WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
+ WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
+ WRAP_SPRITE;
+ }
+
+ return TRUE;
+}
+
+/* Screen funcs */
+static Bool
+VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
+{
+ Bool val;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ UNWRAP_SCREEN(CreateGC);
+ UNWRAP_SCREEN(CloseScreen);
+ UNWRAP_SCREEN(GetImage);
+ UNWRAP_SCREEN(GetSpans);
+ UNWRAP_SCREEN(SourceValidate);
+ UNWRAP_SCREEN(CopyWindow);
+ UNWRAP_SCREEN(ClearToBackground);
+ UNWRAP_SCREEN(SaveScreen);
+ UNWRAP_SCREEN(StoreColors);
+ UNWRAP_SCREEN(DisplayCursor);
+ UNWRAP_SCREEN(RealizeCursor);
+ UNWRAP_SCREEN(UnrealizeCursor);
+ UNWRAP_SCREEN(RecolorCursor);
+ UNWRAP_SCREEN(SetCursorPosition);
+ UNWRAP_PICT(Composite);
+ UNWRAP_PICT(Glyphs);
+ UNWRAP_PICT(CompositeRects);
+ UNWRAP_SCREEN_INFO(AdjustFrame);
+ UNWRAP_SCREEN_INFO(SwitchMode);
+ UNWRAP_SCREEN_INFO(EnterVT);
+ UNWRAP_SCREEN_INFO(LeaveVT);
+ UNWRAP_SCREEN_INFO(FreeScreen);
+ UNWRAP_SPRITE;
+
+ free((pointer) pScreenPriv);
+ xf86VGAarbiterLock(xf86Screens[i]);
+ val = (*pScreen->CloseScreen) (i, pScreen);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ return val;
+}
+
+static void
+VGAarbiterBlockHandler(int i,
+ pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ SCREEN_PROLOG(BlockHandler);
+ VGAGet();
+ pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+ VGAPut();
+ SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
+}
+
+static void
+VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ SCREEN_PROLOG(WakeupHandler);
+ VGAGet();
+ pScreen->WakeupHandler(i, blockData, result, pReadmask);
+ VGAPut();
+ SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
+}
+
+static void
+VGAarbiterGetImage (
+ DrawablePtr pDrawable,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_PROLOG(GetImage);
+// if (xf86Screens[pScreen->myNum]->vtSema) {
+ VGAGet();
+// }
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+ VGAPut();
+ SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
+}
+
+static void
+VGAarbiterGetSpans (
+ DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ SCREEN_PROLOG (GetSpans);
+ VGAGet();
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ VGAPut();
+ SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
+}
+
+static void
+VGAarbiterSourceValidate (
+ DrawablePtr pDrawable,
+ int x, int y, int width, int height )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_PROLOG (SourceValidate);
+ VGAGet();
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+ VGAPut();
+ SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
+}
+
+static void
+VGAarbiterCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOG (CopyWindow);
+ VGAGet();
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ VGAPut();
+ SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
+}
+
+static void
+VGAarbiterClearToBackground (
+ WindowPtr pWin,
+ int x, int y,
+ int w, int h,
+ Bool generateExposures )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOG ( ClearToBackground);
+ VGAGet();
+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+ VGAPut();
+ SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
+}
+
+static PixmapPtr
+VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
+{
+ PixmapPtr pPix;
+
+ SCREEN_PROLOG ( CreatePixmap);
+ VGAGet();
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
+ VGAPut();
+ SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
+
+ return pPix;
+}
+
+static Bool
+VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ Bool val;
+
+ SCREEN_PROLOG (SaveScreen);
+ VGAGet();
+ val = (*pScreen->SaveScreen) (pScreen, unblank);
+ VGAPut();
+ SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
+
+ return val;
+}
+
+static void
+VGAarbiterStoreColors (
+ ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+
+ SCREEN_PROLOG (StoreColors);
+ VGAGet();
+ (*pScreen->StoreColors) (pmap,ndef,pdefs);
+ VGAPut();
+ SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
+}
+
+static void
+VGAarbiterRecolorCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed
+ )
+{
+ SCREEN_PROLOG (RecolorCursor);
+ VGAGet();
+ (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
+ VGAPut();
+ SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
+}
+
+static Bool
+VGAarbiterRealizeCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (RealizeCursor);
+ VGAGet();
+ val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterUnrealizeCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (UnrealizeCursor);
+ VGAGet();
+ val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterDisplayCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (DisplayCursor);
+ VGAGet();
+ val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterSetCursorPosition (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ int x, int y,
+ Bool generateEvent)
+{
+ Bool val;
+
+ SCREEN_PROLOG (SetCursorPosition);
+ VGAGet();
+ val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
+ VGAPut();
+ SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
+ return val;
+}
+
+static void
+VGAarbiterAdjustFrame(int index, int x, int y, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->AdjustFrame)(index, x, y, flags);
+ VGAPut();
+}
+
+static Bool
+VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ Bool val;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ val = (*pScreenPriv->SwitchMode)(index, mode, flags);
+ VGAPut();
+ return val;
+}
+
+static Bool
+VGAarbiterEnterVT(int index, int flags)
+{
+ Bool val;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ val = (*pScreenPriv->EnterVT)(index, flags);
+ VGAPut();
+ return val;
+}
+
+static void
+VGAarbiterLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->LeaveVT)(index, flags);
+ VGAPut();
+}
+
+static void
+VGAarbiterFreeScreen(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->FreeScreen)(index, flags);
+ VGAPut();
+}
+
+static Bool
+VGAarbiterCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
+ Bool ret;
+
+ SCREEN_PROLOG(CreateGC);
+ VGAGet();
+ ret = (*pScreen->CreateGC)(pGC);
+ VGAPut();
+ GC_WRAP(pGC);
+ SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
+
+ return ret;
+}
+
+/* GC funcs */
+static void
+VGAarbiterValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ GC_UNWRAP(pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterDestroyGC(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterChangeGC (
+ GCPtr pGC,
+ unsigned long mask)
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ GC_UNWRAP (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ GC_WRAP (pGCDst);
+}
+
+static void
+VGAarbiterChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ GC_UNWRAP (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ GC_WRAP (pgcDst);
+}
+
+static void
+VGAarbiterDestroyClip(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ GC_WRAP (pGC);
+}
+
+/* GC Ops */
+static void
+VGAarbiterFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static RegionPtr
+VGAarbiterCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static RegionPtr
+VGAarbiterCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+VGAarbiterPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit)
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static int
+VGAarbiterPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static int
+VGAarbiterPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+VGAarbiterImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+/* miSpriteFuncs */
+static Bool
+VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static Bool
+VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static void
+VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static void
+VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static Bool
+VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static void
+VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static void
+VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(Composite);
+
+ VGAGet();
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
+ yDst, width, height);
+ VGAPut();
+ PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
+}
+
+static void
+VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
+ GlyphListPtr list, GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(Glyphs);
+
+ VGAGet();
+ (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ VGAPut();
+ PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
+}
+
+static void
+VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(CompositeRects);
+
+ VGAGet();
+ (*ps->CompositeRects)(op, pDst, color, nRect, rects);
+ VGAPut();
+ PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
+}
+#else
+/* dummy functions */
+void xf86VGAarbiterInit(void) {}
+void xf86VGAarbiterFini(void) {}
+
+void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
+void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
+
+#endif
diff --git a/xorg-server/hw/xfree86/common/xf86VidMode.c b/xorg-server/hw/xfree86/common/xf86VidMode.c
index 49b86e73a..08f27b8e4 100644
--- a/xorg-server/hw/xfree86/common/xf86VidMode.c
+++ b/xorg-server/hw/xfree86/common/xf86VidMode.c
@@ -1,667 +1,667 @@
-/*
- * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the VidMode functions required by the extension.
- * These have been added to avoid the need for the higher level extension
- * code to access the private XFree86 data structures directly. Wherever
- * possible this code uses the functions in xf86Mode.c to do the work,
- * so that two version of code that do similar things don't have to be
- * maintained.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-#ifdef XF86VIDMODE
-#include "vidmodeproc.h"
-#include "xf86cmap.h"
-
-static int VidModeKeyIndex;
-static DevPrivateKey VidModeKey;
-static int VidModeCount = 0;
-static Bool VidModeClose(int i, ScreenPtr pScreen);
-
-#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
-
-#endif
-
-Bool
-VidModeExtensionInit(ScreenPtr pScreen)
-{
-#ifdef XF86VIDMODE
- VidModePtr pVidMode;
-
- if (!xf86GetVidModeEnabled()) {
- DebugF("!xf86GetVidModeEnabled()\n");
- return FALSE;
- }
-
- VidModeKey = &VidModeKeyIndex;
-
- if (!dixSetPrivate(&pScreen->devPrivates, VidModeKey,
- xcalloc(sizeof(VidModeRec), 1))) {
- DebugF("xcalloc failed\n");
- return FALSE;
- }
-
- pVidMode = VMPTR(pScreen);
- pVidMode->Flags = 0;
- pVidMode->Next = NULL;
- pVidMode->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = VidModeClose;
- VidModeCount++;
- return TRUE;
-#else
- DebugF("no vidmode extension\n");
- return FALSE;
-#endif
-}
-
-
-#ifdef XF86VIDMODE
-
-static Bool
-VidModeClose(int i, ScreenPtr pScreen)
-{
- VidModePtr pVidMode = VMPTR(pScreen);
-
- /* This shouldn't happen */
- if (!pVidMode)
- return FALSE;
-
- pScreen->CloseScreen = pVidMode->CloseScreen;
-
- if (--VidModeCount == 0) {
- xfree(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
- dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
- VidModeKey = NULL;
- }
- return pScreen->CloseScreen(i, pScreen);
-}
-
-Bool
-VidModeAvailable(int scrnIndex)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
-
- if (VidModeKey == NULL) {
- DebugF("VidModeKey == NULL\n");
- return FALSE;
- }
-
- pScrn = xf86Screens[scrnIndex];
- if (pScrn == NULL) {
- DebugF("pScrn == NULL\n");
- return FALSE;
- }
-
- pVidMode = VMPTR(pScrn->pScreen);
- if (pVidMode)
- return TRUE;
- else {
- DebugF("pVidMode == NULL\n");
- return FALSE;
- }
-}
-
-Bool
-VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (pScrn->currentMode) {
- *mode = (pointer)(pScrn->currentMode);
- *dotClock = pScrn->currentMode->Clock;
-
- return TRUE;
- }
- return FALSE;
-}
-
-int
-VidModeGetDotClock(int scrnIndex, int Clock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- pScrn = xf86Screens[scrnIndex];
- if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
- return Clock;
- else
- return pScrn->clock[Clock];
-}
-
-int
-VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- pScrn = xf86Screens[scrnIndex];
- if (pScrn->progClock){
- *progClock = TRUE;
- return 0;
- } else {
- *progClock = FALSE;
- return pScrn->numClocks;
- }
-}
-
-Bool
-VidModeGetClocks(int scrnIndex, int *Clocks)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (pScrn->progClock)
- return FALSE;
-
- for (i = 0; i < pScrn->numClocks; i++)
- *Clocks++ = pScrn->clock[i];
-
- return TRUE;
-}
-
-
-Bool
-VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pVidMode = VMPTR(pScrn->pScreen);
- pVidMode->First = pScrn->modes;
- pVidMode->Next = pVidMode->First->next;
-
- if (pVidMode->First->status == MODE_OK) {
- *mode = (pointer)(pVidMode->First);
- *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
- return TRUE;
- }
-
- return VidModeGetNextModeline(scrnIndex, mode, dotClock);
-}
-
-Bool
-VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
- DisplayModePtr p;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pVidMode = VMPTR(pScrn->pScreen);
-
- for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
- if (p->status == MODE_OK) {
- pVidMode->Next = p->next;
- *mode = (pointer)p;
- *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-Bool
-VidModeDeleteModeline(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
- return TRUE;
-}
-
-Bool
-VidModeZoomViewport(int scrnIndex, int zoom)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86ZoomViewport(pScrn->pScreen, zoom);
- return TRUE;
-}
-
-Bool
-VidModeSetViewPort(int scrnIndex, int x, int y)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pScrn->frameX0 = min( max(x, 0),
- pScrn->virtualX - pScrn->currentMode->HDisplay );
- pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
- pScrn->frameY0 = min( max(y, 0),
- pScrn->virtualY - pScrn->currentMode->VDisplay );
- pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
- if (pScrn->AdjustFrame != NULL)
- (pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- return TRUE;
-}
-
-Bool
-VidModeGetViewPort(int scrnIndex, int *x, int *y)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *x = pScrn->frameX0;
- *y = pScrn->frameY0;
- return TRUE;
-}
-
-Bool
-VidModeSwitchMode(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
- DisplayModePtr pTmpMode;
- Bool retval;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- /* save in case we fail */
- pTmpMode = pScrn->currentMode;
- /* Force a mode switch */
- pScrn->currentMode = NULL;
- retval = xf86SwitchMode(pScrn->pScreen, mode);
- /* we failed: restore it */
- if (retval == FALSE)
- pScrn->currentMode = pTmpMode;
- return retval;
-}
-
-Bool
-VidModeLockZoom(int scrnIndex, Bool lock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (xf86Info.dontZoom)
- return FALSE;
-
- xf86LockZoom(pScrn->pScreen, lock);
- return TRUE;
-}
-
-Bool
-VidModeGetMonitor(int scrnIndex, pointer *monitor)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *monitor = (pointer)(pScrn->monitor);
-
- return TRUE;
-}
-
-ModeStatus
-VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return MODE_ERROR;
-
- pScrn = xf86Screens[scrnIndex];
-
- return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
-}
-
-ModeStatus
-VidModeCheckModeForDriver(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return MODE_ERROR;
-
- pScrn = xf86Screens[scrnIndex];
-
- return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
-}
-
-void
-VidModeSetCrtcForMode(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
- DisplayModePtr ScreenModes;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return;
-
- /* Ugly hack so that the xf86Mode.c function can be used without change */
- pScrn = xf86Screens[scrnIndex];
- ScreenModes = pScrn->modes;
- pScrn->modes = (DisplayModePtr)mode;
-
- xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
- pScrn->modes = ScreenModes;
- return;
-}
-
-Bool
-VidModeAddModeline(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- ((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */
- ((DisplayModePtr)mode)->status = MODE_OK;
- ((DisplayModePtr)mode)->next = pScrn->modes->next;
- ((DisplayModePtr)mode)->prev = pScrn->modes;
- pScrn->modes->next = (DisplayModePtr)mode;
- if( ((DisplayModePtr)mode)->next != NULL )
- ((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode;
-
- return TRUE;
-}
-
-int
-VidModeGetNumOfModes(int scrnIndex)
-{
- pointer mode = NULL;
- int dotClock= 0, nummodes = 0;
-
- if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
- return nummodes;
-
- do {
- nummodes++;
- if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
- return nummodes;
- } while (TRUE);
-}
-
-Bool
-VidModeSetGamma(int scrnIndex, float red, float green, float blue)
-{
- ScrnInfoPtr pScrn;
- Gamma gamma;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- gamma.red = red;
- gamma.green = green;
- gamma.blue = blue;
- if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
- return FALSE;
- else
- return TRUE;
-}
-
-Bool
-VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *red = pScrn->gamma.red;
- *green = pScrn->gamma.green;
- *blue = pScrn->gamma.blue;
- return TRUE;
-}
-
-Bool
-VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
- return TRUE;
-}
-
-Bool
-VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
- return TRUE;
-}
-
-int
-VidModeGetGammaRampSize(int scrnIndex)
-{
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
-}
-
-pointer
-VidModeCreateMode(void)
-{
- DisplayModePtr mode;
-
- mode = xalloc(sizeof(DisplayModeRec));
- if (mode != NULL) {
- mode->name = "";
- mode->VScan = 1; /* divides refresh rate. default = 1 */
- mode->Private = NULL;
- mode->next = mode;
- mode->prev = mode;
- }
- return mode;
-}
-
-void
-VidModeCopyMode(pointer modefrom, pointer modeto)
-{
- memcpy(modeto, modefrom, sizeof(DisplayModeRec));
-}
-
-
-int
-VidModeGetModeValue(pointer mode, int valtyp)
-{
- int ret = 0;
-
- switch (valtyp) {
- case VIDMODE_H_DISPLAY:
- ret = ((DisplayModePtr) mode)->HDisplay;
- break;
- case VIDMODE_H_SYNCSTART:
- ret = ((DisplayModePtr)mode)->HSyncStart;
- break;
- case VIDMODE_H_SYNCEND:
- ret = ((DisplayModePtr)mode)->HSyncEnd;
- break;
- case VIDMODE_H_TOTAL:
- ret = ((DisplayModePtr)mode)->HTotal;
- break;
- case VIDMODE_H_SKEW:
- ret = ((DisplayModePtr)mode)->HSkew;
- break;
- case VIDMODE_V_DISPLAY:
- ret = ((DisplayModePtr)mode)->VDisplay;
- break;
- case VIDMODE_V_SYNCSTART:
- ret = ((DisplayModePtr)mode)->VSyncStart;
- break;
- case VIDMODE_V_SYNCEND:
- ret = ((DisplayModePtr)mode)->VSyncEnd;
- break;
- case VIDMODE_V_TOTAL:
- ret = ((DisplayModePtr)mode)->VTotal;
- break;
- case VIDMODE_FLAGS:
- ret = ((DisplayModePtr)mode)->Flags;
- break;
- case VIDMODE_CLOCK:
- ret = ((DisplayModePtr)mode)->Clock;
- break;
- }
- return ret;
-}
-
-void
-VidModeSetModeValue(pointer mode, int valtyp, int val)
-{
- switch (valtyp) {
- case VIDMODE_H_DISPLAY:
- ((DisplayModePtr)mode)->HDisplay = val;
- break;
- case VIDMODE_H_SYNCSTART:
- ((DisplayModePtr)mode)->HSyncStart = val;
- break;
- case VIDMODE_H_SYNCEND:
- ((DisplayModePtr)mode)->HSyncEnd = val;
- break;
- case VIDMODE_H_TOTAL:
- ((DisplayModePtr)mode)->HTotal = val;
- break;
- case VIDMODE_H_SKEW:
- ((DisplayModePtr)mode)->HSkew = val;
- break;
- case VIDMODE_V_DISPLAY:
- ((DisplayModePtr)mode)->VDisplay = val;
- break;
- case VIDMODE_V_SYNCSTART:
- ((DisplayModePtr)mode)->VSyncStart = val;
- break;
- case VIDMODE_V_SYNCEND:
- ((DisplayModePtr)mode)->VSyncEnd = val;
- break;
- case VIDMODE_V_TOTAL:
- ((DisplayModePtr)mode)->VTotal = val;
- break;
- case VIDMODE_FLAGS:
- ((DisplayModePtr)mode)->Flags = val;
- break;
- case VIDMODE_CLOCK:
- ((DisplayModePtr)mode)->Clock = val;
- break;
- }
- return;
-}
-
-vidMonitorValue
-VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
-{
- vidMonitorValue ret;
-
- switch (valtyp) {
- case VIDMODE_MON_VENDOR:
- ret.ptr = (((MonPtr)monitor)->vendor);
- break;
- case VIDMODE_MON_MODEL:
- ret.ptr = (((MonPtr)monitor)->model);
- break;
- case VIDMODE_MON_NHSYNC:
- ret.i = ((MonPtr)monitor)->nHsync;
- break;
- case VIDMODE_MON_NVREFRESH:
- ret.i = ((MonPtr)monitor)->nVrefresh;
- break;
- case VIDMODE_MON_HSYNC_LO:
- ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
- break;
- case VIDMODE_MON_HSYNC_HI:
- ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
- break;
- case VIDMODE_MON_VREFRESH_LO:
- ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
- break;
- case VIDMODE_MON_VREFRESH_HI:
- ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
- break;
- }
- return ret;
-}
-
-
-#endif /* XF86VIDMODE */
+/*
+ * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the VidMode functions required by the extension.
+ * These have been added to avoid the need for the higher level extension
+ * code to access the private XFree86 data structures directly. Wherever
+ * possible this code uses the functions in xf86Mode.c to do the work,
+ * so that two version of code that do similar things don't have to be
+ * maintained.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#ifdef XF86VIDMODE
+#include "vidmodeproc.h"
+#include "xf86cmap.h"
+
+static int VidModeKeyIndex;
+static DevPrivateKey VidModeKey;
+static int VidModeCount = 0;
+static Bool VidModeClose(int i, ScreenPtr pScreen);
+
+#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
+
+#endif
+
+Bool
+VidModeExtensionInit(ScreenPtr pScreen)
+{
+#ifdef XF86VIDMODE
+ VidModePtr pVidMode;
+
+ if (!xf86GetVidModeEnabled()) {
+ DebugF("!xf86GetVidModeEnabled()\n");
+ return FALSE;
+ }
+
+ VidModeKey = &VidModeKeyIndex;
+
+ if (!dixSetPrivate(&pScreen->devPrivates, VidModeKey,
+ calloc(sizeof(VidModeRec), 1))) {
+ DebugF("xcalloc failed\n");
+ return FALSE;
+ }
+
+ pVidMode = VMPTR(pScreen);
+ pVidMode->Flags = 0;
+ pVidMode->Next = NULL;
+ pVidMode->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = VidModeClose;
+ VidModeCount++;
+ return TRUE;
+#else
+ DebugF("no vidmode extension\n");
+ return FALSE;
+#endif
+}
+
+
+#ifdef XF86VIDMODE
+
+static Bool
+VidModeClose(int i, ScreenPtr pScreen)
+{
+ VidModePtr pVidMode = VMPTR(pScreen);
+
+ /* This shouldn't happen */
+ if (!pVidMode)
+ return FALSE;
+
+ pScreen->CloseScreen = pVidMode->CloseScreen;
+
+ if (--VidModeCount == 0) {
+ free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
+ dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
+ VidModeKey = NULL;
+ }
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+Bool
+VidModeAvailable(int scrnIndex)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+
+ if (VidModeKey == NULL) {
+ DebugF("VidModeKey == NULL\n");
+ return FALSE;
+ }
+
+ pScrn = xf86Screens[scrnIndex];
+ if (pScrn == NULL) {
+ DebugF("pScrn == NULL\n");
+ return FALSE;
+ }
+
+ pVidMode = VMPTR(pScrn->pScreen);
+ if (pVidMode)
+ return TRUE;
+ else {
+ DebugF("pVidMode == NULL\n");
+ return FALSE;
+ }
+}
+
+Bool
+VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (pScrn->currentMode) {
+ *mode = (pointer)(pScrn->currentMode);
+ *dotClock = pScrn->currentMode->Clock;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+VidModeGetDotClock(int scrnIndex, int Clock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ pScrn = xf86Screens[scrnIndex];
+ if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
+ return Clock;
+ else
+ return pScrn->clock[Clock];
+}
+
+int
+VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ pScrn = xf86Screens[scrnIndex];
+ if (pScrn->progClock){
+ *progClock = TRUE;
+ return 0;
+ } else {
+ *progClock = FALSE;
+ return pScrn->numClocks;
+ }
+}
+
+Bool
+VidModeGetClocks(int scrnIndex, int *Clocks)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (pScrn->progClock)
+ return FALSE;
+
+ for (i = 0; i < pScrn->numClocks; i++)
+ *Clocks++ = pScrn->clock[i];
+
+ return TRUE;
+}
+
+
+Bool
+VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pVidMode = VMPTR(pScrn->pScreen);
+ pVidMode->First = pScrn->modes;
+ pVidMode->Next = pVidMode->First->next;
+
+ if (pVidMode->First->status == MODE_OK) {
+ *mode = (pointer)(pVidMode->First);
+ *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
+ return TRUE;
+ }
+
+ return VidModeGetNextModeline(scrnIndex, mode, dotClock);
+}
+
+Bool
+VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+ DisplayModePtr p;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pVidMode = VMPTR(pScrn->pScreen);
+
+ for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
+ if (p->status == MODE_OK) {
+ pVidMode->Next = p->next;
+ *mode = (pointer)p;
+ *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+Bool
+VidModeDeleteModeline(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
+ return TRUE;
+}
+
+Bool
+VidModeZoomViewport(int scrnIndex, int zoom)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86ZoomViewport(pScrn->pScreen, zoom);
+ return TRUE;
+}
+
+Bool
+VidModeSetViewPort(int scrnIndex, int x, int y)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pScrn->frameX0 = min( max(x, 0),
+ pScrn->virtualX - pScrn->currentMode->HDisplay );
+ pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
+ pScrn->frameY0 = min( max(y, 0),
+ pScrn->virtualY - pScrn->currentMode->VDisplay );
+ pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
+ if (pScrn->AdjustFrame != NULL)
+ (pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ return TRUE;
+}
+
+Bool
+VidModeGetViewPort(int scrnIndex, int *x, int *y)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *x = pScrn->frameX0;
+ *y = pScrn->frameY0;
+ return TRUE;
+}
+
+Bool
+VidModeSwitchMode(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+ DisplayModePtr pTmpMode;
+ Bool retval;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ /* save in case we fail */
+ pTmpMode = pScrn->currentMode;
+ /* Force a mode switch */
+ pScrn->currentMode = NULL;
+ retval = xf86SwitchMode(pScrn->pScreen, mode);
+ /* we failed: restore it */
+ if (retval == FALSE)
+ pScrn->currentMode = pTmpMode;
+ return retval;
+}
+
+Bool
+VidModeLockZoom(int scrnIndex, Bool lock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (xf86Info.dontZoom)
+ return FALSE;
+
+ xf86LockZoom(pScrn->pScreen, lock);
+ return TRUE;
+}
+
+Bool
+VidModeGetMonitor(int scrnIndex, pointer *monitor)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *monitor = (pointer)(pScrn->monitor);
+
+ return TRUE;
+}
+
+ModeStatus
+VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return MODE_ERROR;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
+}
+
+ModeStatus
+VidModeCheckModeForDriver(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return MODE_ERROR;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
+}
+
+void
+VidModeSetCrtcForMode(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+ DisplayModePtr ScreenModes;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return;
+
+ /* Ugly hack so that the xf86Mode.c function can be used without change */
+ pScrn = xf86Screens[scrnIndex];
+ ScreenModes = pScrn->modes;
+ pScrn->modes = (DisplayModePtr)mode;
+
+ xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
+ pScrn->modes = ScreenModes;
+ return;
+}
+
+Bool
+VidModeAddModeline(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ ((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */
+ ((DisplayModePtr)mode)->status = MODE_OK;
+ ((DisplayModePtr)mode)->next = pScrn->modes->next;
+ ((DisplayModePtr)mode)->prev = pScrn->modes;
+ pScrn->modes->next = (DisplayModePtr)mode;
+ if( ((DisplayModePtr)mode)->next != NULL )
+ ((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode;
+
+ return TRUE;
+}
+
+int
+VidModeGetNumOfModes(int scrnIndex)
+{
+ pointer mode = NULL;
+ int dotClock= 0, nummodes = 0;
+
+ if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
+ return nummodes;
+
+ do {
+ nummodes++;
+ if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
+ return nummodes;
+ } while (TRUE);
+}
+
+Bool
+VidModeSetGamma(int scrnIndex, float red, float green, float blue)
+{
+ ScrnInfoPtr pScrn;
+ Gamma gamma;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ gamma.red = red;
+ gamma.green = green;
+ gamma.blue = blue;
+ if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+Bool
+VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *red = pScrn->gamma.red;
+ *green = pScrn->gamma.green;
+ *blue = pScrn->gamma.blue;
+ return TRUE;
+}
+
+Bool
+VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
+ return TRUE;
+}
+
+Bool
+VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
+ return TRUE;
+}
+
+int
+VidModeGetGammaRampSize(int scrnIndex)
+{
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
+}
+
+pointer
+VidModeCreateMode(void)
+{
+ DisplayModePtr mode;
+
+ mode = malloc(sizeof(DisplayModeRec));
+ if (mode != NULL) {
+ mode->name = "";
+ mode->VScan = 1; /* divides refresh rate. default = 1 */
+ mode->Private = NULL;
+ mode->next = mode;
+ mode->prev = mode;
+ }
+ return mode;
+}
+
+void
+VidModeCopyMode(pointer modefrom, pointer modeto)
+{
+ memcpy(modeto, modefrom, sizeof(DisplayModeRec));
+}
+
+
+int
+VidModeGetModeValue(pointer mode, int valtyp)
+{
+ int ret = 0;
+
+ switch (valtyp) {
+ case VIDMODE_H_DISPLAY:
+ ret = ((DisplayModePtr) mode)->HDisplay;
+ break;
+ case VIDMODE_H_SYNCSTART:
+ ret = ((DisplayModePtr)mode)->HSyncStart;
+ break;
+ case VIDMODE_H_SYNCEND:
+ ret = ((DisplayModePtr)mode)->HSyncEnd;
+ break;
+ case VIDMODE_H_TOTAL:
+ ret = ((DisplayModePtr)mode)->HTotal;
+ break;
+ case VIDMODE_H_SKEW:
+ ret = ((DisplayModePtr)mode)->HSkew;
+ break;
+ case VIDMODE_V_DISPLAY:
+ ret = ((DisplayModePtr)mode)->VDisplay;
+ break;
+ case VIDMODE_V_SYNCSTART:
+ ret = ((DisplayModePtr)mode)->VSyncStart;
+ break;
+ case VIDMODE_V_SYNCEND:
+ ret = ((DisplayModePtr)mode)->VSyncEnd;
+ break;
+ case VIDMODE_V_TOTAL:
+ ret = ((DisplayModePtr)mode)->VTotal;
+ break;
+ case VIDMODE_FLAGS:
+ ret = ((DisplayModePtr)mode)->Flags;
+ break;
+ case VIDMODE_CLOCK:
+ ret = ((DisplayModePtr)mode)->Clock;
+ break;
+ }
+ return ret;
+}
+
+void
+VidModeSetModeValue(pointer mode, int valtyp, int val)
+{
+ switch (valtyp) {
+ case VIDMODE_H_DISPLAY:
+ ((DisplayModePtr)mode)->HDisplay = val;
+ break;
+ case VIDMODE_H_SYNCSTART:
+ ((DisplayModePtr)mode)->HSyncStart = val;
+ break;
+ case VIDMODE_H_SYNCEND:
+ ((DisplayModePtr)mode)->HSyncEnd = val;
+ break;
+ case VIDMODE_H_TOTAL:
+ ((DisplayModePtr)mode)->HTotal = val;
+ break;
+ case VIDMODE_H_SKEW:
+ ((DisplayModePtr)mode)->HSkew = val;
+ break;
+ case VIDMODE_V_DISPLAY:
+ ((DisplayModePtr)mode)->VDisplay = val;
+ break;
+ case VIDMODE_V_SYNCSTART:
+ ((DisplayModePtr)mode)->VSyncStart = val;
+ break;
+ case VIDMODE_V_SYNCEND:
+ ((DisplayModePtr)mode)->VSyncEnd = val;
+ break;
+ case VIDMODE_V_TOTAL:
+ ((DisplayModePtr)mode)->VTotal = val;
+ break;
+ case VIDMODE_FLAGS:
+ ((DisplayModePtr)mode)->Flags = val;
+ break;
+ case VIDMODE_CLOCK:
+ ((DisplayModePtr)mode)->Clock = val;
+ break;
+ }
+ return;
+}
+
+vidMonitorValue
+VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
+{
+ vidMonitorValue ret;
+
+ switch (valtyp) {
+ case VIDMODE_MON_VENDOR:
+ ret.ptr = (((MonPtr)monitor)->vendor);
+ break;
+ case VIDMODE_MON_MODEL:
+ ret.ptr = (((MonPtr)monitor)->model);
+ break;
+ case VIDMODE_MON_NHSYNC:
+ ret.i = ((MonPtr)monitor)->nHsync;
+ break;
+ case VIDMODE_MON_NVREFRESH:
+ ret.i = ((MonPtr)monitor)->nVrefresh;
+ break;
+ case VIDMODE_MON_HSYNC_LO:
+ ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
+ break;
+ case VIDMODE_MON_HSYNC_HI:
+ ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
+ break;
+ case VIDMODE_MON_VREFRESH_LO:
+ ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
+ break;
+ case VIDMODE_MON_VREFRESH_HI:
+ ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
+ break;
+ }
+ return ret;
+}
+
+
+#endif /* XF86VIDMODE */
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index a1a5527f4..f1096f1a5 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -1,1284 +1,1284 @@
-/*
- * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
- *
- * 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 Frederic Lepied not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Frederic Lepied makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL FREDERIC LEPIED 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.
- *
- */
-/*
- * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xmd.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/Xatom.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86Xinput.h"
-#include "XIstubs.h"
-#include "xf86Optrec.h"
-#include "xf86Parser.h"
-#include "mipointer.h"
-#include "xf86InPriv.h"
-#include "compiler.h"
-#include "extinit.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
-#include "exevents.h" /* AddInputDevice */
-#include "exglobals.h"
-#include "eventstr.h"
-
-#include <string.h> /* InputClassMatches */
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#endif
-
-#include "extnsionst.h"
-
-#include "windowstr.h" /* screenIsSaved */
-
-#include <stdarg.h>
-#include <stdint.h> /* for int64_t */
-
-#include <X11/Xpoll.h>
-
-#include "mi.h"
-
-#include <ptrveloc.h> /* dix pointer acceleration */
-#include <xserver-properties.h>
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#include "xkbsrv.h"
-
-#include "os.h"
-
-EventListPtr xf86Events = NULL;
-
-/**
- * Eval config and modify DeviceVelocityRec accordingly
- */
-static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
- DeviceVelocityPtr s)
-{
- int tempi;
- float tempf;
- Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
- Atom prop;
-
- if(!s)
- return;
-
- /* common settings (available via device properties) */
- tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- /* select profile by number */
- tempi = xf86SetIntOption(list, "AccelerationProfile",
- s->statistics.profile_number);
-
- prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
- if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
- PropModeReplace, 1, &tempi, FALSE) == Success) {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
- tempi);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
- devname, tempi);
- }
-
- /* set scaling */
- tempf = xf86SetRealOption(list, "ExpectedRate", 0);
- prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
- if (tempf > 0) {
- tempf = 1000.0 / tempf;
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- } else {
- tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
- if (tempi > 1)
- InitTrackers(s, tempi);
-
- s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
- s->initial_range);
-
- s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
-
- tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
- if (tempf >= 0) {
- xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
- devname, tempf*100.0);
- s->max_rel_diff = tempf;
- }
-
- /* Configure softening. If const deceleration is used, this is expected
- * to provide better subpixel information so we enable
- * softening by default only if ConstantDeceleration is not used
- */
- s->use_softening = xf86SetBoolOption(list, "Softening",
- s->const_acceleration == 1.0);
-
- s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
- s->average_accel);
-
- s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
-}
-
-static void
-ApplyAccelerationSettings(DeviceIntPtr dev){
- int scheme, i;
- DeviceVelocityPtr pVel;
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
- char* schemeStr;
-
- if (dev->valuator && dev->ptrfeed) {
- schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
-
- scheme = dev->valuator->accelScheme.number;
-
- if (!xf86NameCmp(schemeStr, "predictable"))
- scheme = PtrAccelPredictable;
-
- if (!xf86NameCmp(schemeStr, "lightweight"))
- scheme = PtrAccelLightweight;
-
- if (!xf86NameCmp(schemeStr, "none"))
- scheme = PtrAccelNoOp;
-
- /* reinit scheme if needed */
- if (dev->valuator->accelScheme.number != scheme) {
- if (dev->valuator->accelScheme.AccelCleanupProc) {
- dev->valuator->accelScheme.AccelCleanupProc(dev);
- }
-
- if (InitPointerAccelerationScheme(dev, scheme)) {
- xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
- local->name, schemeStr, scheme);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
- local->name, schemeStr);
- scheme = dev->valuator->accelScheme.number;
- }
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
- local->name, scheme);
- }
-
- xfree(schemeStr);
-
- /* process special configuration */
- switch (scheme) {
- case PtrAccelPredictable:
- pVel = GetDevicePredictableAccelData(dev);
- ProcessVelocityConfiguration (dev, local->name, local->options,
- pVel);
- break;
- }
-
- i = xf86SetIntOption(local->options, "AccelerationNumerator",
- dev->ptrfeed->ctrl.num);
- if (i >= 0)
- dev->ptrfeed->ctrl.num = i;
-
- i = xf86SetIntOption(local->options, "AccelerationDenominator",
- dev->ptrfeed->ctrl.den);
- if (i > 0)
- dev->ptrfeed->ctrl.den = i;
-
- i = xf86SetIntOption(local->options, "AccelerationThreshold",
- dev->ptrfeed->ctrl.threshold);
- if (i >= 0)
- dev->ptrfeed->ctrl.threshold = i;
-
- /* mostly a no-op anyway */
- (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
-
- xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
- local->name, ((float)dev->ptrfeed->ctrl.num)/
- ((float)dev->ptrfeed->ctrl.den));
- xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
- local->name, dev->ptrfeed->ctrl.threshold);
- }
-}
-
-static Bool
-xf86SendDragEvents(DeviceIntPtr device)
-{
- LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
-
- if (device->button && device->button->buttonsDown > 0)
- return (local->flags & XI86_SEND_DRAG_EVENTS);
- else
- return (TRUE);
-}
-
-/***********************************************************************
- *
- * xf86ProcessCommonOptions --
- *
- * Process global options.
- *
- ***********************************************************************
- */
-void
-xf86ProcessCommonOptions(LocalDevicePtr local,
- pointer list)
-{
- if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
- !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
- !xf86SetBoolOption(list, "CorePointer", 1) ||
- !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
- xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
- } else {
- local->flags |= XI86_ALWAYS_CORE;
- xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
- }
-
- if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
- local->flags |= XI86_SEND_DRAG_EVENTS;
- } else {
- xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
- }
-
- /* Backwards compatibility. */
- local->history_size = GetMotionHistorySize();
-}
-
-/***********************************************************************
- *
- * xf86ActivateDevice --
- *
- * Initialize an input device.
- *
- * Returns TRUE on success, or FALSE otherwise.
- ***********************************************************************
- */
-int
-xf86ActivateDevice(LocalDevicePtr local)
-{
- DeviceIntPtr dev;
-
- if (local->flags & XI86_CONFIGURED) {
- dev = AddInputDevice(serverClient, local->device_control, TRUE);
-
- if (dev == NULL)
- {
- xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
- local->name);
- local->dev = NULL;
- return FALSE;
- }
-
- local->atom = MakeAtom(local->type_name,
- strlen(local->type_name),
- TRUE);
- AssignTypeAndName(dev, local->atom, local->name);
- dev->public.devicePrivate = (pointer) local;
- local->dev = dev;
-
- dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
- dev->type = SLAVE;
- dev->spriteInfo->spriteOwner = FALSE;
-
- dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
- dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-
- RegisterOtherDevice(dev);
- XkbSetExtension(dev, ProcessKeyboardEvent);
-
- if (serverGeneration == 1)
- xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
- local->name, local->type_name);
- }
-
- return TRUE;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXOpenDevice
- *
- * This is the implementation-dependent routine to open an input device.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them. Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request. This entry point is for the latter type of
- * implementation.
- *
- * If the physical device is not already open, do it here. In this case,
- * you need to keep track of the fact that one or more clients has the
- * device open, and physically close it when the last client that has
- * it open does an XCloseDevice.
- *
- * The default implementation is to do nothing (assume all input devices
- * are opened during X server initialization and kept open).
- *
- ***********************************************************************
- */
-
-void
-OpenInputDevice(DeviceIntPtr dev,
- ClientPtr client,
- int *status)
-{
- if (!dev->inited)
- ActivateDevice(dev, TRUE);
-
- *status = Success;
-}
-
-void
-CloseInputDevice(DeviceIntPtr dev,
- ClientPtr client)
-{
-}
-
-/****************************************************************************
- *
- * Caller: ProcXSetDeviceMode
- *
- * Change the mode of an extension device.
- * This function is used to change the mode of a device from reporting
- * relative motion to reporting absolute positional information, and
- * vice versa.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
-{
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
-
- if (local->switch_mode) {
- return (*local->switch_mode)(client, dev, mode);
- }
- else
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXSetDeviceValuators
- *
- * Set the value of valuators on an extension input device.
- * This function is used to set the initial value of valuators on
- * those input devices that are capable of reporting either relative
- * motion or an absolute position, and allow an initial position to be set.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
- int first_valuator, int num_valuators)
-{
- LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
-
- if (local->set_device_valuators)
- return (*local->set_device_valuators)(local, valuators, first_valuator,
- num_valuators);
-
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXChangeDeviceControl
- *
- * Change the specified device controls on an extension input device.
- *
- ***********************************************************************
- */
-
-int
-ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
-{
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
-
- if (!local->control_proc) {
- switch (control->control) {
- case DEVICE_CORE:
- return BadMatch;
- case DEVICE_RESOLUTION:
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- case DEVICE_ENABLE:
- return Success;
- default:
- return BadMatch;
- }
- }
- else {
- return (*local->control_proc)(local, control);
- }
-}
-
-void
-AddOtherInputDevices(void)
-{
-}
-
-/*
- * Classes without any Match statements match all devices. Otherwise, all
- * statements must match.
- */
-static Bool
-InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
-{
- char **cur;
- Bool match;
-
- if (iclass->match_product) {
- if (!attrs->product)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_product, match = FALSE; *cur; cur++)
- if (strstr(attrs->product, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_vendor) {
- if (!attrs->vendor)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_vendor, match = FALSE; *cur; cur++)
- if (strstr(attrs->vendor, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_device) {
- if (!attrs->device)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_device, match = FALSE; *cur; cur++)
-#ifdef HAVE_FNMATCH_H
- if (fnmatch(*cur, attrs->device, FNM_PATHNAME) == 0) {
-#else
- if (strstr(attrs->device, *cur)) {
-#endif
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_tag) {
- if (!attrs->tags)
- return FALSE;
-
- for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
- const char *tag;
- for(tag = *attrs->tags; *tag; tag++) {
- if (!strcmp(tag, *cur)) {
- match = TRUE;
- break;
- }
- }
- }
-
- if (!match)
- return FALSE;
- }
-
- if (iclass->is_keyboard.set &&
- iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
- return FALSE;
- if (iclass->is_pointer.set &&
- iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
- return FALSE;
- if (iclass->is_joystick.set &&
- iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
- return FALSE;
- if (iclass->is_tablet.set &&
- iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
- return FALSE;
- if (iclass->is_touchpad.set &&
- iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
- return FALSE;
- if (iclass->is_touchscreen.set &&
- iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
- return FALSE;
- return TRUE;
-}
-
-/*
- * Merge in any InputClass configurations. Options in each InputClass
- * section have more priority than the original device configuration as
- * well as any previous InputClass sections.
- */
-static int
-MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- XF86OptionPtr classopts, mergedopts = NULL;
- char *classdriver = NULL;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, attrs))
- continue;
-
- /* Collect class options and merge over previous classes */
- xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
- idev->identifier, cl->identifier);
- if (cl->driver)
- classdriver = cl->driver;
- classopts = xf86optionListDup(cl->option_lst);
- mergedopts = xf86optionListMerge(mergedopts, classopts);
- }
-
- /* Apply options to device with InputClass settings preferred. */
- if (classdriver) {
- xfree(idev->driver);
- idev->driver = xstrdup(classdriver);
- if (!idev->driver) {
- xf86Msg(X_ERROR, "Failed to allocate memory while merging "
- "InputClass configuration");
- return BadAlloc;
- }
- mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
- }
- idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
-
- return Success;
-}
-
-/*
- * Iterate the list of classes and look for Option "Ignore". Return the
- * value of the last matching class and holler when returning TRUE.
- */
-static Bool
-IgnoreInputClass(IDevPtr idev, InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- Bool ignore = FALSE;
- const char *ignore_class;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, attrs))
- continue;
- if (xf86findOption(cl->option_lst, "Ignore")) {
- ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
- ignore_class = cl->identifier;
- }
- }
-
- if (ignore)
- xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
- idev->identifier, ignore_class);
- return ignore;
-}
-
-/**
- * Create a new input device, activate and enable it.
- *
- * Possible return codes:
- * BadName .. a bad driver name was supplied.
- * BadImplementation ... The driver does not have a PreInit function. This
- * is a driver bug.
- * BadMatch .. device initialization failed.
- * BadAlloc .. too many input devices
- *
- * @param idev The device, already set up with identifier, driver, and the
- * options.
- * @param pdev Pointer to the new device, if Success was reported.
- * @param enable Enable the device after activating it.
- *
- * @return Success or an error code
- */
-_X_INTERNAL int
-xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
-{
- InputDriverPtr drv = NULL;
- InputInfoPtr pInfo = NULL;
- DeviceIntPtr dev = NULL;
- int rval;
-
- /* Memory leak for every attached device if we don't
- * test if the module is already loaded first */
- drv = xf86LookupInputDriver(idev->driver);
- if (!drv)
- if (xf86LoadOneModule(idev->driver, NULL))
- drv = xf86LookupInputDriver(idev->driver);
- if (!drv) {
- xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver);
- rval = BadName;
- goto unwind;
- }
-
- if (!drv->PreInit) {
- xf86Msg(X_ERROR,
- "Input driver `%s' has no PreInit function (ignoring)\n",
- drv->driverName);
- rval = BadImplementation;
- goto unwind;
- }
-
- pInfo = drv->PreInit(drv, idev, 0);
-
- if (!pInfo) {
- xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
- else if (!(pInfo->flags & XI86_CONFIGURED)) {
- xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
- idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
-
- if (!xf86ActivateDevice(pInfo))
- {
- rval = BadAlloc;
- goto unwind;
- }
-
- dev = pInfo->dev;
- rval = ActivateDevice(dev, TRUE);
- if (rval != Success)
- {
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
- RemoveDevice(dev, TRUE);
- goto unwind;
- }
-
- /* Enable it if it's properly initialised and we're currently in the VT */
- if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
- {
- EnableDevice(dev, TRUE);
- if (!dev->enabled)
- {
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
- /* send enter/leave event, update sprite window */
- CheckMotion(NULL, dev);
- }
-
- *pdev = dev;
- return Success;
-
-unwind:
- if(pInfo) {
- if(drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
- }
- return rval;
-}
-
-int
-NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
- DeviceIntPtr *pdev)
-{
- IDevRec *idev = NULL;
- InputOption *option = NULL;
- int rval = Success;
- int is_auto = 0;
-
- idev = xcalloc(sizeof(*idev), 1);
- if (!idev)
- return BadAlloc;
-
- for (option = options; option; option = option->next) {
- if (strcasecmp(option->key, "driver") == 0) {
- if (idev->driver) {
- rval = BadRequest;
- goto unwind;
- }
- idev->driver = xstrdup(option->value);
- if (!idev->driver) {
- rval = BadAlloc;
- goto unwind;
- }
- }
-
- if (strcasecmp(option->key, "name") == 0 ||
- strcasecmp(option->key, "identifier") == 0) {
- if (idev->identifier) {
- rval = BadRequest;
- goto unwind;
- }
- idev->identifier = xstrdup(option->value);
- if (!idev->identifier) {
- rval = BadAlloc;
- goto unwind;
- }
- }
-
- if (strcmp(option->key, "_source") == 0 &&
- (strcmp(option->value, "server/hal") == 0 ||
- strcmp(option->value, "server/udev") == 0)) {
- is_auto = 1;
- if (!xf86Info.autoAddDevices) {
- rval = BadMatch;
- goto unwind;
- }
- }
- }
-
- for (option = options; option; option = option->next) {
- /* Steal option key/value strings from the provided list.
- * We need those strings, the InputOption list doesn't. */
- idev->commonOptions = xf86addNewOption(idev->commonOptions,
- option->key, option->value);
- option->key = NULL;
- option->value = NULL;
- }
-
- /* Apply InputClass settings */
- if (attrs) {
- if (IgnoreInputClass(idev, attrs)) {
- rval = BadIDChoice;
- goto unwind;
- }
-
- rval = MergeInputClasses(idev, attrs);
- if (rval != Success)
- goto unwind;
- }
-
- if (!idev->driver || !idev->identifier) {
- xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
- rval = BadRequest;
- goto unwind;
- }
-
- if (!idev->identifier) {
- xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
- return BadMatch;
- }
-
- rval = xf86NewInputDevice(idev, pdev,
- (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
- if (rval == Success)
- return Success;
-
-unwind:
- if (is_auto && !xf86Info.autoAddDevices)
- xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
- if(idev->driver)
- xfree(idev->driver);
- if(idev->identifier)
- xfree(idev->identifier);
- xf86optionListFree(idev->commonOptions);
- xfree(idev);
- return rval;
-}
-
-void
-DeleteInputDeviceRequest(DeviceIntPtr pDev)
-{
- LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
- InputDriverPtr drv = NULL;
- IDevRec *idev = NULL;
- IDevPtr *it;
- Bool isMaster = IsMaster(pDev);
-
- if (pInfo) /* need to get these before RemoveDevice */
- {
- drv = pInfo->drv;
- idev = pInfo->conf_idev;
- }
-
- OsBlockSignals();
- RemoveDevice(pDev, TRUE);
-
- if (!isMaster && pInfo != NULL)
- {
- if(drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
-
- /* devices added through HAL aren't in the config layout */
- it = xf86ConfigLayout.inputs;
- while(*it && *it != idev)
- it++;
-
- if (!(*it)) /* end of list, not in the layout */
- {
- xfree(idev->driver);
- xfree(idev->identifier);
- xf86optionListFree(idev->commonOptions);
- xfree(idev);
- }
- }
- OsReleaseSignals();
-}
-
-/*
- * convenient functions to post events
- */
-
-void
-xf86PostMotionEvent(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- static int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
-}
-
-void
-xf86PostMotionEventP(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
- Bool drag = xf86SendDragEvents(device);
- DeviceEvent *event;
- int flags = 0;
-
-#if XFreeXDGA
- int index;
- int dx = 0, dy = 0;
-#endif
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-
-#if XFreeXDGA
- /* The evdev driver may not always send all axes across. */
- if (num_valuators >= 1 && first_valuator <= 1) {
- if (miPointerGetScreen(device)) {
- index = miPointerGetScreen(device)->myNum;
- if (first_valuator == 0)
- {
- dx = valuators[0];
- if (is_absolute)
- dx -= device->last.valuators[0];
- }
-
- if (first_valuator == 1 || num_valuators >= 2)
- {
- dy = valuators[1 - first_valuator];
- if (is_absolute)
- dy -= device->last.valuators[1];
- }
-
- if (DGAStealMotionEvent(device, index, dx, dy))
- return;
- }
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
- flags, first_valuator, num_valuators,
- valuators);
-
- for (i = 0; i < nevents; i++) {
- event = (DeviceEvent*)((xf86Events + i)->event);
- /* Don't post core motion events for devices not registered to send
- * drag events. */
- if (event->header == ET_Internal &&
- (event->type != ET_Motion || drag)) {
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
- }
- }
-}
-
-void
-xf86PostProximityEvent(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i;
- int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostProximityEventP(device, is_in, first_valuator, num_valuators,
- valuators);
-
-}
-
-void
-xf86PostProximityEventP(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i, nevents;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- nevents = GetProximityEvents(xf86Events, device,
- is_in ? ProximityIn : ProximityOut,
- first_valuator, num_valuators, valuators);
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostButtonEvent(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int valuators[MAX_VALUATORS];
- int i = 0;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostButtonEventP(device, is_absolute, button, is_down, first_valuator,
- num_valuators, valuators);
-
-}
-
-void
-xf86PostButtonEventP(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
- int flags = 0;
-
-#if XFreeXDGA
- int index;
-#endif
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-
-#if XFreeXDGA
- if (miPointerGetScreen(device)) {
- index = miPointerGetScreen(device)->myNum;
- if (DGAStealButtonEvent(device, index, button, is_down))
- return;
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device,
- is_down ? ButtonPress : ButtonRelease, button,
- flags, first_valuator, num_valuators, valuators);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostKeyEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- static int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostKeyEventP(device, key_code, is_down, is_absolute, first_valuator,
- num_valuators, valuators);
-
-}
-
-void
-xf86PostKeyEventP(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute) {
- nevents = GetKeyboardValuatorEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code, first_valuator,
- num_valuators, valuators);
- }
- else {
- nevents = GetKeyboardEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code);
- }
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-}
-
-void
-xf86PostKeyboardEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down)
-{
- xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
-}
-
-LocalDevicePtr
-xf86FirstLocalDevice(void)
-{
- return xf86InputDevs;
-}
-
-/*
- * Cx - raw data from touch screen
- * Sxhigh - scaled highest dimension
- * (remember, this is of rows - 1 because of 0 origin)
- * Sxlow - scaled lowest dimension
- * Rxhigh - highest raw value from touch screen calibration
- * Rxlow - lowest raw value from touch screen calibration
- *
- * This function is the same for X or Y coordinates.
- * You may have to reverse the high and low values to compensate for
- * different orgins on the touch screen vs X.
- */
-
-int
-xf86ScaleAxis(int Cx,
- int Sxhigh,
- int Sxlow,
- int Rxhigh,
- int Rxlow )
-{
- int X;
- int64_t dSx = Sxhigh - Sxlow;
- int64_t dRx = Rxhigh - Rxlow;
-
- if (dRx) {
- X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow);
- }
- else {
- X = 0;
- ErrorF ("Divide by Zero in xf86ScaleAxis");
- }
-
- if (X > Sxhigh)
- X = Sxhigh;
- if (X < Sxlow)
- X = Sxlow;
-
- return (X);
-}
-
-/*
- * This function checks the given screen against the current screen and
- * makes changes if appropriate. It should be called from an XInput driver's
- * ReadInput function before any events are posted, if the device is screen
- * specific like a touch screen.
- */
-void
-xf86XInputSetScreen(LocalDevicePtr local,
- int screen_number,
- int x,
- int y)
-{
- if (miPointerGetScreen(local->dev) !=
- screenInfo.screens[screen_number]) {
- miPointerSetScreen(local->dev, screen_number, x, y);
- }
-}
-
-
-void
-xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res)
-{
- if (!dev || !dev->valuator)
- return;
-
- InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
- max_res);
-}
-
-/*
- * Set the valuator values to be in synch with dix/event.c
- * DefineInitialRootWindow().
- */
-void
-xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
-{
- if (axnum == 0) {
- dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
- dev->last.valuators[0] = dev->valuator->axisVal[0];
- }
- else if (axnum == 1) {
- dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
- dev->last.valuators[1] = dev->valuator->axisVal[1];
- }
-
- if(axnum == 0) /* to prevent double invocation */
- ApplyAccelerationSettings(dev);
-}
-
-
-/**
- * Deactivate a device. Call this function from the driver if you receive a
- * read error or something else that spoils your day.
- * Device will be moved to the off_devices list, but it will still be there
- * until you really clean up after it.
- * Notifies the client about an inactive device.
- *
- * @param panic True if device is unrecoverable and needs to be removed.
- */
-void
-xf86DisableDevice(DeviceIntPtr dev, Bool panic)
-{
- if(!panic)
- {
- DisableDevice(dev, TRUE);
- } else
- {
- SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
- DeleteInputDeviceRequest(dev);
- }
-}
-
-/**
- * Reactivate a device. Call this function from the driver if you just found
- * out that the read error wasn't quite that bad after all.
- * Device will be re-activated, and an event sent to the client.
- */
-void
-xf86EnableDevice(DeviceIntPtr dev)
-{
- EnableDevice(dev, TRUE);
-}
-
-/* end of xf86Xinput.c */
+/*
+ * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
+ *
+ * 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 Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED 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.
+ *
+ */
+/*
+ * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/Xatom.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "XIstubs.h"
+#include "xf86Optrec.h"
+#include "xf86Parser.h"
+#include "mipointer.h"
+#include "xf86InPriv.h"
+#include "compiler.h"
+#include "extinit.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+#include "exevents.h" /* AddInputDevice */
+#include "exglobals.h"
+#include "eventstr.h"
+
+#include <string.h> /* InputClassMatches */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
+#include "extnsionst.h"
+
+#include "windowstr.h" /* screenIsSaved */
+
+#include <stdarg.h>
+#include <stdint.h> /* for int64_t */
+
+#include <X11/Xpoll.h>
+
+#include "mi.h"
+
+#include <ptrveloc.h> /* dix pointer acceleration */
+#include <xserver-properties.h>
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#include "xkbsrv.h"
+
+#include "os.h"
+
+EventListPtr xf86Events = NULL;
+
+/**
+ * Eval config and modify DeviceVelocityRec accordingly
+ */
+static void
+ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
+ DeviceVelocityPtr s)
+{
+ int tempi;
+ float tempf;
+ Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
+ Atom prop;
+
+ if(!s)
+ return;
+
+ /* common settings (available via device properties) */
+ tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ /* select profile by number */
+ tempi = xf86SetIntOption(list, "AccelerationProfile",
+ s->statistics.profile_number);
+
+ prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+ if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
+ PropModeReplace, 1, &tempi, FALSE) == Success) {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
+ tempi);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
+ devname, tempi);
+ }
+
+ /* set scaling */
+ tempf = xf86SetRealOption(list, "ExpectedRate", 0);
+ prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+ if (tempf > 0) {
+ tempf = 1000.0 / tempf;
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ } else {
+ tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
+ if (tempi > 1)
+ InitTrackers(s, tempi);
+
+ s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
+ s->initial_range);
+
+ s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
+
+ tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
+ if (tempf >= 0) {
+ xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
+ devname, tempf*100.0);
+ s->max_rel_diff = tempf;
+ }
+
+ /* Configure softening. If const deceleration is used, this is expected
+ * to provide better subpixel information so we enable
+ * softening by default only if ConstantDeceleration is not used
+ */
+ s->use_softening = xf86SetBoolOption(list, "Softening",
+ s->const_acceleration == 1.0);
+
+ s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
+ s->average_accel);
+
+ s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
+}
+
+static void
+ApplyAccelerationSettings(DeviceIntPtr dev){
+ int scheme, i;
+ DeviceVelocityPtr pVel;
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+ char* schemeStr;
+
+ if (dev->valuator && dev->ptrfeed) {
+ schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
+
+ scheme = dev->valuator->accelScheme.number;
+
+ if (!xf86NameCmp(schemeStr, "predictable"))
+ scheme = PtrAccelPredictable;
+
+ if (!xf86NameCmp(schemeStr, "lightweight"))
+ scheme = PtrAccelLightweight;
+
+ if (!xf86NameCmp(schemeStr, "none"))
+ scheme = PtrAccelNoOp;
+
+ /* reinit scheme if needed */
+ if (dev->valuator->accelScheme.number != scheme) {
+ if (dev->valuator->accelScheme.AccelCleanupProc) {
+ dev->valuator->accelScheme.AccelCleanupProc(dev);
+ }
+
+ if (InitPointerAccelerationScheme(dev, scheme)) {
+ xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
+ local->name, schemeStr, scheme);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
+ local->name, schemeStr);
+ scheme = dev->valuator->accelScheme.number;
+ }
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
+ local->name, scheme);
+ }
+
+ free(schemeStr);
+
+ /* process special configuration */
+ switch (scheme) {
+ case PtrAccelPredictable:
+ pVel = GetDevicePredictableAccelData(dev);
+ ProcessVelocityConfiguration (dev, local->name, local->options,
+ pVel);
+ break;
+ }
+
+ i = xf86SetIntOption(local->options, "AccelerationNumerator",
+ dev->ptrfeed->ctrl.num);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.num = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationDenominator",
+ dev->ptrfeed->ctrl.den);
+ if (i > 0)
+ dev->ptrfeed->ctrl.den = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationThreshold",
+ dev->ptrfeed->ctrl.threshold);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.threshold = i;
+
+ /* mostly a no-op anyway */
+ (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
+
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
+ local->name, ((float)dev->ptrfeed->ctrl.num)/
+ ((float)dev->ptrfeed->ctrl.den));
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
+ local->name, dev->ptrfeed->ctrl.threshold);
+ }
+}
+
+static Bool
+xf86SendDragEvents(DeviceIntPtr device)
+{
+ LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
+
+ if (device->button && device->button->buttonsDown > 0)
+ return (local->flags & XI86_SEND_DRAG_EVENTS);
+ else
+ return (TRUE);
+}
+
+/***********************************************************************
+ *
+ * xf86ProcessCommonOptions --
+ *
+ * Process global options.
+ *
+ ***********************************************************************
+ */
+void
+xf86ProcessCommonOptions(LocalDevicePtr local,
+ pointer list)
+{
+ if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
+ !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
+ !xf86SetBoolOption(list, "CorePointer", 1) ||
+ !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
+ xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
+ } else {
+ local->flags |= XI86_ALWAYS_CORE;
+ xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
+ }
+
+ if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
+ local->flags |= XI86_SEND_DRAG_EVENTS;
+ } else {
+ xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
+ }
+
+ /* Backwards compatibility. */
+ local->history_size = GetMotionHistorySize();
+}
+
+/***********************************************************************
+ *
+ * xf86ActivateDevice --
+ *
+ * Initialize an input device.
+ *
+ * Returns TRUE on success, or FALSE otherwise.
+ ***********************************************************************
+ */
+int
+xf86ActivateDevice(LocalDevicePtr local)
+{
+ DeviceIntPtr dev;
+
+ if (local->flags & XI86_CONFIGURED) {
+ dev = AddInputDevice(serverClient, local->device_control, TRUE);
+
+ if (dev == NULL)
+ {
+ xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
+ local->name);
+ local->dev = NULL;
+ return FALSE;
+ }
+
+ local->atom = MakeAtom(local->type_name,
+ strlen(local->type_name),
+ TRUE);
+ AssignTypeAndName(dev, local->atom, local->name);
+ dev->public.devicePrivate = (pointer) local;
+ local->dev = dev;
+
+ dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
+ dev->type = SLAVE;
+ dev->spriteInfo->spriteOwner = FALSE;
+
+ dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+
+ RegisterOtherDevice(dev);
+ XkbSetExtension(dev, ProcessKeyboardEvent);
+
+ if (serverGeneration == 1)
+ xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
+ local->name, local->type_name);
+ }
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXOpenDevice
+ *
+ * This is the implementation-dependent routine to open an input device.
+ * Some implementations open all input devices when the server is first
+ * initialized, and never close them. Other implementations open only
+ * the X pointer and keyboard devices during server initialization,
+ * and only open other input devices when some client makes an
+ * XOpenDevice request. This entry point is for the latter type of
+ * implementation.
+ *
+ * If the physical device is not already open, do it here. In this case,
+ * you need to keep track of the fact that one or more clients has the
+ * device open, and physically close it when the last client that has
+ * it open does an XCloseDevice.
+ *
+ * The default implementation is to do nothing (assume all input devices
+ * are opened during X server initialization and kept open).
+ *
+ ***********************************************************************
+ */
+
+void
+OpenInputDevice(DeviceIntPtr dev,
+ ClientPtr client,
+ int *status)
+{
+ if (!dev->inited)
+ ActivateDevice(dev, TRUE);
+
+ *status = Success;
+}
+
+void
+CloseInputDevice(DeviceIntPtr dev,
+ ClientPtr client)
+{
+}
+
+/****************************************************************************
+ *
+ * Caller: ProcXSetDeviceMode
+ *
+ * Change the mode of an extension device.
+ * This function is used to change the mode of a device from reporting
+ * relative motion to reporting absolute positional information, and
+ * vice versa.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+
+ if (local->switch_mode) {
+ return (*local->switch_mode)(client, dev, mode);
+ }
+ else
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXSetDeviceValuators
+ *
+ * Set the value of valuators on an extension input device.
+ * This function is used to set the initial value of valuators on
+ * those input devices that are capable of reporting either relative
+ * motion or an absolute position, and allow an initial position to be set.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
+ int first_valuator, int num_valuators)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ if (local->set_device_valuators)
+ return (*local->set_device_valuators)(local, valuators, first_valuator,
+ num_valuators);
+
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXChangeDeviceControl
+ *
+ * Change the specified device controls on an extension input device.
+ *
+ ***********************************************************************
+ */
+
+int
+ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+
+ if (!local->control_proc) {
+ switch (control->control) {
+ case DEVICE_CORE:
+ return BadMatch;
+ case DEVICE_RESOLUTION:
+ case DEVICE_ABS_CALIB:
+ case DEVICE_ABS_AREA:
+ case DEVICE_ENABLE:
+ return Success;
+ default:
+ return BadMatch;
+ }
+ }
+ else {
+ return (*local->control_proc)(local, control);
+ }
+}
+
+void
+AddOtherInputDevices(void)
+{
+}
+
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
+{
+ char **cur;
+ Bool match;
+
+ if (iclass->match_product) {
+ if (!attrs->product)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_product, match = FALSE; *cur; cur++)
+ if (strstr(attrs->product, *cur)) {
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_vendor) {
+ if (!attrs->vendor)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_vendor, match = FALSE; *cur; cur++)
+ if (strstr(attrs->vendor, *cur)) {
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_device) {
+ if (!attrs->device)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_device, match = FALSE; *cur; cur++)
+#ifdef HAVE_FNMATCH_H
+ if (fnmatch(*cur, attrs->device, FNM_PATHNAME) == 0) {
+#else
+ if (strstr(attrs->device, *cur)) {
+#endif
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_tag) {
+ if (!attrs->tags)
+ return FALSE;
+
+ for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
+ const char *tag;
+ for(tag = *attrs->tags; *tag; tag++) {
+ if (!strcmp(tag, *cur)) {
+ match = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!match)
+ return FALSE;
+ }
+
+ if (iclass->is_keyboard.set &&
+ iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
+ return FALSE;
+ if (iclass->is_pointer.set &&
+ iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
+ return FALSE;
+ if (iclass->is_joystick.set &&
+ iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
+ return FALSE;
+ if (iclass->is_tablet.set &&
+ iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
+ return FALSE;
+ if (iclass->is_touchpad.set &&
+ iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
+ return FALSE;
+ if (iclass->is_touchscreen.set &&
+ iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Merge in any InputClass configurations. Options in each InputClass
+ * section have more priority than the original device configuration as
+ * well as any previous InputClass sections.
+ */
+static int
+MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ XF86OptionPtr classopts, mergedopts = NULL;
+ char *classdriver = NULL;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, attrs))
+ continue;
+
+ /* Collect class options and merge over previous classes */
+ xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
+ idev->identifier, cl->identifier);
+ if (cl->driver)
+ classdriver = cl->driver;
+ classopts = xf86optionListDup(cl->option_lst);
+ mergedopts = xf86optionListMerge(mergedopts, classopts);
+ }
+
+ /* Apply options to device with InputClass settings preferred. */
+ if (classdriver) {
+ free(idev->driver);
+ idev->driver = xstrdup(classdriver);
+ if (!idev->driver) {
+ xf86Msg(X_ERROR, "Failed to allocate memory while merging "
+ "InputClass configuration");
+ return BadAlloc;
+ }
+ mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
+ }
+ idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
+
+ return Success;
+}
+
+/*
+ * Iterate the list of classes and look for Option "Ignore". Return the
+ * value of the last matching class and holler when returning TRUE.
+ */
+static Bool
+IgnoreInputClass(IDevPtr idev, InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ Bool ignore = FALSE;
+ const char *ignore_class;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, attrs))
+ continue;
+ if (xf86findOption(cl->option_lst, "Ignore")) {
+ ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
+ ignore_class = cl->identifier;
+ }
+ }
+
+ if (ignore)
+ xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
+ idev->identifier, ignore_class);
+ return ignore;
+}
+
+/**
+ * Create a new input device, activate and enable it.
+ *
+ * Possible return codes:
+ * BadName .. a bad driver name was supplied.
+ * BadImplementation ... The driver does not have a PreInit function. This
+ * is a driver bug.
+ * BadMatch .. device initialization failed.
+ * BadAlloc .. too many input devices
+ *
+ * @param idev The device, already set up with identifier, driver, and the
+ * options.
+ * @param pdev Pointer to the new device, if Success was reported.
+ * @param enable Enable the device after activating it.
+ *
+ * @return Success or an error code
+ */
+_X_INTERNAL int
+xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
+{
+ InputDriverPtr drv = NULL;
+ InputInfoPtr pInfo = NULL;
+ DeviceIntPtr dev = NULL;
+ int rval;
+
+ /* Memory leak for every attached device if we don't
+ * test if the module is already loaded first */
+ drv = xf86LookupInputDriver(idev->driver);
+ if (!drv)
+ if (xf86LoadOneModule(idev->driver, NULL))
+ drv = xf86LookupInputDriver(idev->driver);
+ if (!drv) {
+ xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver);
+ rval = BadName;
+ goto unwind;
+ }
+
+ if (!drv->PreInit) {
+ xf86Msg(X_ERROR,
+ "Input driver `%s' has no PreInit function (ignoring)\n",
+ drv->driverName);
+ rval = BadImplementation;
+ goto unwind;
+ }
+
+ pInfo = drv->PreInit(drv, idev, 0);
+
+ if (!pInfo) {
+ xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+ else if (!(pInfo->flags & XI86_CONFIGURED)) {
+ xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
+ idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+
+ if (!xf86ActivateDevice(pInfo))
+ {
+ rval = BadAlloc;
+ goto unwind;
+ }
+
+ dev = pInfo->dev;
+ rval = ActivateDevice(dev, TRUE);
+ if (rval != Success)
+ {
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+ RemoveDevice(dev, TRUE);
+ goto unwind;
+ }
+
+ /* Enable it if it's properly initialised and we're currently in the VT */
+ if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
+ {
+ EnableDevice(dev, TRUE);
+ if (!dev->enabled)
+ {
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+ /* send enter/leave event, update sprite window */
+ CheckMotion(NULL, dev);
+ }
+
+ *pdev = dev;
+ return Success;
+
+unwind:
+ if(pInfo) {
+ if(drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+ }
+ return rval;
+}
+
+int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+ DeviceIntPtr *pdev)
+{
+ IDevRec *idev = NULL;
+ InputOption *option = NULL;
+ int rval = Success;
+ int is_auto = 0;
+
+ idev = calloc(sizeof(*idev), 1);
+ if (!idev)
+ return BadAlloc;
+
+ for (option = options; option; option = option->next) {
+ if (strcasecmp(option->key, "driver") == 0) {
+ if (idev->driver) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ idev->driver = xstrdup(option->value);
+ if (!idev->driver) {
+ rval = BadAlloc;
+ goto unwind;
+ }
+ }
+
+ if (strcasecmp(option->key, "name") == 0 ||
+ strcasecmp(option->key, "identifier") == 0) {
+ if (idev->identifier) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ idev->identifier = xstrdup(option->value);
+ if (!idev->identifier) {
+ rval = BadAlloc;
+ goto unwind;
+ }
+ }
+
+ if (strcmp(option->key, "_source") == 0 &&
+ (strcmp(option->value, "server/hal") == 0 ||
+ strcmp(option->value, "server/udev") == 0)) {
+ is_auto = 1;
+ if (!xf86Info.autoAddDevices) {
+ rval = BadMatch;
+ goto unwind;
+ }
+ }
+ }
+
+ for (option = options; option; option = option->next) {
+ /* Steal option key/value strings from the provided list.
+ * We need those strings, the InputOption list doesn't. */
+ idev->commonOptions = xf86addNewOption(idev->commonOptions,
+ option->key, option->value);
+ option->key = NULL;
+ option->value = NULL;
+ }
+
+ /* Apply InputClass settings */
+ if (attrs) {
+ if (IgnoreInputClass(idev, attrs)) {
+ rval = BadIDChoice;
+ goto unwind;
+ }
+
+ rval = MergeInputClasses(idev, attrs);
+ if (rval != Success)
+ goto unwind;
+ }
+
+ if (!idev->driver || !idev->identifier) {
+ xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
+ rval = BadRequest;
+ goto unwind;
+ }
+
+ if (!idev->identifier) {
+ xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
+ return BadMatch;
+ }
+
+ rval = xf86NewInputDevice(idev, pdev,
+ (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
+ if (rval == Success)
+ return Success;
+
+unwind:
+ if (is_auto && !xf86Info.autoAddDevices)
+ xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
+ if(idev->driver)
+ free(idev->driver);
+ if(idev->identifier)
+ free(idev->identifier);
+ xf86optionListFree(idev->commonOptions);
+ free(idev);
+ return rval;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+ LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
+ InputDriverPtr drv = NULL;
+ IDevRec *idev = NULL;
+ IDevPtr *it;
+ Bool isMaster = IsMaster(pDev);
+
+ if (pInfo) /* need to get these before RemoveDevice */
+ {
+ drv = pInfo->drv;
+ idev = pInfo->conf_idev;
+ }
+
+ OsBlockSignals();
+ RemoveDevice(pDev, TRUE);
+
+ if (!isMaster && pInfo != NULL)
+ {
+ if(drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+
+ /* devices added through HAL aren't in the config layout */
+ it = xf86ConfigLayout.inputs;
+ while(*it && *it != idev)
+ it++;
+
+ if (!(*it)) /* end of list, not in the layout */
+ {
+ free(idev->driver);
+ free(idev->identifier);
+ xf86optionListFree(idev->commonOptions);
+ free(idev);
+ }
+ }
+ OsReleaseSignals();
+}
+
+/*
+ * convenient functions to post events
+ */
+
+void
+xf86PostMotionEvent(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ static int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
+}
+
+void
+xf86PostMotionEventP(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+ Bool drag = xf86SendDragEvents(device);
+ DeviceEvent *event;
+ int flags = 0;
+
+#if XFreeXDGA
+ int index;
+ int dx = 0, dy = 0;
+#endif
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+
+#if XFreeXDGA
+ /* The evdev driver may not always send all axes across. */
+ if (num_valuators >= 1 && first_valuator <= 1) {
+ if (miPointerGetScreen(device)) {
+ index = miPointerGetScreen(device)->myNum;
+ if (first_valuator == 0)
+ {
+ dx = valuators[0];
+ if (is_absolute)
+ dx -= device->last.valuators[0];
+ }
+
+ if (first_valuator == 1 || num_valuators >= 2)
+ {
+ dy = valuators[1 - first_valuator];
+ if (is_absolute)
+ dy -= device->last.valuators[1];
+ }
+
+ if (DGAStealMotionEvent(device, index, dx, dy))
+ return;
+ }
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
+ flags, first_valuator, num_valuators,
+ valuators);
+
+ for (i = 0; i < nevents; i++) {
+ event = (DeviceEvent*)((xf86Events + i)->event);
+ /* Don't post core motion events for devices not registered to send
+ * drag events. */
+ if (event->header == ET_Internal &&
+ (event->type != ET_Motion || drag)) {
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+ }
+ }
+}
+
+void
+xf86PostProximityEvent(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i;
+ int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostProximityEventP(device, is_in, first_valuator, num_valuators,
+ valuators);
+
+}
+
+void
+xf86PostProximityEventP(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i, nevents;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ nevents = GetProximityEvents(xf86Events, device,
+ is_in ? ProximityIn : ProximityOut,
+ first_valuator, num_valuators, valuators);
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostButtonEvent(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int valuators[MAX_VALUATORS];
+ int i = 0;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostButtonEventP(device, is_absolute, button, is_down, first_valuator,
+ num_valuators, valuators);
+
+}
+
+void
+xf86PostButtonEventP(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+ int flags = 0;
+
+#if XFreeXDGA
+ int index;
+#endif
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+
+#if XFreeXDGA
+ if (miPointerGetScreen(device)) {
+ index = miPointerGetScreen(device)->myNum;
+ if (DGAStealButtonEvent(device, index, button, is_down))
+ return;
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device,
+ is_down ? ButtonPress : ButtonRelease, button,
+ flags, first_valuator, num_valuators, valuators);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostKeyEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ static int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostKeyEventP(device, key_code, is_down, is_absolute, first_valuator,
+ num_valuators, valuators);
+
+}
+
+void
+xf86PostKeyEventP(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute) {
+ nevents = GetKeyboardValuatorEvents(xf86Events, device,
+ is_down ? KeyPress : KeyRelease,
+ key_code, first_valuator,
+ num_valuators, valuators);
+ }
+ else {
+ nevents = GetKeyboardEvents(xf86Events, device,
+ is_down ? KeyPress : KeyRelease,
+ key_code);
+ }
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+}
+
+void
+xf86PostKeyboardEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down)
+{
+ xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
+}
+
+LocalDevicePtr
+xf86FirstLocalDevice(void)
+{
+ return xf86InputDevs;
+}
+
+/*
+ * Cx - raw data from touch screen
+ * Sxhigh - scaled highest dimension
+ * (remember, this is of rows - 1 because of 0 origin)
+ * Sxlow - scaled lowest dimension
+ * Rxhigh - highest raw value from touch screen calibration
+ * Rxlow - lowest raw value from touch screen calibration
+ *
+ * This function is the same for X or Y coordinates.
+ * You may have to reverse the high and low values to compensate for
+ * different orgins on the touch screen vs X.
+ */
+
+int
+xf86ScaleAxis(int Cx,
+ int Sxhigh,
+ int Sxlow,
+ int Rxhigh,
+ int Rxlow )
+{
+ int X;
+ int64_t dSx = Sxhigh - Sxlow;
+ int64_t dRx = Rxhigh - Rxlow;
+
+ if (dRx) {
+ X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow);
+ }
+ else {
+ X = 0;
+ ErrorF ("Divide by Zero in xf86ScaleAxis");
+ }
+
+ if (X > Sxhigh)
+ X = Sxhigh;
+ if (X < Sxlow)
+ X = Sxlow;
+
+ return (X);
+}
+
+/*
+ * This function checks the given screen against the current screen and
+ * makes changes if appropriate. It should be called from an XInput driver's
+ * ReadInput function before any events are posted, if the device is screen
+ * specific like a touch screen.
+ */
+void
+xf86XInputSetScreen(LocalDevicePtr local,
+ int screen_number,
+ int x,
+ int y)
+{
+ if (miPointerGetScreen(local->dev) !=
+ screenInfo.screens[screen_number]) {
+ miPointerSetScreen(local->dev, screen_number, x, y);
+ }
+}
+
+
+void
+xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
+ int resolution, int min_res, int max_res)
+{
+ if (!dev || !dev->valuator)
+ return;
+
+ InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
+ max_res);
+}
+
+/*
+ * Set the valuator values to be in synch with dix/event.c
+ * DefineInitialRootWindow().
+ */
+void
+xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
+{
+ if (axnum == 0) {
+ dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+ dev->last.valuators[0] = dev->valuator->axisVal[0];
+ }
+ else if (axnum == 1) {
+ dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+ dev->last.valuators[1] = dev->valuator->axisVal[1];
+ }
+
+ if(axnum == 0) /* to prevent double invocation */
+ ApplyAccelerationSettings(dev);
+}
+
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ *
+ * @param panic True if device is unrecoverable and needs to be removed.
+ */
+void
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
+{
+ if(!panic)
+ {
+ DisableDevice(dev, TRUE);
+ } else
+ {
+ SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
+ DeleteInputDeviceRequest(dev);
+ }
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client.
+ */
+void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+ EnableDevice(dev, TRUE);
+}
+
+/* end of xf86Xinput.c */
diff --git a/xorg-server/hw/xfree86/common/xf86cmap.c b/xorg-server/hw/xfree86/common/xf86cmap.c
index e266ffb6d..fa0ebc8eb 100644
--- a/xorg-server/hw/xfree86/common/xf86cmap.c
+++ b/xorg-server/hw/xfree86/common/xf86cmap.c
@@ -1,1166 +1,1166 @@
-/*
- * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#if defined(_XOPEN_SOURCE) || defined(sun) && defined(__SVR4)
-#include <math.h>
-#else
-#define _XOPEN_SOURCE /* to get prototype for pow on some systems */
-#include <math.h>
-#undef _XOPEN_SOURCE
-#endif
-
-#include <X11/X.h>
-#include "misc.h"
-#include <X11/Xproto.h>
-#include "colormapst.h"
-#include "scrnintstr.h"
-
-#include "resource.h"
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86str.h"
-#include "micmap.h"
-#include "xf86Crtc.h"
-
-#ifdef XFreeXDGA
-#include <X11/extensions/xf86dgaproto.h>
-#include "dgaproc.h"
-#endif
-
-#include "xf86cmap.h"
-
-#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
- ((CMapScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, CMapScreenKey))->field)
-#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
- ((pScreen)->field = wrapper)
-
-#define LOAD_PALETTE(pmap) \
- ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
- xf86Screens[pmap->pScreen->myNum]->vtSema || pScreenPriv->isDGAmode))
-
-
-typedef struct _CMapLink {
- ColormapPtr cmap;
- struct _CMapLink *next;
-} CMapLink, *CMapLinkPtr;
-
-typedef struct {
- ScrnInfoPtr pScrn;
- CloseScreenProcPtr CloseScreen;
- CreateColormapProcPtr CreateColormap;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- StoreColorsProcPtr StoreColors;
- Bool (*EnterVT)(int, int);
- Bool (*SwitchMode)(int, DisplayModePtr, int);
- int (*SetDGAMode)(int, int, DGADevicePtr);
- xf86ChangeGammaProc *ChangeGamma;
- int maxColors;
- int sigRGBbits;
- int gammaElements;
- LOCO *gamma;
- int *PreAllocIndices;
- CMapLinkPtr maps;
- unsigned int flags;
- Bool isDGAmode;
-} CMapScreenRec, *CMapScreenPtr;
-
-typedef struct {
- int numColors;
- LOCO *colors;
- Bool recalculate;
- int overscan;
-} CMapColormapRec, *CMapColormapPtr;
-
-static int CMapScreenKeyIndex;
-static DevPrivateKey CMapScreenKey;
-static int CMapColormapKeyIndex;
-static DevPrivateKey CMapColormapKey = &CMapColormapKeyIndex;
-
-static void CMapInstallColormap(ColormapPtr);
-static void CMapStoreColors(ColormapPtr, int, xColorItem *);
-static Bool CMapCloseScreen (int, ScreenPtr);
-static Bool CMapCreateColormap (ColormapPtr);
-static void CMapDestroyColormap (ColormapPtr);
-
-static Bool CMapEnterVT(int, int);
-static Bool CMapSwitchMode(int, DisplayModePtr, int);
-#ifdef XFreeXDGA
-static int CMapSetDGAMode(int, int, DGADevicePtr);
-#endif
-static int CMapChangeGamma(int, Gamma);
-
-static void ComputeGamma(CMapScreenPtr);
-static Bool CMapAllocateColormapPrivate(ColormapPtr);
-static void CMapRefreshColors(ColormapPtr, int, int*);
-static void CMapSetOverscan(ColormapPtr, int, int *);
-static void CMapReinstallMap(ColormapPtr);
-static void CMapUnwrapScreen(ScreenPtr pScreen);
-
-
-
-Bool xf86HandleColormaps(
- ScreenPtr pScreen,
- int maxColors,
- int sigRGBbits,
- xf86LoadPaletteProc *loadPalette,
- xf86SetOverscanProc *setOverscan,
- unsigned int flags
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- ColormapPtr pDefMap = NULL;
- CMapScreenPtr pScreenPriv;
- LOCO *gamma;
- int *indices;
- int elements;
-
- /* If we support a better colormap system, then pretend we succeeded. */
- if (xf86_crtc_supports_gamma(pScrn))
- return TRUE;
-
- if(!maxColors || !sigRGBbits || !loadPalette)
- return FALSE;
-
- CMapScreenKey = &CMapScreenKeyIndex;
-
- elements = 1 << sigRGBbits;
-
- if(!(gamma = xalloc(elements * sizeof(LOCO))))
- return FALSE;
-
- if(!(indices = xalloc(maxColors * sizeof(int)))) {
- xfree(gamma);
- return FALSE;
- }
-
- if(!(pScreenPriv = xalloc(sizeof(CMapScreenRec)))) {
- xfree(gamma);
- xfree(indices);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, CMapScreenKey, pScreenPriv);
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreenPriv->CreateColormap = pScreen->CreateColormap;
- pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
- pScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreenPriv->StoreColors = pScreen->StoreColors;
- pScreen->CloseScreen = CMapCloseScreen;
- pScreen->CreateColormap = CMapCreateColormap;
- pScreen->DestroyColormap = CMapDestroyColormap;
- pScreen->InstallColormap = CMapInstallColormap;
- pScreen->StoreColors = CMapStoreColors;
-
- pScreenPriv->pScrn = pScrn;
- pScrn->LoadPalette = loadPalette;
- pScrn->SetOverscan = setOverscan;
- pScreenPriv->maxColors = maxColors;
- pScreenPriv->sigRGBbits = sigRGBbits;
- pScreenPriv->gammaElements = elements;
- pScreenPriv->gamma = gamma;
- pScreenPriv->PreAllocIndices = indices;
- pScreenPriv->maps = NULL;
- pScreenPriv->flags = flags;
- pScreenPriv->isDGAmode = FALSE;
-
- pScreenPriv->EnterVT = pScrn->EnterVT;
- pScreenPriv->SwitchMode = pScrn->SwitchMode;
- pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
- pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
-
- if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
- pScrn->EnterVT = CMapEnterVT;
- if ((flags & CMAP_RELOAD_ON_MODE_SWITCH) && pScrn->SwitchMode)
- pScrn->SwitchMode = CMapSwitchMode;
- }
-#ifdef XFreeXDGA
- pScrn->SetDGAMode = CMapSetDGAMode;
-#endif
- pScrn->ChangeGamma = CMapChangeGamma;
-
- ComputeGamma(pScreenPriv);
-
- /* get the default map */
- dixLookupResourceByType((pointer *)&pDefMap, pScreen->defColormap,
- RT_COLORMAP, serverClient, DixInstallAccess);
-
- if(!CMapAllocateColormapPrivate(pDefMap)) {
- CMapUnwrapScreen(pScreen);
- return FALSE;
- }
-
- /* Force the initial map to be loaded */
- SetInstalledmiColormap(pScreen, NULL);
- CMapInstallColormap(pDefMap);
- return TRUE;
-}
-
-
-/**** Screen functions ****/
-
-
-static Bool
-CMapCloseScreen (int i, ScreenPtr pScreen)
-{
- CMapUnwrapScreen(pScreen);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static Bool
-CMapColormapUseMax(VisualPtr pVisual, CMapScreenPtr pScreenPriv)
-{
- if (pVisual->nplanes > 16)
- return TRUE;
- return ((1 << pVisual->nplanes) > pScreenPriv->maxColors);
-}
-
-static Bool
-CMapAllocateColormapPrivate(ColormapPtr pmap)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv;
- CMapLinkPtr pLink;
- int numColors;
- LOCO *colors;
-
- if (CMapColormapUseMax(pmap->pVisual, pScreenPriv))
- numColors = pmap->pVisual->ColormapEntries;
- else
- numColors = 1 << pmap->pVisual->nplanes;
-
- if(!(colors = xalloc(numColors * sizeof(LOCO))))
- return FALSE;
-
- if(!(pColPriv = xalloc(sizeof(CMapColormapRec)))) {
- xfree(colors);
- return FALSE;
- }
-
- dixSetPrivate(&pmap->devPrivates, CMapColormapKey, pColPriv);
-
- pColPriv->numColors = numColors;
- pColPriv->colors = colors;
- pColPriv->recalculate = TRUE;
- pColPriv->overscan = -1;
-
- /* add map to list */
- pLink = xalloc(sizeof(CMapLink));
- if(pLink) {
- pLink->cmap = pmap;
- pLink->next = pScreenPriv->maps;
- pScreenPriv->maps = pLink;
- }
-
- return TRUE;
-}
-
-static Bool
-CMapCreateColormap (ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- Bool ret = FALSE;
-
- pScreen->CreateColormap = pScreenPriv->CreateColormap;
- if((*pScreen->CreateColormap)(pmap)) {
- if(CMapAllocateColormapPrivate(pmap))
- ret = TRUE;
- }
- pScreen->CreateColormap = CMapCreateColormap;
-
- return ret;
-}
-
-static void
-CMapDestroyColormap (ColormapPtr cmap)
-{
- ScreenPtr pScreen = cmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &cmap->devPrivates, CMapColormapKey);
- CMapLinkPtr prevLink = NULL, pLink = pScreenPriv->maps;
-
- if(pColPriv) {
- if(pColPriv->colors) xfree(pColPriv->colors);
- xfree(pColPriv);
- }
-
- /* remove map from list */
- while(pLink) {
- if(pLink->cmap == cmap) {
- if(prevLink)
- prevLink->next = pLink->next;
- else
- pScreenPriv->maps = pLink->next;
- xfree(pLink);
- break;
- }
- prevLink = pLink;
- pLink = pLink->next;
- }
-
- if(pScreenPriv->DestroyColormap) {
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- (*pScreen->DestroyColormap)(cmap);
- pScreen->DestroyColormap = CMapDestroyColormap;
- }
-}
-
-
-
-static void
-CMapStoreColors(
- ColormapPtr pmap,
- int ndef,
- xColorItem *pdefs
-){
- ScreenPtr pScreen = pmap->pScreen;
- VisualPtr pVisual = pmap->pVisual;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- int *indices = pScreenPriv->PreAllocIndices;
- int num = ndef;
-
- /* At the moment this isn't necessary since there's nobody below us */
- pScreen->StoreColors = pScreenPriv->StoreColors;
- (*pScreen->StoreColors)(pmap, ndef, pdefs);
- pScreen->StoreColors = CMapStoreColors;
-
- /* should never get here for these */
- if( (pVisual->class == TrueColor) ||
- (pVisual->class == StaticColor) ||
- (pVisual->class == StaticGray))
- return;
-
- if(pVisual->class == DirectColor) {
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- int i;
-
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- int index;
-
- num = 0;
- while(ndef--) {
- if(pdefs[ndef].flags & DoRed) {
- index = (pdefs[ndef].pixel & pVisual->redMask) >>
- pVisual->offsetRed;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- if(pdefs[ndef].flags & DoGreen) {
- index = (pdefs[ndef].pixel & pVisual->greenMask) >>
- pVisual->offsetGreen;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- if(pdefs[ndef].flags & DoBlue) {
- index = (pdefs[ndef].pixel & pVisual->blueMask) >>
- pVisual->offsetBlue;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- }
-
- } else {
- /* not really as overkill as it seems */
- num = pColPriv->numColors;
- for(i = 0; i < pColPriv->numColors; i++)
- indices[i] = i;
- }
- } else {
- while(ndef--)
- indices[ndef] = pdefs[ndef].pixel;
- }
-
- CMapRefreshColors(pmap, num, indices);
-}
-
-
-static void
-CMapInstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if (pmap == GetInstalledmiColormap(pmap->pScreen))
- return;
-
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- (*pScreen->InstallColormap)(pmap);
- pScreen->InstallColormap = CMapInstallColormap;
-
- /* Important. We let the lower layers, namely DGA,
- overwrite the choice of Colormap to install */
- if (GetInstalledmiColormap(pmap->pScreen))
- pmap = GetInstalledmiColormap(pmap->pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pmap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pmap->pVisual, pScreenPriv))
- return;
-
- if(LOAD_PALETTE(pmap))
- CMapReinstallMap(pmap);
-}
-
-
-/**** ScrnInfoRec functions ****/
-
-static Bool
-CMapEnterVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if((*pScreenPriv->EnterVT)(index, flags)) {
- if(GetInstalledmiColormap(pScreen))
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
- return TRUE;
- }
- return FALSE;
-}
-
-
-static Bool
-CMapSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if((*pScreenPriv->SwitchMode)(index, mode, flags)) {
- if(GetInstalledmiColormap(pScreen))
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
- return TRUE;
- }
- return FALSE;
-}
-
-#ifdef XFreeXDGA
-static int
-CMapSetDGAMode(int index, int num, DGADevicePtr dev)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- int ret;
-
- ret = (*pScreenPriv->SetDGAMode)(index, num, dev);
-
- pScreenPriv->isDGAmode = DGAActive(index);
-
- if(!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
- && xf86Screens[pScreen->myNum]->vtSema)
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
-
- return ret;
-}
-#endif
-
-
-/**** Utilities ****/
-
-static void
-CMapReinstallMap(ColormapPtr pmap)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr cmapPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- int i = cmapPriv->numColors;
- int *indices = pScreenPriv->PreAllocIndices;
-
- while(i--)
- indices[i] = i;
-
- if(cmapPriv->recalculate)
- CMapRefreshColors(pmap, cmapPriv->numColors, indices);
- else {
- (*pScrn->LoadPalette)(pScrn, cmapPriv->numColors,
- indices, cmapPriv->colors, pmap->pVisual);
- if (pScrn->SetOverscan) {
-#ifdef DEBUGOVERSCAN
- ErrorF("SetOverscan() called from CMapReinstallMap\n");
-#endif
- pScrn->SetOverscan(pScrn, cmapPriv->overscan);
- }
- }
-
- cmapPriv->recalculate = FALSE;
-}
-
-
-static void
-CMapRefreshColors(ColormapPtr pmap, int defs, int* indices)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- VisualPtr pVisual = pmap->pVisual;
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- int numColors, i;
- LOCO *gamma, *colors;
- EntryPtr entry;
- int reds, greens, blues, maxValue, index, shift;
-
- numColors = pColPriv->numColors;
- shift = 16 - pScreenPriv->sigRGBbits;
- maxValue = (1 << pScreenPriv->sigRGBbits) - 1;
- gamma = pScreenPriv->gamma;
- colors = pColPriv->colors;
-
- reds = pVisual->redMask >> pVisual->offsetRed;
- greens = pVisual->greenMask >> pVisual->offsetGreen;
- blues = pVisual->blueMask >> pVisual->offsetBlue;
-
- switch(pVisual->class) {
- case StaticGray:
- for(i = 0; i < numColors; i++) {
- index = (i+1) * maxValue / numColors;
- colors[i].red = gamma[index].red;
- colors[i].green = gamma[index].green;
- colors[i].blue = gamma[index].blue;
- }
- break;
- case TrueColor:
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- for(i = 0; i <= reds; i++)
- colors[i].red = gamma[i * maxValue / reds].red;
- for(i = 0; i <= greens; i++)
- colors[i].green = gamma[i * maxValue / greens].green;
- for(i = 0; i <= blues; i++)
- colors[i].blue = gamma[i * maxValue / blues].blue;
- break;
- }
- for(i = 0; i < numColors; i++) {
- colors[i].red = gamma[((i >> pVisual->offsetRed) & reds) *
- maxValue / reds].red;
- colors[i].green = gamma[((i >> pVisual->offsetGreen) & greens) *
- maxValue / greens].green;
- colors[i].blue = gamma[((i >> pVisual->offsetBlue) & blues) *
- maxValue / blues].blue;
- }
- break;
- case StaticColor:
- case PseudoColor:
- case GrayScale:
- for(i = 0; i < defs; i++) {
- index = indices[i];
- entry = (EntryPtr)&pmap->red[index];
-
- if(entry->fShared) {
- colors[index].red =
- gamma[entry->co.shco.red->color >> shift].red;
- colors[index].green =
- gamma[entry->co.shco.green->color >> shift].green;
- colors[index].blue =
- gamma[entry->co.shco.blue->color >> shift].blue;
- } else {
- colors[index].red =
- gamma[entry->co.local.red >> shift].red;
- colors[index].green =
- gamma[entry->co.local.green >> shift].green;
- colors[index].blue =
- gamma[entry->co.local.blue >> shift].blue;
- }
- }
- break;
- case DirectColor:
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- for(i = 0; i < defs; i++) {
- index = indices[i];
- if(index <= reds)
- colors[index].red =
- gamma[pmap->red[index].co.local.red >> shift].red;
- if(index <= greens)
- colors[index].green =
- gamma[pmap->green[index].co.local.green >> shift].green;
- if(index <= blues)
- colors[index].blue =
- gamma[pmap->blue[index].co.local.blue >> shift].blue;
-
- }
- break;
- }
- for(i = 0; i < defs; i++) {
- index = indices[i];
-
- colors[index].red = gamma[pmap->red[
- (index >> pVisual->offsetRed) & reds
- ].co.local.red >> shift].red;
- colors[index].green = gamma[pmap->green[
- (index >> pVisual->offsetGreen) & greens
- ].co.local.green >> shift].green;
- colors[index].blue = gamma[pmap->blue[
- (index >> pVisual->offsetBlue) & blues
- ].co.local.blue >> shift].blue;
- }
- break;
- }
-
-
- if(LOAD_PALETTE(pmap))
- (*pScrn->LoadPalette)(pScreenPriv->pScrn, defs, indices,
- colors, pmap->pVisual);
-
- if (pScrn->SetOverscan)
- CMapSetOverscan(pmap, defs, indices);
-
-}
-
-static Bool
-CMapCompareColors(LOCO *color1, LOCO *color2)
-{
- /* return TRUE if the color1 is "closer" to black than color2 */
-#ifdef DEBUGOVERSCAN
- ErrorF("#%02x%02x%02x vs #%02x%02x%02x (%d vs %d)\n",
- color1->red, color1->green, color1->blue,
- color2->red, color2->green, color2->blue,
- color1->red + color1->green + color1->blue,
- color2->red + color2->green + color2->blue);
-#endif
- return (color1->red + color1->green + color1->blue <
- color2->red + color2->green + color2->blue);
-}
-
-static void
-CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- VisualPtr pVisual = pmap->pVisual;
- int i;
- LOCO *colors;
- int index;
- Bool newOverscan = FALSE;
- int overscan, tmpOverscan;
-
- colors = pColPriv->colors;
- overscan = pColPriv->overscan;
-
- /*
- * Search for a new overscan index in the following cases:
- *
- * - The index hasn't yet been initialised.  In this case search
- * for an index that is black or a close match to black.
- *
- * - The colour of the old index is changed. In this case search
- * all indices for a black or close match to black.
- *
- * - The colour of the old index wasn't black. In this case only
- * search the indices that were changed for a better match to black.
- */
-
- switch (pVisual->class) {
- case StaticGray:
- case TrueColor:
- /* Should only come here once. Initialise the overscan index to 0 */
- overscan = 0;
- newOverscan = TRUE;
- break;
- case StaticColor:
- /*
- * Only come here once, but search for the overscan in the same way
- * as for the other cases.
- */
- case DirectColor:
- case PseudoColor:
- case GrayScale:
- if (overscan < 0 || overscan > pScreenPriv->maxColors - 1) {
- /* Uninitialised */
- newOverscan = TRUE;
- } else {
- /* Check if the overscan was changed */
- for (i = 0; i < defs; i++) {
- index = indices[i];
- if (index == overscan) {
- newOverscan = TRUE;
- break;
- }
- }
- }
- if (newOverscan) {
- /* The overscan is either uninitialised or it has been changed */
-
- if (overscan < 0 || overscan > pScreenPriv->maxColors - 1)
- tmpOverscan = pScreenPriv->maxColors - 1;
- else
- tmpOverscan = overscan;
-
- /* search all entries for a close match to black */
- for (i = pScreenPriv->maxColors - 1; i >= 0; i--) {
- if (colors[i].red == 0 && colors[i].green == 0 &&
- colors[i].blue == 0) {
- overscan = i;
-#ifdef DEBUGOVERSCAN
- ErrorF("Black found at index 0x%02x\n", i);
-#endif
- break;
- } else {
-#ifdef DEBUGOVERSCAN
- ErrorF("0x%02x: ", i);
-#endif
- if (CMapCompareColors(&colors[i], &colors[tmpOverscan])) {
- tmpOverscan = i;
-#ifdef DEBUGOVERSCAN
- ErrorF("possible \"Black\" at index 0x%02x\n", i);
-#endif
- }
- }
- }
- if (i < 0)
- overscan = tmpOverscan;
- } else {
- /* Check of the old overscan wasn't black */
- if (colors[overscan].red != 0 || colors[overscan].green != 0 ||
- colors[overscan].blue != 0) {
- int oldOverscan = tmpOverscan = overscan;
- /* See of there is now a better match */
- for (i = 0; i < defs; i++) {
- index = indices[i];
- if (colors[index].red == 0 && colors[index].green == 0 &&
- colors[index].blue == 0) {
- overscan = index;
-#ifdef DEBUGOVERSCAN
- ErrorF("Black found at index 0x%02x\n", index);
-#endif
- break;
- } else {
-#ifdef DEBUGOVERSCAN
- ErrorF("0x%02x: ", index);
-#endif
- if (CMapCompareColors(&colors[index],
- &colors[tmpOverscan])) {
- tmpOverscan = index;
-#ifdef DEBUGOVERSCAN
- ErrorF("possible \"Black\" at index 0x%02x\n",
- index);
-#endif
- }
- }
- }
- if (i == defs)
- overscan = tmpOverscan;
- if (overscan != oldOverscan)
- newOverscan = TRUE;
- }
- }
- break;
- }
- if (newOverscan) {
- pColPriv->overscan = overscan;
- if (LOAD_PALETTE(pmap)) {
-#ifdef DEBUGOVERSCAN
- ErrorF("SetOverscan() called from CmapSetOverscan\n");
-#endif
- pScrn->SetOverscan(pScreenPriv->pScrn, overscan);
- }
- }
-}
-
-static void
-CMapUnwrapScreen(ScreenPtr pScreen)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->CreateColormap = pScreenPriv->CreateColormap;
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- pScreen->StoreColors = pScreenPriv->StoreColors;
-
- pScrn->EnterVT = pScreenPriv->EnterVT;
- pScrn->SwitchMode = pScreenPriv->SwitchMode;
- pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
- pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
-
- xfree(pScreenPriv->gamma);
- xfree(pScreenPriv->PreAllocIndices);
- xfree(pScreenPriv);
-}
-
-
-static void
-ComputeGamma(CMapScreenPtr priv)
-{
- int elements = priv->gammaElements - 1;
- double RedGamma, GreenGamma, BlueGamma;
- int i;
-
-#ifndef DONT_CHECK_GAMMA
- /* This check is to catch drivers that are not initialising pScrn->gamma */
- if (priv->pScrn->gamma.red < GAMMA_MIN ||
- priv->pScrn->gamma.red > GAMMA_MAX ||
- priv->pScrn->gamma.green < GAMMA_MIN ||
- priv->pScrn->gamma.green > GAMMA_MAX ||
- priv->pScrn->gamma.blue < GAMMA_MIN ||
- priv->pScrn->gamma.blue > GAMMA_MAX) {
-
- xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
- "The %s driver didn't call xf86SetGamma() to initialise\n"
- "\tthe gamma values.\n", priv->pScrn->driverName);
- xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
- "PLEASE FIX THE `%s' DRIVER!\n", priv->pScrn->driverName);
- priv->pScrn->gamma.red = 1.0;
- priv->pScrn->gamma.green = 1.0;
- priv->pScrn->gamma.blue = 1.0;
- }
-#endif
-
- RedGamma = 1.0 / (double)priv->pScrn->gamma.red;
- GreenGamma = 1.0 / (double)priv->pScrn->gamma.green;
- BlueGamma = 1.0 / (double)priv->pScrn->gamma.blue;
-
- for(i = 0; i <= elements; i++) {
- if(RedGamma == 1.0)
- priv->gamma[i].red = i;
- else
- priv->gamma[i].red = (CARD16)(pow((double)i/(double)elements,
- RedGamma) * (double)elements + 0.5);
-
- if(GreenGamma == 1.0)
- priv->gamma[i].green = i;
- else
- priv->gamma[i].green = (CARD16)(pow((double)i/(double)elements,
- GreenGamma) * (double)elements + 0.5);
-
- if(BlueGamma == 1.0)
- priv->gamma[i].blue = i;
- else
- priv->gamma[i].blue = (CARD16)(pow((double)i/(double)elements,
- BlueGamma) * (double)elements + 0.5);
- }
-}
-
-
-int
-CMapChangeGamma(
- int index,
- Gamma gamma
-){
- int ret = Success;
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = pScrn->pScreen;
- CMapColormapPtr pColPriv;
- CMapScreenPtr pScreenPriv;
- CMapLinkPtr pLink;
-
- /* Is this sufficient checking ? */
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if (gamma.red < GAMMA_MIN || gamma.red > GAMMA_MAX ||
- gamma.green < GAMMA_MIN || gamma.green > GAMMA_MAX ||
- gamma.blue < GAMMA_MIN || gamma.blue > GAMMA_MAX)
- return BadValue;
-
- pScrn->gamma.red = gamma.red;
- pScrn->gamma.green = gamma.green;
- pScrn->gamma.blue = gamma.blue;
-
- ComputeGamma(pScreenPriv);
-
- /* mark all colormaps on this screen */
- pLink = pScreenPriv->maps;
- while(pLink) {
- pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
- CMapColormapKey);
- pColPriv->recalculate = TRUE;
- pLink = pLink->next;
- }
-
- if(GetInstalledmiColormap(pScreen) &&
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
- pScrn->vtSema || pScreenPriv->isDGAmode)) {
- ColormapPtr pMap = GetInstalledmiColormap(pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pMap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
-
- /* if the current map doesn't have a palette look
- for another map to change the gamma on. */
-
- pLink = pScreenPriv->maps;
- while(pLink) {
- if(pLink->cmap->pVisual->class == PseudoColor)
- break;
- pLink = pLink->next;
- }
-
- if(pLink) {
- /* need to trick CMapRefreshColors() into thinking
- this is the currently installed map */
- SetInstalledmiColormap(pScreen, pLink->cmap);
- CMapReinstallMap(pLink->cmap);
- SetInstalledmiColormap(pScreen, pMap);
- }
- } else
- CMapReinstallMap(pMap);
- }
-
- pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
- if (pScrn->ChangeGamma)
- ret = pScrn->ChangeGamma(index, gamma);
- pScrn->ChangeGamma = CMapChangeGamma;
-
- return ret;
-}
-
-
-static void
-ComputeGammaRamp (
- CMapScreenPtr priv,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- int elements = priv->gammaElements;
- LOCO *entry = priv->gamma;
- int shift = 16 - priv->sigRGBbits;
-
- while(elements--) {
- entry->red = *(red++) >> shift;
- entry->green = *(green++) >> shift;
- entry->blue = *(blue++) >> shift;
- entry++;
- }
-}
-
-int
-xf86ChangeGammaRamp(
- ScreenPtr pScreen,
- int size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapColormapPtr pColPriv;
- CMapScreenPtr pScreenPriv;
- CMapLinkPtr pLink;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc) {
- if (crtc->gammaSize != size)
- return BadValue;
-
- RRCrtcGammaSet(crtc, red, green, blue);
-
- return Success;
- }
- }
-
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if(pScreenPriv->gammaElements != size)
- return BadValue;
-
- ComputeGammaRamp(pScreenPriv, red, green, blue);
-
- /* mark all colormaps on this screen */
- pLink = pScreenPriv->maps;
- while(pLink) {
- pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
- CMapColormapKey);
- pColPriv->recalculate = TRUE;
- pLink = pLink->next;
- }
-
- if(GetInstalledmiColormap(pScreen) &&
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
- pScrn->vtSema || pScreenPriv->isDGAmode)) {
- ColormapPtr pMap = GetInstalledmiColormap(pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pMap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
-
- /* if the current map doesn't have a palette look
- for another map to change the gamma on. */
-
- pLink = pScreenPriv->maps;
- while(pLink) {
- if(pLink->cmap->pVisual->class == PseudoColor)
- break;
- pLink = pLink->next;
- }
-
- if(pLink) {
- /* need to trick CMapRefreshColors() into thinking
- this is the currently installed map */
- SetInstalledmiColormap(pScreen, pLink->cmap);
- CMapReinstallMap(pLink->cmap);
- SetInstalledmiColormap(pScreen, pMap);
- }
- } else
- CMapReinstallMap(pMap);
- }
-
- return Success;
-}
-
-int
-xf86GetGammaRampSize(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapScreenPtr pScreenPriv;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc)
- return crtc->gammaSize;
- }
-
- if(CMapScreenKey == NULL) return 0;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv) return 0;
-
- return pScreenPriv->gammaElements;
-}
-
-int
-xf86GetGammaRamp(
- ScreenPtr pScreen,
- int size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapScreenPtr pScreenPriv;
- LOCO *entry;
- int shift, sigbits;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc) {
- if (crtc->gammaSize < size)
- return BadValue;
-
- if (!RRCrtcGammaGet(crtc))
- return BadImplementation;
-
- memcpy(red, crtc->gammaRed, size * sizeof(*red));
- memcpy(green, crtc->gammaGreen, size * sizeof(*green));
- memcpy(blue, crtc->gammaBlue, size * sizeof(*blue));
-
- return Success;
- }
- }
-
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if(size > pScreenPriv->gammaElements)
- return BadValue;
-
- entry = pScreenPriv->gamma;
- sigbits = pScreenPriv->sigRGBbits;
-
- while(size--) {
- *red = entry->red << (16 - sigbits);
- *green = entry->green << (16 - sigbits);
- *blue = entry->blue << (16 - sigbits);
- shift = sigbits;
- while(shift < 16) {
- *red |= *red >> shift;
- *green |= *green >> shift;
- *blue |= *blue >> shift;
- shift += sigbits;
- }
- red++; green++; blue++;
- entry++;
- }
-
- return Success;
-}
-
-int
-xf86ChangeGamma(
- ScreenPtr pScreen,
- Gamma gamma
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if(pScrn->ChangeGamma)
- return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
-
- return BadImplementation;
-}
+/*
+ * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(sun) && defined(__SVR4)
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for pow on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include <X11/Xproto.h>
+#include "colormapst.h"
+#include "scrnintstr.h"
+
+#include "resource.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86str.h"
+#include "micmap.h"
+#include "xf86Crtc.h"
+
+#ifdef XFreeXDGA
+#include <X11/extensions/xf86dgaproto.h>
+#include "dgaproc.h"
+#endif
+
+#include "xf86cmap.h"
+
+#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
+ ((CMapScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, CMapScreenKey))->field)
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+#define LOAD_PALETTE(pmap) \
+ ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
+ xf86Screens[pmap->pScreen->myNum]->vtSema || pScreenPriv->isDGAmode))
+
+
+typedef struct _CMapLink {
+ ColormapPtr cmap;
+ struct _CMapLink *next;
+} CMapLink, *CMapLinkPtr;
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ CloseScreenProcPtr CloseScreen;
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ StoreColorsProcPtr StoreColors;
+ Bool (*EnterVT)(int, int);
+ Bool (*SwitchMode)(int, DisplayModePtr, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+ xf86ChangeGammaProc *ChangeGamma;
+ int maxColors;
+ int sigRGBbits;
+ int gammaElements;
+ LOCO *gamma;
+ int *PreAllocIndices;
+ CMapLinkPtr maps;
+ unsigned int flags;
+ Bool isDGAmode;
+} CMapScreenRec, *CMapScreenPtr;
+
+typedef struct {
+ int numColors;
+ LOCO *colors;
+ Bool recalculate;
+ int overscan;
+} CMapColormapRec, *CMapColormapPtr;
+
+static int CMapScreenKeyIndex;
+static DevPrivateKey CMapScreenKey;
+static int CMapColormapKeyIndex;
+static DevPrivateKey CMapColormapKey = &CMapColormapKeyIndex;
+
+static void CMapInstallColormap(ColormapPtr);
+static void CMapStoreColors(ColormapPtr, int, xColorItem *);
+static Bool CMapCloseScreen (int, ScreenPtr);
+static Bool CMapCreateColormap (ColormapPtr);
+static void CMapDestroyColormap (ColormapPtr);
+
+static Bool CMapEnterVT(int, int);
+static Bool CMapSwitchMode(int, DisplayModePtr, int);
+#ifdef XFreeXDGA
+static int CMapSetDGAMode(int, int, DGADevicePtr);
+#endif
+static int CMapChangeGamma(int, Gamma);
+
+static void ComputeGamma(CMapScreenPtr);
+static Bool CMapAllocateColormapPrivate(ColormapPtr);
+static void CMapRefreshColors(ColormapPtr, int, int*);
+static void CMapSetOverscan(ColormapPtr, int, int *);
+static void CMapReinstallMap(ColormapPtr);
+static void CMapUnwrapScreen(ScreenPtr pScreen);
+
+
+
+Bool xf86HandleColormaps(
+ ScreenPtr pScreen,
+ int maxColors,
+ int sigRGBbits,
+ xf86LoadPaletteProc *loadPalette,
+ xf86SetOverscanProc *setOverscan,
+ unsigned int flags
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ColormapPtr pDefMap = NULL;
+ CMapScreenPtr pScreenPriv;
+ LOCO *gamma;
+ int *indices;
+ int elements;
+
+ /* If we support a better colormap system, then pretend we succeeded. */
+ if (xf86_crtc_supports_gamma(pScrn))
+ return TRUE;
+
+ if(!maxColors || !sigRGBbits || !loadPalette)
+ return FALSE;
+
+ CMapScreenKey = &CMapScreenKeyIndex;
+
+ elements = 1 << sigRGBbits;
+
+ if(!(gamma = malloc(elements * sizeof(LOCO))))
+ return FALSE;
+
+ if(!(indices = malloc(maxColors * sizeof(int)))) {
+ free(gamma);
+ return FALSE;
+ }
+
+ if(!(pScreenPriv = malloc(sizeof(CMapScreenRec)))) {
+ free(gamma);
+ free(indices);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, CMapScreenKey, pScreenPriv);
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->CreateColormap = pScreen->CreateColormap;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreenPriv->StoreColors = pScreen->StoreColors;
+ pScreen->CloseScreen = CMapCloseScreen;
+ pScreen->CreateColormap = CMapCreateColormap;
+ pScreen->DestroyColormap = CMapDestroyColormap;
+ pScreen->InstallColormap = CMapInstallColormap;
+ pScreen->StoreColors = CMapStoreColors;
+
+ pScreenPriv->pScrn = pScrn;
+ pScrn->LoadPalette = loadPalette;
+ pScrn->SetOverscan = setOverscan;
+ pScreenPriv->maxColors = maxColors;
+ pScreenPriv->sigRGBbits = sigRGBbits;
+ pScreenPriv->gammaElements = elements;
+ pScreenPriv->gamma = gamma;
+ pScreenPriv->PreAllocIndices = indices;
+ pScreenPriv->maps = NULL;
+ pScreenPriv->flags = flags;
+ pScreenPriv->isDGAmode = FALSE;
+
+ pScreenPriv->EnterVT = pScrn->EnterVT;
+ pScreenPriv->SwitchMode = pScrn->SwitchMode;
+ pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
+
+ if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
+ pScrn->EnterVT = CMapEnterVT;
+ if ((flags & CMAP_RELOAD_ON_MODE_SWITCH) && pScrn->SwitchMode)
+ pScrn->SwitchMode = CMapSwitchMode;
+ }
+#ifdef XFreeXDGA
+ pScrn->SetDGAMode = CMapSetDGAMode;
+#endif
+ pScrn->ChangeGamma = CMapChangeGamma;
+
+ ComputeGamma(pScreenPriv);
+
+ /* get the default map */
+ dixLookupResourceByType((pointer *)&pDefMap, pScreen->defColormap,
+ RT_COLORMAP, serverClient, DixInstallAccess);
+
+ if(!CMapAllocateColormapPrivate(pDefMap)) {
+ CMapUnwrapScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Force the initial map to be loaded */
+ SetInstalledmiColormap(pScreen, NULL);
+ CMapInstallColormap(pDefMap);
+ return TRUE;
+}
+
+
+/**** Screen functions ****/
+
+
+static Bool
+CMapCloseScreen (int i, ScreenPtr pScreen)
+{
+ CMapUnwrapScreen(pScreen);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static Bool
+CMapColormapUseMax(VisualPtr pVisual, CMapScreenPtr pScreenPriv)
+{
+ if (pVisual->nplanes > 16)
+ return TRUE;
+ return ((1 << pVisual->nplanes) > pScreenPriv->maxColors);
+}
+
+static Bool
+CMapAllocateColormapPrivate(ColormapPtr pmap)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv;
+ CMapLinkPtr pLink;
+ int numColors;
+ LOCO *colors;
+
+ if (CMapColormapUseMax(pmap->pVisual, pScreenPriv))
+ numColors = pmap->pVisual->ColormapEntries;
+ else
+ numColors = 1 << pmap->pVisual->nplanes;
+
+ if(!(colors = malloc(numColors * sizeof(LOCO))))
+ return FALSE;
+
+ if(!(pColPriv = malloc(sizeof(CMapColormapRec)))) {
+ free(colors);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pmap->devPrivates, CMapColormapKey, pColPriv);
+
+ pColPriv->numColors = numColors;
+ pColPriv->colors = colors;
+ pColPriv->recalculate = TRUE;
+ pColPriv->overscan = -1;
+
+ /* add map to list */
+ pLink = malloc(sizeof(CMapLink));
+ if(pLink) {
+ pLink->cmap = pmap;
+ pLink->next = pScreenPriv->maps;
+ pScreenPriv->maps = pLink;
+ }
+
+ return TRUE;
+}
+
+static Bool
+CMapCreateColormap (ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ Bool ret = FALSE;
+
+ pScreen->CreateColormap = pScreenPriv->CreateColormap;
+ if((*pScreen->CreateColormap)(pmap)) {
+ if(CMapAllocateColormapPrivate(pmap))
+ ret = TRUE;
+ }
+ pScreen->CreateColormap = CMapCreateColormap;
+
+ return ret;
+}
+
+static void
+CMapDestroyColormap (ColormapPtr cmap)
+{
+ ScreenPtr pScreen = cmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &cmap->devPrivates, CMapColormapKey);
+ CMapLinkPtr prevLink = NULL, pLink = pScreenPriv->maps;
+
+ if(pColPriv) {
+ if(pColPriv->colors) free(pColPriv->colors);
+ free(pColPriv);
+ }
+
+ /* remove map from list */
+ while(pLink) {
+ if(pLink->cmap == cmap) {
+ if(prevLink)
+ prevLink->next = pLink->next;
+ else
+ pScreenPriv->maps = pLink->next;
+ free(pLink);
+ break;
+ }
+ prevLink = pLink;
+ pLink = pLink->next;
+ }
+
+ if(pScreenPriv->DestroyColormap) {
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ (*pScreen->DestroyColormap)(cmap);
+ pScreen->DestroyColormap = CMapDestroyColormap;
+ }
+}
+
+
+
+static void
+CMapStoreColors(
+ ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs
+){
+ ScreenPtr pScreen = pmap->pScreen;
+ VisualPtr pVisual = pmap->pVisual;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ int *indices = pScreenPriv->PreAllocIndices;
+ int num = ndef;
+
+ /* At the moment this isn't necessary since there's nobody below us */
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+ (*pScreen->StoreColors)(pmap, ndef, pdefs);
+ pScreen->StoreColors = CMapStoreColors;
+
+ /* should never get here for these */
+ if( (pVisual->class == TrueColor) ||
+ (pVisual->class == StaticColor) ||
+ (pVisual->class == StaticGray))
+ return;
+
+ if(pVisual->class == DirectColor) {
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ int i;
+
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ int index;
+
+ num = 0;
+ while(ndef--) {
+ if(pdefs[ndef].flags & DoRed) {
+ index = (pdefs[ndef].pixel & pVisual->redMask) >>
+ pVisual->offsetRed;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ if(pdefs[ndef].flags & DoGreen) {
+ index = (pdefs[ndef].pixel & pVisual->greenMask) >>
+ pVisual->offsetGreen;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ if(pdefs[ndef].flags & DoBlue) {
+ index = (pdefs[ndef].pixel & pVisual->blueMask) >>
+ pVisual->offsetBlue;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ }
+
+ } else {
+ /* not really as overkill as it seems */
+ num = pColPriv->numColors;
+ for(i = 0; i < pColPriv->numColors; i++)
+ indices[i] = i;
+ }
+ } else {
+ while(ndef--)
+ indices[ndef] = pdefs[ndef].pixel;
+ }
+
+ CMapRefreshColors(pmap, num, indices);
+}
+
+
+static void
+CMapInstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if (pmap == GetInstalledmiColormap(pmap->pScreen))
+ return;
+
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ (*pScreen->InstallColormap)(pmap);
+ pScreen->InstallColormap = CMapInstallColormap;
+
+ /* Important. We let the lower layers, namely DGA,
+ overwrite the choice of Colormap to install */
+ if (GetInstalledmiColormap(pmap->pScreen))
+ pmap = GetInstalledmiColormap(pmap->pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pmap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pmap->pVisual, pScreenPriv))
+ return;
+
+ if(LOAD_PALETTE(pmap))
+ CMapReinstallMap(pmap);
+}
+
+
+/**** ScrnInfoRec functions ****/
+
+static Bool
+CMapEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if((*pScreenPriv->EnterVT)(index, flags)) {
+ if(GetInstalledmiColormap(pScreen))
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static Bool
+CMapSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if((*pScreenPriv->SwitchMode)(index, mode, flags)) {
+ if(GetInstalledmiColormap(pScreen))
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifdef XFreeXDGA
+static int
+CMapSetDGAMode(int index, int num, DGADevicePtr dev)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ int ret;
+
+ ret = (*pScreenPriv->SetDGAMode)(index, num, dev);
+
+ pScreenPriv->isDGAmode = DGAActive(index);
+
+ if(!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
+ && xf86Screens[pScreen->myNum]->vtSema)
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+
+ return ret;
+}
+#endif
+
+
+/**** Utilities ****/
+
+static void
+CMapReinstallMap(ColormapPtr pmap)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr cmapPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ int i = cmapPriv->numColors;
+ int *indices = pScreenPriv->PreAllocIndices;
+
+ while(i--)
+ indices[i] = i;
+
+ if(cmapPriv->recalculate)
+ CMapRefreshColors(pmap, cmapPriv->numColors, indices);
+ else {
+ (*pScrn->LoadPalette)(pScrn, cmapPriv->numColors,
+ indices, cmapPriv->colors, pmap->pVisual);
+ if (pScrn->SetOverscan) {
+#ifdef DEBUGOVERSCAN
+ ErrorF("SetOverscan() called from CMapReinstallMap\n");
+#endif
+ pScrn->SetOverscan(pScrn, cmapPriv->overscan);
+ }
+ }
+
+ cmapPriv->recalculate = FALSE;
+}
+
+
+static void
+CMapRefreshColors(ColormapPtr pmap, int defs, int* indices)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ VisualPtr pVisual = pmap->pVisual;
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ int numColors, i;
+ LOCO *gamma, *colors;
+ EntryPtr entry;
+ int reds, greens, blues, maxValue, index, shift;
+
+ numColors = pColPriv->numColors;
+ shift = 16 - pScreenPriv->sigRGBbits;
+ maxValue = (1 << pScreenPriv->sigRGBbits) - 1;
+ gamma = pScreenPriv->gamma;
+ colors = pColPriv->colors;
+
+ reds = pVisual->redMask >> pVisual->offsetRed;
+ greens = pVisual->greenMask >> pVisual->offsetGreen;
+ blues = pVisual->blueMask >> pVisual->offsetBlue;
+
+ switch(pVisual->class) {
+ case StaticGray:
+ for(i = 0; i < numColors; i++) {
+ index = (i+1) * maxValue / numColors;
+ colors[i].red = gamma[index].red;
+ colors[i].green = gamma[index].green;
+ colors[i].blue = gamma[index].blue;
+ }
+ break;
+ case TrueColor:
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ for(i = 0; i <= reds; i++)
+ colors[i].red = gamma[i * maxValue / reds].red;
+ for(i = 0; i <= greens; i++)
+ colors[i].green = gamma[i * maxValue / greens].green;
+ for(i = 0; i <= blues; i++)
+ colors[i].blue = gamma[i * maxValue / blues].blue;
+ break;
+ }
+ for(i = 0; i < numColors; i++) {
+ colors[i].red = gamma[((i >> pVisual->offsetRed) & reds) *
+ maxValue / reds].red;
+ colors[i].green = gamma[((i >> pVisual->offsetGreen) & greens) *
+ maxValue / greens].green;
+ colors[i].blue = gamma[((i >> pVisual->offsetBlue) & blues) *
+ maxValue / blues].blue;
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case GrayScale:
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+ entry = (EntryPtr)&pmap->red[index];
+
+ if(entry->fShared) {
+ colors[index].red =
+ gamma[entry->co.shco.red->color >> shift].red;
+ colors[index].green =
+ gamma[entry->co.shco.green->color >> shift].green;
+ colors[index].blue =
+ gamma[entry->co.shco.blue->color >> shift].blue;
+ } else {
+ colors[index].red =
+ gamma[entry->co.local.red >> shift].red;
+ colors[index].green =
+ gamma[entry->co.local.green >> shift].green;
+ colors[index].blue =
+ gamma[entry->co.local.blue >> shift].blue;
+ }
+ }
+ break;
+ case DirectColor:
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+ if(index <= reds)
+ colors[index].red =
+ gamma[pmap->red[index].co.local.red >> shift].red;
+ if(index <= greens)
+ colors[index].green =
+ gamma[pmap->green[index].co.local.green >> shift].green;
+ if(index <= blues)
+ colors[index].blue =
+ gamma[pmap->blue[index].co.local.blue >> shift].blue;
+
+ }
+ break;
+ }
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+
+ colors[index].red = gamma[pmap->red[
+ (index >> pVisual->offsetRed) & reds
+ ].co.local.red >> shift].red;
+ colors[index].green = gamma[pmap->green[
+ (index >> pVisual->offsetGreen) & greens
+ ].co.local.green >> shift].green;
+ colors[index].blue = gamma[pmap->blue[
+ (index >> pVisual->offsetBlue) & blues
+ ].co.local.blue >> shift].blue;
+ }
+ break;
+ }
+
+
+ if(LOAD_PALETTE(pmap))
+ (*pScrn->LoadPalette)(pScreenPriv->pScrn, defs, indices,
+ colors, pmap->pVisual);
+
+ if (pScrn->SetOverscan)
+ CMapSetOverscan(pmap, defs, indices);
+
+}
+
+static Bool
+CMapCompareColors(LOCO *color1, LOCO *color2)
+{
+ /* return TRUE if the color1 is "closer" to black than color2 */
+#ifdef DEBUGOVERSCAN
+ ErrorF("#%02x%02x%02x vs #%02x%02x%02x (%d vs %d)\n",
+ color1->red, color1->green, color1->blue,
+ color2->red, color2->green, color2->blue,
+ color1->red + color1->green + color1->blue,
+ color2->red + color2->green + color2->blue);
+#endif
+ return (color1->red + color1->green + color1->blue <
+ color2->red + color2->green + color2->blue);
+}
+
+static void
+CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ VisualPtr pVisual = pmap->pVisual;
+ int i;
+ LOCO *colors;
+ int index;
+ Bool newOverscan = FALSE;
+ int overscan, tmpOverscan;
+
+ colors = pColPriv->colors;
+ overscan = pColPriv->overscan;
+
+ /*
+ * Search for a new overscan index in the following cases:
+ *
+ * - The index hasn't yet been initialised.  In this case search
+ * for an index that is black or a close match to black.
+ *
+ * - The colour of the old index is changed. In this case search
+ * all indices for a black or close match to black.
+ *
+ * - The colour of the old index wasn't black. In this case only
+ * search the indices that were changed for a better match to black.
+ */
+
+ switch (pVisual->class) {
+ case StaticGray:
+ case TrueColor:
+ /* Should only come here once. Initialise the overscan index to 0 */
+ overscan = 0;
+ newOverscan = TRUE;
+ break;
+ case StaticColor:
+ /*
+ * Only come here once, but search for the overscan in the same way
+ * as for the other cases.
+ */
+ case DirectColor:
+ case PseudoColor:
+ case GrayScale:
+ if (overscan < 0 || overscan > pScreenPriv->maxColors - 1) {
+ /* Uninitialised */
+ newOverscan = TRUE;
+ } else {
+ /* Check if the overscan was changed */
+ for (i = 0; i < defs; i++) {
+ index = indices[i];
+ if (index == overscan) {
+ newOverscan = TRUE;
+ break;
+ }
+ }
+ }
+ if (newOverscan) {
+ /* The overscan is either uninitialised or it has been changed */
+
+ if (overscan < 0 || overscan > pScreenPriv->maxColors - 1)
+ tmpOverscan = pScreenPriv->maxColors - 1;
+ else
+ tmpOverscan = overscan;
+
+ /* search all entries for a close match to black */
+ for (i = pScreenPriv->maxColors - 1; i >= 0; i--) {
+ if (colors[i].red == 0 && colors[i].green == 0 &&
+ colors[i].blue == 0) {
+ overscan = i;
+#ifdef DEBUGOVERSCAN
+ ErrorF("Black found at index 0x%02x\n", i);
+#endif
+ break;
+ } else {
+#ifdef DEBUGOVERSCAN
+ ErrorF("0x%02x: ", i);
+#endif
+ if (CMapCompareColors(&colors[i], &colors[tmpOverscan])) {
+ tmpOverscan = i;
+#ifdef DEBUGOVERSCAN
+ ErrorF("possible \"Black\" at index 0x%02x\n", i);
+#endif
+ }
+ }
+ }
+ if (i < 0)
+ overscan = tmpOverscan;
+ } else {
+ /* Check of the old overscan wasn't black */
+ if (colors[overscan].red != 0 || colors[overscan].green != 0 ||
+ colors[overscan].blue != 0) {
+ int oldOverscan = tmpOverscan = overscan;
+ /* See of there is now a better match */
+ for (i = 0; i < defs; i++) {
+ index = indices[i];
+ if (colors[index].red == 0 && colors[index].green == 0 &&
+ colors[index].blue == 0) {
+ overscan = index;
+#ifdef DEBUGOVERSCAN
+ ErrorF("Black found at index 0x%02x\n", index);
+#endif
+ break;
+ } else {
+#ifdef DEBUGOVERSCAN
+ ErrorF("0x%02x: ", index);
+#endif
+ if (CMapCompareColors(&colors[index],
+ &colors[tmpOverscan])) {
+ tmpOverscan = index;
+#ifdef DEBUGOVERSCAN
+ ErrorF("possible \"Black\" at index 0x%02x\n",
+ index);
+#endif
+ }
+ }
+ }
+ if (i == defs)
+ overscan = tmpOverscan;
+ if (overscan != oldOverscan)
+ newOverscan = TRUE;
+ }
+ }
+ break;
+ }
+ if (newOverscan) {
+ pColPriv->overscan = overscan;
+ if (LOAD_PALETTE(pmap)) {
+#ifdef DEBUGOVERSCAN
+ ErrorF("SetOverscan() called from CmapSetOverscan\n");
+#endif
+ pScrn->SetOverscan(pScreenPriv->pScrn, overscan);
+ }
+ }
+}
+
+static void
+CMapUnwrapScreen(ScreenPtr pScreen)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreateColormap = pScreenPriv->CreateColormap;
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+
+ pScrn->EnterVT = pScreenPriv->EnterVT;
+ pScrn->SwitchMode = pScreenPriv->SwitchMode;
+ pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
+
+ free(pScreenPriv->gamma);
+ free(pScreenPriv->PreAllocIndices);
+ free(pScreenPriv);
+}
+
+
+static void
+ComputeGamma(CMapScreenPtr priv)
+{
+ int elements = priv->gammaElements - 1;
+ double RedGamma, GreenGamma, BlueGamma;
+ int i;
+
+#ifndef DONT_CHECK_GAMMA
+ /* This check is to catch drivers that are not initialising pScrn->gamma */
+ if (priv->pScrn->gamma.red < GAMMA_MIN ||
+ priv->pScrn->gamma.red > GAMMA_MAX ||
+ priv->pScrn->gamma.green < GAMMA_MIN ||
+ priv->pScrn->gamma.green > GAMMA_MAX ||
+ priv->pScrn->gamma.blue < GAMMA_MIN ||
+ priv->pScrn->gamma.blue > GAMMA_MAX) {
+
+ xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
+ "The %s driver didn't call xf86SetGamma() to initialise\n"
+ "\tthe gamma values.\n", priv->pScrn->driverName);
+ xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
+ "PLEASE FIX THE `%s' DRIVER!\n", priv->pScrn->driverName);
+ priv->pScrn->gamma.red = 1.0;
+ priv->pScrn->gamma.green = 1.0;
+ priv->pScrn->gamma.blue = 1.0;
+ }
+#endif
+
+ RedGamma = 1.0 / (double)priv->pScrn->gamma.red;
+ GreenGamma = 1.0 / (double)priv->pScrn->gamma.green;
+ BlueGamma = 1.0 / (double)priv->pScrn->gamma.blue;
+
+ for(i = 0; i <= elements; i++) {
+ if(RedGamma == 1.0)
+ priv->gamma[i].red = i;
+ else
+ priv->gamma[i].red = (CARD16)(pow((double)i/(double)elements,
+ RedGamma) * (double)elements + 0.5);
+
+ if(GreenGamma == 1.0)
+ priv->gamma[i].green = i;
+ else
+ priv->gamma[i].green = (CARD16)(pow((double)i/(double)elements,
+ GreenGamma) * (double)elements + 0.5);
+
+ if(BlueGamma == 1.0)
+ priv->gamma[i].blue = i;
+ else
+ priv->gamma[i].blue = (CARD16)(pow((double)i/(double)elements,
+ BlueGamma) * (double)elements + 0.5);
+ }
+}
+
+
+int
+CMapChangeGamma(
+ int index,
+ Gamma gamma
+){
+ int ret = Success;
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = pScrn->pScreen;
+ CMapColormapPtr pColPriv;
+ CMapScreenPtr pScreenPriv;
+ CMapLinkPtr pLink;
+
+ /* Is this sufficient checking ? */
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if (gamma.red < GAMMA_MIN || gamma.red > GAMMA_MAX ||
+ gamma.green < GAMMA_MIN || gamma.green > GAMMA_MAX ||
+ gamma.blue < GAMMA_MIN || gamma.blue > GAMMA_MAX)
+ return BadValue;
+
+ pScrn->gamma.red = gamma.red;
+ pScrn->gamma.green = gamma.green;
+ pScrn->gamma.blue = gamma.blue;
+
+ ComputeGamma(pScreenPriv);
+
+ /* mark all colormaps on this screen */
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
+ CMapColormapKey);
+ pColPriv->recalculate = TRUE;
+ pLink = pLink->next;
+ }
+
+ if(GetInstalledmiColormap(pScreen) &&
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
+ pScrn->vtSema || pScreenPriv->isDGAmode)) {
+ ColormapPtr pMap = GetInstalledmiColormap(pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pMap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
+
+ /* if the current map doesn't have a palette look
+ for another map to change the gamma on. */
+
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ if(pLink->cmap->pVisual->class == PseudoColor)
+ break;
+ pLink = pLink->next;
+ }
+
+ if(pLink) {
+ /* need to trick CMapRefreshColors() into thinking
+ this is the currently installed map */
+ SetInstalledmiColormap(pScreen, pLink->cmap);
+ CMapReinstallMap(pLink->cmap);
+ SetInstalledmiColormap(pScreen, pMap);
+ }
+ } else
+ CMapReinstallMap(pMap);
+ }
+
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
+ if (pScrn->ChangeGamma)
+ ret = pScrn->ChangeGamma(index, gamma);
+ pScrn->ChangeGamma = CMapChangeGamma;
+
+ return ret;
+}
+
+
+static void
+ComputeGammaRamp (
+ CMapScreenPtr priv,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ int elements = priv->gammaElements;
+ LOCO *entry = priv->gamma;
+ int shift = 16 - priv->sigRGBbits;
+
+ while(elements--) {
+ entry->red = *(red++) >> shift;
+ entry->green = *(green++) >> shift;
+ entry->blue = *(blue++) >> shift;
+ entry++;
+ }
+}
+
+int
+xf86ChangeGammaRamp(
+ ScreenPtr pScreen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapColormapPtr pColPriv;
+ CMapScreenPtr pScreenPriv;
+ CMapLinkPtr pLink;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc) {
+ if (crtc->gammaSize != size)
+ return BadValue;
+
+ RRCrtcGammaSet(crtc, red, green, blue);
+
+ return Success;
+ }
+ }
+
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if(pScreenPriv->gammaElements != size)
+ return BadValue;
+
+ ComputeGammaRamp(pScreenPriv, red, green, blue);
+
+ /* mark all colormaps on this screen */
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
+ CMapColormapKey);
+ pColPriv->recalculate = TRUE;
+ pLink = pLink->next;
+ }
+
+ if(GetInstalledmiColormap(pScreen) &&
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
+ pScrn->vtSema || pScreenPriv->isDGAmode)) {
+ ColormapPtr pMap = GetInstalledmiColormap(pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pMap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
+
+ /* if the current map doesn't have a palette look
+ for another map to change the gamma on. */
+
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ if(pLink->cmap->pVisual->class == PseudoColor)
+ break;
+ pLink = pLink->next;
+ }
+
+ if(pLink) {
+ /* need to trick CMapRefreshColors() into thinking
+ this is the currently installed map */
+ SetInstalledmiColormap(pScreen, pLink->cmap);
+ CMapReinstallMap(pLink->cmap);
+ SetInstalledmiColormap(pScreen, pMap);
+ }
+ } else
+ CMapReinstallMap(pMap);
+ }
+
+ return Success;
+}
+
+int
+xf86GetGammaRampSize(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapScreenPtr pScreenPriv;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc)
+ return crtc->gammaSize;
+ }
+
+ if(CMapScreenKey == NULL) return 0;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv) return 0;
+
+ return pScreenPriv->gammaElements;
+}
+
+int
+xf86GetGammaRamp(
+ ScreenPtr pScreen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapScreenPtr pScreenPriv;
+ LOCO *entry;
+ int shift, sigbits;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc) {
+ if (crtc->gammaSize < size)
+ return BadValue;
+
+ if (!RRCrtcGammaGet(crtc))
+ return BadImplementation;
+
+ memcpy(red, crtc->gammaRed, size * sizeof(*red));
+ memcpy(green, crtc->gammaGreen, size * sizeof(*green));
+ memcpy(blue, crtc->gammaBlue, size * sizeof(*blue));
+
+ return Success;
+ }
+ }
+
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if(size > pScreenPriv->gammaElements)
+ return BadValue;
+
+ entry = pScreenPriv->gamma;
+ sigbits = pScreenPriv->sigRGBbits;
+
+ while(size--) {
+ *red = entry->red << (16 - sigbits);
+ *green = entry->green << (16 - sigbits);
+ *blue = entry->blue << (16 - sigbits);
+ shift = sigbits;
+ while(shift < 16) {
+ *red |= *red >> shift;
+ *green |= *green >> shift;
+ *blue |= *blue >> shift;
+ shift += sigbits;
+ }
+ red++; green++; blue++;
+ entry++;
+ }
+
+ return Success;
+}
+
+int
+xf86ChangeGamma(
+ ScreenPtr pScreen,
+ Gamma gamma
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if(pScrn->ChangeGamma)
+ return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
+
+ return BadImplementation;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86fbman.c b/xorg-server/hw/xfree86/common/xf86fbman.c
index 5b8871723..1ca27015f 100644
--- a/xorg-server/hw/xfree86/common/xf86fbman.c
+++ b/xorg-server/hw/xfree86/common/xf86fbman.c
@@ -1,1438 +1,1438 @@
-
-/*
- * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "xf86fbman.h"
-
-/*
-#define DEBUG
-*/
-
-static int xf86FBManagerKeyIndex;
-static DevPrivateKey xf86FBManagerKey;
-
-Bool xf86RegisterOffscreenManager(
- ScreenPtr pScreen,
- FBManagerFuncsPtr funcs
-){
-
- xf86FBManagerKey = &xf86FBManagerKeyIndex;
- dixSetPrivate(&pScreen->devPrivates, xf86FBManagerKey, funcs);
-
- return TRUE;
-}
-
-
-Bool
-xf86FBManagerRunning(ScreenPtr pScreen)
-{
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!dixLookupPrivate(&pScreen->devPrivates, xf86FBManagerKey))
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-xf86RegisterFreeBoxCallback(
- ScreenPtr pScreen,
- FreeBoxCallbackProcPtr FreeBoxCallback,
- pointer devPriv
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->RegisterFreeBoxCallback)(pScreen, FreeBoxCallback, devPriv);
-}
-
-
-FBAreaPtr
-xf86AllocateOffscreenArea(
- ScreenPtr pScreen,
- int w, int h,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- return (*funcs->AllocateOffscreenArea)(
- pScreen, w, h, gran, moveCB, removeCB, privData);
-}
-
-
-FBLinearPtr
-xf86AllocateOffscreenLinear(
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveLinearCallbackProcPtr moveCB,
- RemoveLinearCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- return (*funcs->AllocateOffscreenLinear)(
- pScreen, length, gran, moveCB, removeCB, privData);
-}
-
-
-void
-xf86FreeOffscreenArea(FBAreaPtr area)
-{
- FBManagerFuncsPtr funcs;
-
- if(!area) return;
-
- if(xf86FBManagerKey == NULL)
- return;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &area->pScreen->devPrivates, xf86FBManagerKey)))
- return;
-
- (*funcs->FreeOffscreenArea)(area);
-
- return;
-}
-
-
-void
-xf86FreeOffscreenLinear(FBLinearPtr linear)
-{
- FBManagerFuncsPtr funcs;
-
- if(!linear) return;
-
- if(xf86FBManagerKey == NULL)
- return;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &linear->pScreen->devPrivates, xf86FBManagerKey)))
- return;
-
- (*funcs->FreeOffscreenLinear)(linear);
-
- return;
-}
-
-
-Bool
-xf86ResizeOffscreenArea(
- FBAreaPtr resize,
- int w, int h
-){
- FBManagerFuncsPtr funcs;
-
- if(!resize) return FALSE;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &resize->pScreen->devPrivates, xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->ResizeOffscreenArea)(resize, w, h);
-}
-
-Bool
-xf86ResizeOffscreenLinear(
- FBLinearPtr resize,
- int size
-){
- FBManagerFuncsPtr funcs;
-
- if(!resize) return FALSE;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &resize->pScreen->devPrivates, xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->ResizeOffscreenLinear)(resize, size);
-}
-
-
-Bool
-xf86QueryLargestOffscreenArea(
- ScreenPtr pScreen,
- int *w, int *h,
- int gran,
- int preferences,
- int severity
-){
- FBManagerFuncsPtr funcs;
-
- *w = 0;
- *h = 0;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->QueryLargestOffscreenArea)(
- pScreen, w, h, gran, preferences, severity);
-}
-
-Bool
-xf86QueryLargestOffscreenLinear(
- ScreenPtr pScreen,
- int *size,
- int gran,
- int severity
-){
- FBManagerFuncsPtr funcs;
-
- *size = 0;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->QueryLargestOffscreenLinear)(
- pScreen, size, gran, severity);
-}
-
-
-Bool
-xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
-{
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->PurgeOffscreenAreas)(pScreen);
-}
-
-/************************************************************\
-
- Below is a specific implementation of an offscreen manager.
-
-\************************************************************/
-
-static int xf86FBScreenKeyIndex;
-static DevPrivateKey xf86FBScreenKey = &xf86FBScreenKeyIndex;
-
-typedef struct _FBLink {
- FBArea area;
- struct _FBLink *next;
-} FBLink, *FBLinkPtr;
-
-typedef struct _FBLinearLink {
- FBLinear linear;
- int free; /* need to add free here as FBLinear is publicly accessible */
- FBAreaPtr area; /* only used if allocation came from XY area */
- struct _FBLinearLink *next;
-} FBLinearLink, *FBLinearLinkPtr;
-
-
-typedef struct {
- ScreenPtr pScreen;
- RegionPtr InitialBoxes;
- RegionPtr FreeBoxes;
- FBLinkPtr UsedAreas;
- int NumUsedAreas;
- FBLinearLinkPtr LinearAreas;
- CloseScreenProcPtr CloseScreen;
- int NumCallbacks;
- FreeBoxCallbackProcPtr *FreeBoxesUpdateCallback;
- DevUnion *devPrivates;
-} FBManager, *FBManagerPtr;
-
-
-static void
-SendCallFreeBoxCallbacks(FBManagerPtr offman)
-{
- int i = offman->NumCallbacks;
-
- while(i--) {
- (*offman->FreeBoxesUpdateCallback[i])(
- offman->pScreen, offman->FreeBoxes, offman->devPrivates[i].ptr);
- }
-}
-
-static Bool
-localRegisterFreeBoxCallback(
- ScreenPtr pScreen,
- FreeBoxCallbackProcPtr FreeBoxCallback,
- pointer devPriv
-){
- FBManagerPtr offman;
- FreeBoxCallbackProcPtr *newCallbacks;
- DevUnion *newPrivates;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- newCallbacks = xrealloc( offman->FreeBoxesUpdateCallback,
- sizeof(FreeBoxCallbackProcPtr) * (offman->NumCallbacks + 1));
-
- newPrivates = xrealloc(offman->devPrivates,
- sizeof(DevUnion) * (offman->NumCallbacks + 1));
-
- if(!newCallbacks || !newPrivates)
- return FALSE;
-
- offman->FreeBoxesUpdateCallback = newCallbacks;
- offman->devPrivates = newPrivates;
-
- offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback;
- offman->devPrivates[offman->NumCallbacks].ptr = devPriv;
- offman->NumCallbacks++;
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
-}
-
-
-static FBAreaPtr
-AllocateArea(
- FBManagerPtr offman,
- int w, int h,
- int granularity,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- ScreenPtr pScreen = offman->pScreen;
- FBLinkPtr link = NULL;
- FBAreaPtr area = NULL;
- RegionRec NewReg;
- int i, x = 0, num;
- BoxPtr boxp;
-
- if(granularity <= 1) granularity = 0;
-
- boxp = REGION_RECTS(offman->FreeBoxes);
- num = REGION_NUM_RECTS(offman->FreeBoxes);
-
- /* look through the free boxes */
- for(i = 0; i < num; i++, boxp++) {
- x = boxp->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
- continue;
-
- link = xalloc(sizeof(FBLink));
- if(!link) return NULL;
-
- area = &(link->area);
- link->next = offman->UsedAreas;
- offman->UsedAreas = link;
- offman->NumUsedAreas++;
- break;
- }
-
- /* try to boot a removeable one out if we are not expendable ourselves */
- if(!area && !removeCB) {
- link = offman->UsedAreas;
-
- while(link) {
- if(!link->area.RemoveAreaCallback) {
- link = link->next;
- continue;
- }
-
- boxp = &(link->area.box);
- x = boxp->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
- link = link->next;
- continue;
- }
-
- /* bye, bye */
- (*link->area.RemoveAreaCallback)(&link->area);
- REGION_INIT(pScreen, &NewReg, &(link->area.box), 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
- REGION_UNINIT(pScreen, &NewReg);
-
- area = &(link->area);
- break;
- }
- }
-
- if(area) {
- area->pScreen = pScreen;
- area->granularity = granularity;
- area->box.x1 = x;
- area->box.x2 = x + w;
- area->box.y1 = boxp->y1;
- area->box.y2 = boxp->y1 + h;
- area->MoveAreaCallback = moveCB;
- area->RemoveAreaCallback = removeCB;
- area->devPrivate.ptr = privData;
-
- REGION_INIT(pScreen, &NewReg, &(area->box), 1);
- REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
- REGION_UNINIT(pScreen, &NewReg);
- }
-
- return area;
-}
-
-static FBAreaPtr
-localAllocateOffscreenArea(
- ScreenPtr pScreen,
- int w, int h,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerPtr offman;
- FBAreaPtr area = NULL;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- if((area = AllocateArea(offman, w, h, gran, moveCB, removeCB, privData)))
- SendCallFreeBoxCallbacks(offman);
-
- return area;
-}
-
-
-static void
-localFreeOffscreenArea(FBAreaPtr area)
-{
- FBManagerPtr offman;
- FBLinkPtr pLink, pLinkPrev = NULL;
- RegionRec FreedRegion;
- ScreenPtr pScreen;
-
- pScreen = area->pScreen;
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->UsedAreas;
- if(!pLink) return;
-
- while(&(pLink->area) != area) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- /* put the area back into the pool */
- REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedRegion);
- REGION_UNINIT(pScreen, &FreedRegion);
-
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- xfree(pLink);
- offman->NumUsedAreas--;
-
- SendCallFreeBoxCallbacks(offman);
-}
-
-
-
-static Bool
-localResizeOffscreenArea(
- FBAreaPtr resize,
- int w, int h
-){
- FBManagerPtr offman;
- ScreenPtr pScreen;
- BoxRec OrigArea;
- RegionRec FreedReg;
- FBAreaPtr area = NULL;
- FBLinkPtr pLink, newLink, pLinkPrev = NULL;
-
- pScreen = resize->pScreen;
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- /* find this link */
- if(!(pLink = offman->UsedAreas))
- return FALSE;
-
- while(&(pLink->area) != resize) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return FALSE;
- }
-
- OrigArea.x1 = resize->box.x1;
- OrigArea.x2 = resize->box.x2;
- OrigArea.y1 = resize->box.y1;
- OrigArea.y2 = resize->box.y2;
-
- /* if it's smaller, this is easy */
-
- if((w <= (resize->box.x2 - resize->box.x1)) &&
- (h <= (resize->box.y2 - resize->box.y1))) {
- RegionRec NewReg;
-
- resize->box.x2 = resize->box.x1 + w;
- resize->box.y2 = resize->box.y1 + h;
-
- if((resize->box.y2 == OrigArea.y2) &&
- (resize->box.x2 == OrigArea.x2))
- return TRUE;
-
- REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
- REGION_INIT(pScreen, &NewReg, &(resize->box), 1);
- REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
- REGION_UNINIT(pScreen, &FreedReg);
- REGION_UNINIT(pScreen, &NewReg);
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
- }
-
-
- /* otherwise we remove the old region */
-
- REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
-
- /* remove the old link */
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- /* and try to add a new one */
-
- if((area = AllocateArea(offman, w, h, resize->granularity,
- resize->MoveAreaCallback, resize->RemoveAreaCallback,
- resize->devPrivate.ptr))) {
-
- /* copy data over to our link and replace the new with old */
- memcpy(resize, area, sizeof(FBArea));
-
- pLinkPrev = NULL;
- newLink = offman->UsedAreas;
-
- while(&(newLink->area) != area) {
- pLinkPrev = newLink;
- newLink = newLink->next;
- }
-
- if(pLinkPrev)
- pLinkPrev->next = newLink->next;
- else offman->UsedAreas = newLink->next;
-
- pLink->next = offman->UsedAreas;
- offman->UsedAreas = pLink;
-
- xfree(newLink);
-
- /* AllocateArea added one but we really only exchanged one */
- offman->NumUsedAreas--;
- } else {
- /* reinstate the old region */
- REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
- REGION_UNINIT(pScreen, &FreedReg);
-
- pLink->next = offman->UsedAreas;
- offman->UsedAreas = pLink;
- return FALSE;
- }
-
-
- REGION_UNINIT(pScreen, &FreedReg);
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
-}
-
-static Bool
-localQueryLargestOffscreenArea(
- ScreenPtr pScreen,
- int *width, int *height,
- int granularity,
- int preferences,
- int severity
-){
- FBManagerPtr offman;
- RegionPtr newRegion = NULL;
- BoxPtr pbox;
- int nbox;
- int x, w, h, area, oldArea;
-
- *width = *height = oldArea = 0;
-
- if(granularity <= 1) granularity = 0;
-
- if((preferences < 0) || (preferences > 3))
- return FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- if(severity < 0) severity = 0;
- if(severity > 2) severity = 2;
-
- switch(severity) {
- case 2:
- if(offman->NumUsedAreas) {
- FBLinkPtr pLink;
- RegionRec tmpRegion;
- newRegion = REGION_CREATE(pScreen, NULL, 1);
- REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
- pLink = offman->UsedAreas;
-
- while(pLink) {
- if(!pLink->area.RemoveAreaCallback) {
- REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
- REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
- REGION_UNINIT(pScreen, &tmpRegion);
- }
- pLink = pLink->next;
- }
-
- nbox = REGION_NUM_RECTS(newRegion);
- pbox = REGION_RECTS(newRegion);
- break;
- }
- case 1:
- if(offman->NumUsedAreas) {
- FBLinkPtr pLink;
- RegionRec tmpRegion;
- newRegion = REGION_CREATE(pScreen, NULL, 1);
- REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
- pLink = offman->UsedAreas;
-
- while(pLink) {
- if(pLink->area.RemoveAreaCallback) {
- REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
- REGION_APPEND(pScreen, newRegion, &tmpRegion);
- REGION_UNINIT(pScreen, &tmpRegion);
- }
- pLink = pLink->next;
- }
-
- nbox = REGION_NUM_RECTS(newRegion);
- pbox = REGION_RECTS(newRegion);
- break;
- }
- default:
- nbox = REGION_NUM_RECTS(offman->FreeBoxes);
- pbox = REGION_RECTS(offman->FreeBoxes);
- break;
- }
-
- while(nbox--) {
- x = pbox->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- w = pbox->x2 - x;
- h = pbox->y2 - pbox->y1;
- area = w * h;
-
- if(w > 0) {
- Bool gotIt = FALSE;
- switch(preferences) {
- case FAVOR_AREA_THEN_WIDTH:
- if((area > oldArea) || ((area == oldArea) && (w > *width)))
- gotIt = TRUE;
- break;
- case FAVOR_AREA_THEN_HEIGHT:
- if((area > oldArea) || ((area == oldArea) && (h > *height)))
- gotIt = TRUE;
- break;
- case FAVOR_WIDTH_THEN_AREA:
- if((w > *width) || ((w == *width) && (area > oldArea)))
- gotIt = TRUE;
- break;
- case FAVOR_HEIGHT_THEN_AREA:
- if((h > *height) || ((h == *height) && (area > oldArea)))
- gotIt = TRUE;
- break;
- }
- if(gotIt) {
- *width = w;
- *height = h;
- oldArea = area;
- }
- }
- pbox++;
- }
-
- if(newRegion)
- REGION_DESTROY(pScreen, newRegion);
-
- return TRUE;
-}
-
-static Bool
-localPurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
-{
- FBManagerPtr offman;
- FBLinkPtr pLink, tmp, pPrev = NULL;
- RegionRec FreedRegion;
- Bool anyUsed = FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->UsedAreas;
- if(!pLink) return TRUE;
-
- while(pLink) {
- if(pLink->area.RemoveAreaCallback) {
- (*pLink->area.RemoveAreaCallback)(&pLink->area);
-
- REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
- REGION_APPEND(pScreen, offman->FreeBoxes, &FreedRegion);
- REGION_UNINIT(pScreen, &FreedRegion);
-
- if(pPrev)
- pPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- tmp = pLink;
- pLink = pLink->next;
- xfree(tmp);
- offman->NumUsedAreas--;
- anyUsed = TRUE;
- } else {
- pPrev = pLink;
- pLink = pLink->next;
- }
- }
-
- if(anyUsed) {
- REGION_VALIDATE(pScreen, offman->FreeBoxes, &anyUsed);
- SendCallFreeBoxCallbacks(offman);
- }
-
- return TRUE;
-}
-
-static void
-LinearMoveCBWrapper(FBAreaPtr from, FBAreaPtr to)
-{
- /* this will never get called */
-}
-
-static void
-LinearRemoveCBWrapper(FBAreaPtr area)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink, pLinkPrev = NULL;
- ScreenPtr pScreen = area->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return;
-
- while(pLink->area != area) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- /* give the user the callback it is expecting */
- (*pLink->linear.RemoveLinearCallback)(&(pLink->linear));
-
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->LinearAreas = pLink->next;
-
- xfree(pLink);
-}
-
-static void
-DumpDebug(FBLinearLinkPtr pLink)
-{
-#ifdef DEBUG
- if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n");
-
- while (pLink) {
- ErrorF(" Offset:%08x, Size:%08x, %s,%s\n",
- pLink->linear.offset,
- pLink->linear.size,
- pLink->free ? "Free" : "Used",
- pLink->area ? "Area" : "Linear");
-
- pLink = pLink->next;
- }
-#endif
-}
-
-static FBLinearPtr
-AllocateLinear(
- FBManagerPtr offman,
- int size,
- int granularity,
- pointer privData
-){
- ScreenPtr pScreen = offman->pScreen;
- FBLinearLinkPtr linear = NULL;
- FBLinearLinkPtr newlink = NULL;
- int offset, end;
-
- if(size <= 0) return NULL;
-
- if (!offman->LinearAreas) return NULL;
-
- linear = offman->LinearAreas;
- while (linear) {
- /* Make sure we get a free area that's not an XY fallback case */
- if (!linear->area && linear->free) {
- offset = linear->linear.offset;
- if (granularity > 1)
- offset = ((offset + granularity - 1) / granularity) * granularity;
- end = offset+size;
- if (end <= (linear->linear.offset + linear->linear.size))
- break;
- }
- linear = linear->next;
- }
- if (!linear)
- return NULL;
-
- /* break left */
- if (offset > linear->linear.offset) {
- newlink = xalloc(sizeof(FBLinearLink));
- if (!newlink)
- return NULL;
- newlink->area = NULL;
- newlink->linear.offset = offset;
- newlink->linear.size = linear->linear.size - (offset - linear->linear.offset);
- newlink->free = 1;
- newlink->next = linear->next;
- linear->linear.size -= newlink->linear.size;
- linear->next = newlink;
- linear = newlink;
- }
-
- /* break right */
- if (size < linear->linear.size) {
- newlink = xalloc(sizeof(FBLinearLink));
- if (!newlink)
- return NULL;
- newlink->area = NULL;
- newlink->linear.offset = offset + size;
- newlink->linear.size = linear->linear.size - size;
- newlink->free = 1;
- newlink->next = linear->next;
- linear->linear.size = size;
- linear->next = newlink;
- }
-
- /* p = middle block */
- linear->linear.granularity = granularity;
- linear->free = 0;
- linear->linear.pScreen = pScreen;
- linear->linear.MoveLinearCallback = NULL;
- linear->linear.RemoveLinearCallback = NULL;
- linear->linear.devPrivate.ptr = NULL;
-
- DumpDebug(offman->LinearAreas);
-
- return &(linear->linear);
-}
-
-static FBLinearPtr
-localAllocateOffscreenLinear(
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveLinearCallbackProcPtr moveCB,
- RemoveLinearCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerPtr offman;
- FBLinearLinkPtr link;
- FBAreaPtr area;
- FBLinearPtr linear = NULL;
- BoxPtr extents;
- int w, h, pitch;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
-
- /* Try to allocate from linear memory first...... */
- DebugF("ALLOCATING LINEAR\n");
- if ((linear = AllocateLinear(offman, length, gran, privData)))
- return linear;
-
- DebugF("NOPE, ALLOCATING AREA\n");
-
- if(!(link = xalloc(sizeof(FBLinearLink))))
- return NULL;
-
- /* No linear available, so try and pinch some from the XY areas */
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- pitch = extents->x2 - extents->x1;
-
- if (gran > 1) {
- if (gran > pitch) {
- /* we can't match the specified alignment with XY allocations */
- xfree(link);
- return NULL;
- }
-
- if (pitch % gran) {
- /* pitch and granularity aren't a perfect match, let's allocate
- * a bit more so we can align later on
- */
- length += gran - 1;
- }
- }
-
- if(length < pitch) { /* special case */
- w = length;
- h = 1;
- } else {
- w = pitch;
- h = (length + pitch - 1) / pitch;
- }
-
- if((area = localAllocateOffscreenArea(pScreen, w, h, gran,
- moveCB ? LinearMoveCBWrapper : NULL,
- removeCB ? LinearRemoveCBWrapper : NULL,
- privData)))
- {
- link->area = area;
- link->free = 0;
- link->next = offman->LinearAreas;
- offman->LinearAreas = link;
- linear = &(link->linear);
- linear->pScreen = pScreen;
- linear->size = h * w;
- linear->offset = (pitch * area->box.y1) + area->box.x1;
- if (gran > 1)
- linear->offset = ((linear->offset + gran - 1) / gran) * gran;
- linear->granularity = gran;
- linear->MoveLinearCallback = moveCB;
- linear->RemoveLinearCallback = removeCB;
- linear->devPrivate.ptr = privData;
- } else
- xfree(link);
-
- DumpDebug(offman->LinearAreas);
-
- return linear;
-}
-
-
-static void
-localFreeOffscreenLinear(FBLinearPtr linear)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink, pLinkPrev = NULL;
- ScreenPtr pScreen = linear->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return;
-
- while(&(pLink->linear) != linear) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- if(pLink->area) { /* really an XY area */
- DebugF("FREEING AREA\n");
- localFreeOffscreenArea(pLink->area);
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->LinearAreas = pLink->next;
- xfree(pLink);
- DumpDebug(offman->LinearAreas);
- return;
- }
-
- pLink->free = 1;
-
- if (pLink->next && pLink->next->free) {
- FBLinearLinkPtr p = pLink->next;
- pLink->linear.size += p->linear.size;
- pLink->next = p->next;
- free(p);
- }
-
- if(pLinkPrev) {
- if (pLinkPrev->next && pLinkPrev->next->free && !pLinkPrev->area) {
- FBLinearLinkPtr p = pLinkPrev->next;
- pLinkPrev->linear.size += p->linear.size;
- pLinkPrev->next = p->next;
- free(p);
- }
- }
-
- DebugF("FREEING LINEAR\n");
- DumpDebug(offman->LinearAreas);
-}
-
-
-static Bool
-localResizeOffscreenLinear(FBLinearPtr resize, int length)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink;
- ScreenPtr pScreen = resize->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return FALSE;
-
- while(&(pLink->linear) != resize) {
- pLink = pLink->next;
- if(!pLink) return FALSE;
- }
-
- /* This could actually be alot smarter and try to move allocations
- from XY to linear when available. For now if it was XY, we keep
- it XY */
-
- if(pLink->area) { /* really an XY area */
- BoxPtr extents;
- int pitch, w, h;
-
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- pitch = extents->x2 - extents->x1;
-
- if(length < pitch) { /* special case */
- w = length;
- h = 1;
- } else {
- w = pitch;
- h = (length + pitch - 1) / pitch;
- }
-
- if(localResizeOffscreenArea(pLink->area, w, h)) {
- resize->size = h * w;
- resize->offset = (pitch * pLink->area->box.y1) + pLink->area->box.x1;
- return TRUE;
- }
- } else {
- /* TODO!!!! resize the linear area */
- }
-
- return FALSE;
-}
-
-
-static Bool
-localQueryLargestOffscreenLinear(
- ScreenPtr pScreen,
- int *size,
- int gran,
- int priority
-)
-{
- FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- FBLinearLinkPtr pLink;
- FBLinearLinkPtr pLinkRet;
-
- *size = 0;
-
- pLink = offman->LinearAreas;
-
- if (pLink && !pLink->area) {
- pLinkRet = pLink;
- while (pLink) {
- if (pLink->free) {
- if (pLink->linear.size > pLinkRet->linear.size)
- pLinkRet = pLink;
- }
- pLink = pLink->next;
- }
-
- if (pLinkRet->free) {
- *size = pLinkRet->linear.size;
- return TRUE;
- }
- } else {
- int w, h;
-
- if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran,
- FAVOR_WIDTH_THEN_AREA, priority))
- {
- FBManagerPtr offman;
- BoxPtr extents;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- if((extents->x2 - extents->x1) == w)
- *size = w * h;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-
-static FBManagerFuncs xf86FBManFuncs = {
- localAllocateOffscreenArea,
- localFreeOffscreenArea,
- localResizeOffscreenArea,
- localQueryLargestOffscreenArea,
- localRegisterFreeBoxCallback,
- localAllocateOffscreenLinear,
- localFreeOffscreenLinear,
- localResizeOffscreenLinear,
- localQueryLargestOffscreenLinear,
- localPurgeUnlockedOffscreenAreas
- };
-
-
-static Bool
-xf86FBCloseScreen (int i, ScreenPtr pScreen)
-{
- FBLinkPtr pLink, tmp;
- FBLinearLinkPtr pLinearLink, tmp2;
- FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
-
- pScreen->CloseScreen = offman->CloseScreen;
-
- pLink = offman->UsedAreas;
- while(pLink) {
- tmp = pLink;
- pLink = pLink->next;
- xfree(tmp);
- }
-
- pLinearLink = offman->LinearAreas;
- while(pLinearLink) {
- tmp2 = pLinearLink;
- pLinearLink = pLinearLink->next;
- xfree(tmp2);
- }
-
- REGION_DESTROY(pScreen, offman->InitialBoxes);
- REGION_DESTROY(pScreen, offman->FreeBoxes);
-
- xfree(offman->FreeBoxesUpdateCallback);
- xfree(offman->devPrivates);
- xfree(offman);
- dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, NULL);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-xf86InitFBManager(
- ScreenPtr pScreen,
- BoxPtr FullBox
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RegionRec ScreenRegion;
- RegionRec FullRegion;
- BoxRec ScreenBox;
- Bool ret;
-
- ScreenBox.x1 = 0;
- ScreenBox.y1 = 0;
- ScreenBox.x2 = pScrn->virtualX;
- ScreenBox.y2 = pScrn->virtualY;
-
- if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
- (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
- return FALSE;
- }
-
- if (FullBox->y2 < FullBox->y1) return FALSE;
- if (FullBox->x2 < FullBox->x1) return FALSE;
-
- REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
- REGION_INIT(pScreen, &FullRegion, FullBox, 1);
-
- REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
-
- ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
-
- REGION_UNINIT(pScreen, &ScreenRegion);
- REGION_UNINIT(pScreen, &FullRegion);
-
- return ret;
-}
-
-Bool
-xf86InitFBManagerArea(
- ScreenPtr pScreen,
- int PixelArea,
- int Verbosity
-)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xRectangle Rect[3];
- RegionPtr pRegion, pScreenRegion;
- int nRect;
- Bool ret = FALSE;
-
- if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
- return FALSE;
-
- Rect[0].x = Rect[0].y = 0;
- Rect[0].width = pScrn->displayWidth;
- Rect[0].height = PixelArea / pScrn->displayWidth;
- nRect = 1;
-
- /* Add a possible partial scanline */
- if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
- Rect[1].x = 0;
- Rect[1].y = Rect[0].height;
- Rect[1].height = 1;
- nRect++;
- }
-
- /* Factor out virtual resolution */
- pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
- if (pRegion) {
- if (!REGION_NAR(pRegion)) {
- Rect[2].x = Rect[2].y = 0;
- Rect[2].width = pScrn->virtualX;
- Rect[2].height = pScrn->virtualY;
-
- pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
- if (pScreenRegion) {
- if (!REGION_NAR(pScreenRegion)) {
- REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);
-
- ret = xf86InitFBManagerRegion(pScreen, pRegion);
-
- if (ret && xf86GetVerbosity() >= Verbosity) {
- int scrnIndex = pScrn->scrnIndex;
-
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "Largest offscreen areas (with overlaps):\n");
-
- if (Rect[2].width < Rect[0].width) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at %d,0\n",
- Rect[0].width - Rect[2].width,
- Rect[0].height,
- Rect[2].width);
- }
- if (Rect[2].width < Rect[1].width) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at %d,0\n",
- Rect[1].width - Rect[2].width,
- Rect[0].height + Rect[1].height,
- Rect[2].width);
- }
- if (Rect[2].height < Rect[0].height) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at 0,%d\n",
- Rect[0].width,
- Rect[0].height - Rect[2].height,
- Rect[2].height);
- }
- if (Rect[1].height) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at 0,%d\n",
- Rect[1].width,
- Rect[0].height - Rect[2].height +
- Rect[1].height,
- Rect[2].height);
- }
- }
- }
-
- REGION_DESTROY(pScreen, pScreenRegion);
- }
- }
-
- REGION_DESTROY(pScreen, pRegion);
- }
-
- return ret;
-}
-
-Bool
-xf86InitFBManagerRegion(
- ScreenPtr pScreen,
- RegionPtr FullRegion
-){
- FBManagerPtr offman;
-
- if(REGION_NIL(FullRegion))
- return FALSE;
-
- if(!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
- return FALSE;
-
- offman = xalloc(sizeof(FBManager));
- if(!offman) return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman);
-
- offman->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86FBCloseScreen;
-
- offman->InitialBoxes = REGION_CREATE(pScreen, NULL, 1);
- offman->FreeBoxes = REGION_CREATE(pScreen, NULL, 1);
-
- REGION_COPY(pScreen, offman->InitialBoxes, FullRegion);
- REGION_COPY(pScreen, offman->FreeBoxes, FullRegion);
-
- offman->pScreen = pScreen;
- offman->UsedAreas = NULL;
- offman->LinearAreas = NULL;
- offman->NumUsedAreas = 0;
- offman->NumCallbacks = 0;
- offman->FreeBoxesUpdateCallback = NULL;
- offman->devPrivates = NULL;
-
- return TRUE;
-}
-
-Bool
-xf86InitFBManagerLinear(
- ScreenPtr pScreen,
- int offset,
- int size
-){
- FBManagerPtr offman;
- FBLinearLinkPtr link;
- FBLinearPtr linear;
-
- if (size <= 0)
- return FALSE;
-
- /* we expect people to have called the Area setup first for pixmap cache */
- if (!dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey))
- return FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- offman->LinearAreas = xalloc(sizeof(FBLinearLink));
- if (!offman->LinearAreas)
- return FALSE;
-
- link = offman->LinearAreas;
- link->area = NULL;
- link->next = NULL;
- link->free = 1;
- linear = &(link->linear);
- linear->pScreen = pScreen;
- linear->size = size;
- linear->offset = offset;
- linear->granularity = 0;
- linear->MoveLinearCallback = NULL;
- linear->RemoveLinearCallback = NULL;
- linear->devPrivate.ptr = NULL;
-
- return TRUE;
-}
-
-
-/* This is an implementation specific function and should
- disappear after the next release. People should use the
- real linear functions instead */
-
-FBAreaPtr
-xf86AllocateLinearOffscreenArea (
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
- FBManagerPtr offman;
- BoxPtr extents;
- int w, h;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- w = extents->x2 - extents->x1;
-
- if (gran > 1) {
- if (gran > w)
- return NULL;
-
- if (w % gran)
- length += gran - 1;
- }
-
- if(length <= w) { /* special case */
- h = 1;
- w = length;
- } else {
- h = (length + w - 1) / w;
- }
-
- return (*funcs->AllocateOffscreenArea)(
- pScreen, w, h, gran, moveCB, removeCB, privData);
-}
+
+/*
+ * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+
+/*
+#define DEBUG
+*/
+
+static int xf86FBManagerKeyIndex;
+static DevPrivateKey xf86FBManagerKey;
+
+Bool xf86RegisterOffscreenManager(
+ ScreenPtr pScreen,
+ FBManagerFuncsPtr funcs
+){
+
+ xf86FBManagerKey = &xf86FBManagerKeyIndex;
+ dixSetPrivate(&pScreen->devPrivates, xf86FBManagerKey, funcs);
+
+ return TRUE;
+}
+
+
+Bool
+xf86FBManagerRunning(ScreenPtr pScreen)
+{
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!dixLookupPrivate(&pScreen->devPrivates, xf86FBManagerKey))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+xf86RegisterFreeBoxCallback(
+ ScreenPtr pScreen,
+ FreeBoxCallbackProcPtr FreeBoxCallback,
+ pointer devPriv
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->RegisterFreeBoxCallback)(pScreen, FreeBoxCallback, devPriv);
+}
+
+
+FBAreaPtr
+xf86AllocateOffscreenArea(
+ ScreenPtr pScreen,
+ int w, int h,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ return (*funcs->AllocateOffscreenArea)(
+ pScreen, w, h, gran, moveCB, removeCB, privData);
+}
+
+
+FBLinearPtr
+xf86AllocateOffscreenLinear(
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ return (*funcs->AllocateOffscreenLinear)(
+ pScreen, length, gran, moveCB, removeCB, privData);
+}
+
+
+void
+xf86FreeOffscreenArea(FBAreaPtr area)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(!area) return;
+
+ if(xf86FBManagerKey == NULL)
+ return;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &area->pScreen->devPrivates, xf86FBManagerKey)))
+ return;
+
+ (*funcs->FreeOffscreenArea)(area);
+
+ return;
+}
+
+
+void
+xf86FreeOffscreenLinear(FBLinearPtr linear)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(!linear) return;
+
+ if(xf86FBManagerKey == NULL)
+ return;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &linear->pScreen->devPrivates, xf86FBManagerKey)))
+ return;
+
+ (*funcs->FreeOffscreenLinear)(linear);
+
+ return;
+}
+
+
+Bool
+xf86ResizeOffscreenArea(
+ FBAreaPtr resize,
+ int w, int h
+){
+ FBManagerFuncsPtr funcs;
+
+ if(!resize) return FALSE;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &resize->pScreen->devPrivates, xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->ResizeOffscreenArea)(resize, w, h);
+}
+
+Bool
+xf86ResizeOffscreenLinear(
+ FBLinearPtr resize,
+ int size
+){
+ FBManagerFuncsPtr funcs;
+
+ if(!resize) return FALSE;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &resize->pScreen->devPrivates, xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->ResizeOffscreenLinear)(resize, size);
+}
+
+
+Bool
+xf86QueryLargestOffscreenArea(
+ ScreenPtr pScreen,
+ int *w, int *h,
+ int gran,
+ int preferences,
+ int severity
+){
+ FBManagerFuncsPtr funcs;
+
+ *w = 0;
+ *h = 0;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->QueryLargestOffscreenArea)(
+ pScreen, w, h, gran, preferences, severity);
+}
+
+Bool
+xf86QueryLargestOffscreenLinear(
+ ScreenPtr pScreen,
+ int *size,
+ int gran,
+ int severity
+){
+ FBManagerFuncsPtr funcs;
+
+ *size = 0;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->QueryLargestOffscreenLinear)(
+ pScreen, size, gran, severity);
+}
+
+
+Bool
+xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->PurgeOffscreenAreas)(pScreen);
+}
+
+/************************************************************\
+
+ Below is a specific implementation of an offscreen manager.
+
+\************************************************************/
+
+static int xf86FBScreenKeyIndex;
+static DevPrivateKey xf86FBScreenKey = &xf86FBScreenKeyIndex;
+
+typedef struct _FBLink {
+ FBArea area;
+ struct _FBLink *next;
+} FBLink, *FBLinkPtr;
+
+typedef struct _FBLinearLink {
+ FBLinear linear;
+ int free; /* need to add free here as FBLinear is publicly accessible */
+ FBAreaPtr area; /* only used if allocation came from XY area */
+ struct _FBLinearLink *next;
+} FBLinearLink, *FBLinearLinkPtr;
+
+
+typedef struct {
+ ScreenPtr pScreen;
+ RegionPtr InitialBoxes;
+ RegionPtr FreeBoxes;
+ FBLinkPtr UsedAreas;
+ int NumUsedAreas;
+ FBLinearLinkPtr LinearAreas;
+ CloseScreenProcPtr CloseScreen;
+ int NumCallbacks;
+ FreeBoxCallbackProcPtr *FreeBoxesUpdateCallback;
+ DevUnion *devPrivates;
+} FBManager, *FBManagerPtr;
+
+
+static void
+SendCallFreeBoxCallbacks(FBManagerPtr offman)
+{
+ int i = offman->NumCallbacks;
+
+ while(i--) {
+ (*offman->FreeBoxesUpdateCallback[i])(
+ offman->pScreen, offman->FreeBoxes, offman->devPrivates[i].ptr);
+ }
+}
+
+static Bool
+localRegisterFreeBoxCallback(
+ ScreenPtr pScreen,
+ FreeBoxCallbackProcPtr FreeBoxCallback,
+ pointer devPriv
+){
+ FBManagerPtr offman;
+ FreeBoxCallbackProcPtr *newCallbacks;
+ DevUnion *newPrivates;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ newCallbacks = realloc( offman->FreeBoxesUpdateCallback,
+ sizeof(FreeBoxCallbackProcPtr) * (offman->NumCallbacks + 1));
+
+ newPrivates = realloc(offman->devPrivates,
+ sizeof(DevUnion) * (offman->NumCallbacks + 1));
+
+ if(!newCallbacks || !newPrivates)
+ return FALSE;
+
+ offman->FreeBoxesUpdateCallback = newCallbacks;
+ offman->devPrivates = newPrivates;
+
+ offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback;
+ offman->devPrivates[offman->NumCallbacks].ptr = devPriv;
+ offman->NumCallbacks++;
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+}
+
+
+static FBAreaPtr
+AllocateArea(
+ FBManagerPtr offman,
+ int w, int h,
+ int granularity,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ ScreenPtr pScreen = offman->pScreen;
+ FBLinkPtr link = NULL;
+ FBAreaPtr area = NULL;
+ RegionRec NewReg;
+ int i, x = 0, num;
+ BoxPtr boxp;
+
+ if(granularity <= 1) granularity = 0;
+
+ boxp = REGION_RECTS(offman->FreeBoxes);
+ num = REGION_NUM_RECTS(offman->FreeBoxes);
+
+ /* look through the free boxes */
+ for(i = 0; i < num; i++, boxp++) {
+ x = boxp->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
+ continue;
+
+ link = malloc(sizeof(FBLink));
+ if(!link) return NULL;
+
+ area = &(link->area);
+ link->next = offman->UsedAreas;
+ offman->UsedAreas = link;
+ offman->NumUsedAreas++;
+ break;
+ }
+
+ /* try to boot a removeable one out if we are not expendable ourselves */
+ if(!area && !removeCB) {
+ link = offman->UsedAreas;
+
+ while(link) {
+ if(!link->area.RemoveAreaCallback) {
+ link = link->next;
+ continue;
+ }
+
+ boxp = &(link->area.box);
+ x = boxp->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
+ link = link->next;
+ continue;
+ }
+
+ /* bye, bye */
+ (*link->area.RemoveAreaCallback)(&link->area);
+ REGION_INIT(pScreen, &NewReg, &(link->area.box), 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
+ REGION_UNINIT(pScreen, &NewReg);
+
+ area = &(link->area);
+ break;
+ }
+ }
+
+ if(area) {
+ area->pScreen = pScreen;
+ area->granularity = granularity;
+ area->box.x1 = x;
+ area->box.x2 = x + w;
+ area->box.y1 = boxp->y1;
+ area->box.y2 = boxp->y1 + h;
+ area->MoveAreaCallback = moveCB;
+ area->RemoveAreaCallback = removeCB;
+ area->devPrivate.ptr = privData;
+
+ REGION_INIT(pScreen, &NewReg, &(area->box), 1);
+ REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
+ REGION_UNINIT(pScreen, &NewReg);
+ }
+
+ return area;
+}
+
+static FBAreaPtr
+localAllocateOffscreenArea(
+ ScreenPtr pScreen,
+ int w, int h,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerPtr offman;
+ FBAreaPtr area = NULL;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ if((area = AllocateArea(offman, w, h, gran, moveCB, removeCB, privData)))
+ SendCallFreeBoxCallbacks(offman);
+
+ return area;
+}
+
+
+static void
+localFreeOffscreenArea(FBAreaPtr area)
+{
+ FBManagerPtr offman;
+ FBLinkPtr pLink, pLinkPrev = NULL;
+ RegionRec FreedRegion;
+ ScreenPtr pScreen;
+
+ pScreen = area->pScreen;
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->UsedAreas;
+ if(!pLink) return;
+
+ while(&(pLink->area) != area) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ /* put the area back into the pool */
+ REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedRegion);
+ REGION_UNINIT(pScreen, &FreedRegion);
+
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ free(pLink);
+ offman->NumUsedAreas--;
+
+ SendCallFreeBoxCallbacks(offman);
+}
+
+
+
+static Bool
+localResizeOffscreenArea(
+ FBAreaPtr resize,
+ int w, int h
+){
+ FBManagerPtr offman;
+ ScreenPtr pScreen;
+ BoxRec OrigArea;
+ RegionRec FreedReg;
+ FBAreaPtr area = NULL;
+ FBLinkPtr pLink, newLink, pLinkPrev = NULL;
+
+ pScreen = resize->pScreen;
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ /* find this link */
+ if(!(pLink = offman->UsedAreas))
+ return FALSE;
+
+ while(&(pLink->area) != resize) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return FALSE;
+ }
+
+ OrigArea.x1 = resize->box.x1;
+ OrigArea.x2 = resize->box.x2;
+ OrigArea.y1 = resize->box.y1;
+ OrigArea.y2 = resize->box.y2;
+
+ /* if it's smaller, this is easy */
+
+ if((w <= (resize->box.x2 - resize->box.x1)) &&
+ (h <= (resize->box.y2 - resize->box.y1))) {
+ RegionRec NewReg;
+
+ resize->box.x2 = resize->box.x1 + w;
+ resize->box.y2 = resize->box.y1 + h;
+
+ if((resize->box.y2 == OrigArea.y2) &&
+ (resize->box.x2 == OrigArea.x2))
+ return TRUE;
+
+ REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
+ REGION_INIT(pScreen, &NewReg, &(resize->box), 1);
+ REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+ REGION_UNINIT(pScreen, &FreedReg);
+ REGION_UNINIT(pScreen, &NewReg);
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+ }
+
+
+ /* otherwise we remove the old region */
+
+ REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+
+ /* remove the old link */
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ /* and try to add a new one */
+
+ if((area = AllocateArea(offman, w, h, resize->granularity,
+ resize->MoveAreaCallback, resize->RemoveAreaCallback,
+ resize->devPrivate.ptr))) {
+
+ /* copy data over to our link and replace the new with old */
+ memcpy(resize, area, sizeof(FBArea));
+
+ pLinkPrev = NULL;
+ newLink = offman->UsedAreas;
+
+ while(&(newLink->area) != area) {
+ pLinkPrev = newLink;
+ newLink = newLink->next;
+ }
+
+ if(pLinkPrev)
+ pLinkPrev->next = newLink->next;
+ else offman->UsedAreas = newLink->next;
+
+ pLink->next = offman->UsedAreas;
+ offman->UsedAreas = pLink;
+
+ free(newLink);
+
+ /* AllocateArea added one but we really only exchanged one */
+ offman->NumUsedAreas--;
+ } else {
+ /* reinstate the old region */
+ REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+ REGION_UNINIT(pScreen, &FreedReg);
+
+ pLink->next = offman->UsedAreas;
+ offman->UsedAreas = pLink;
+ return FALSE;
+ }
+
+
+ REGION_UNINIT(pScreen, &FreedReg);
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+}
+
+static Bool
+localQueryLargestOffscreenArea(
+ ScreenPtr pScreen,
+ int *width, int *height,
+ int granularity,
+ int preferences,
+ int severity
+){
+ FBManagerPtr offman;
+ RegionPtr newRegion = NULL;
+ BoxPtr pbox;
+ int nbox;
+ int x, w, h, area, oldArea;
+
+ *width = *height = oldArea = 0;
+
+ if(granularity <= 1) granularity = 0;
+
+ if((preferences < 0) || (preferences > 3))
+ return FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ if(severity < 0) severity = 0;
+ if(severity > 2) severity = 2;
+
+ switch(severity) {
+ case 2:
+ if(offman->NumUsedAreas) {
+ FBLinkPtr pLink;
+ RegionRec tmpRegion;
+ newRegion = REGION_CREATE(pScreen, NULL, 1);
+ REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
+ pLink = offman->UsedAreas;
+
+ while(pLink) {
+ if(!pLink->area.RemoveAreaCallback) {
+ REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
+ REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
+ REGION_UNINIT(pScreen, &tmpRegion);
+ }
+ pLink = pLink->next;
+ }
+
+ nbox = REGION_NUM_RECTS(newRegion);
+ pbox = REGION_RECTS(newRegion);
+ break;
+ }
+ case 1:
+ if(offman->NumUsedAreas) {
+ FBLinkPtr pLink;
+ RegionRec tmpRegion;
+ newRegion = REGION_CREATE(pScreen, NULL, 1);
+ REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
+ pLink = offman->UsedAreas;
+
+ while(pLink) {
+ if(pLink->area.RemoveAreaCallback) {
+ REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
+ REGION_APPEND(pScreen, newRegion, &tmpRegion);
+ REGION_UNINIT(pScreen, &tmpRegion);
+ }
+ pLink = pLink->next;
+ }
+
+ nbox = REGION_NUM_RECTS(newRegion);
+ pbox = REGION_RECTS(newRegion);
+ break;
+ }
+ default:
+ nbox = REGION_NUM_RECTS(offman->FreeBoxes);
+ pbox = REGION_RECTS(offman->FreeBoxes);
+ break;
+ }
+
+ while(nbox--) {
+ x = pbox->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ w = pbox->x2 - x;
+ h = pbox->y2 - pbox->y1;
+ area = w * h;
+
+ if(w > 0) {
+ Bool gotIt = FALSE;
+ switch(preferences) {
+ case FAVOR_AREA_THEN_WIDTH:
+ if((area > oldArea) || ((area == oldArea) && (w > *width)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_AREA_THEN_HEIGHT:
+ if((area > oldArea) || ((area == oldArea) && (h > *height)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_WIDTH_THEN_AREA:
+ if((w > *width) || ((w == *width) && (area > oldArea)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_HEIGHT_THEN_AREA:
+ if((h > *height) || ((h == *height) && (area > oldArea)))
+ gotIt = TRUE;
+ break;
+ }
+ if(gotIt) {
+ *width = w;
+ *height = h;
+ oldArea = area;
+ }
+ }
+ pbox++;
+ }
+
+ if(newRegion)
+ REGION_DESTROY(pScreen, newRegion);
+
+ return TRUE;
+}
+
+static Bool
+localPurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
+{
+ FBManagerPtr offman;
+ FBLinkPtr pLink, tmp, pPrev = NULL;
+ RegionRec FreedRegion;
+ Bool anyUsed = FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->UsedAreas;
+ if(!pLink) return TRUE;
+
+ while(pLink) {
+ if(pLink->area.RemoveAreaCallback) {
+ (*pLink->area.RemoveAreaCallback)(&pLink->area);
+
+ REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
+ REGION_APPEND(pScreen, offman->FreeBoxes, &FreedRegion);
+ REGION_UNINIT(pScreen, &FreedRegion);
+
+ if(pPrev)
+ pPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ tmp = pLink;
+ pLink = pLink->next;
+ free(tmp);
+ offman->NumUsedAreas--;
+ anyUsed = TRUE;
+ } else {
+ pPrev = pLink;
+ pLink = pLink->next;
+ }
+ }
+
+ if(anyUsed) {
+ REGION_VALIDATE(pScreen, offman->FreeBoxes, &anyUsed);
+ SendCallFreeBoxCallbacks(offman);
+ }
+
+ return TRUE;
+}
+
+static void
+LinearMoveCBWrapper(FBAreaPtr from, FBAreaPtr to)
+{
+ /* this will never get called */
+}
+
+static void
+LinearRemoveCBWrapper(FBAreaPtr area)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink, pLinkPrev = NULL;
+ ScreenPtr pScreen = area->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return;
+
+ while(pLink->area != area) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ /* give the user the callback it is expecting */
+ (*pLink->linear.RemoveLinearCallback)(&(pLink->linear));
+
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->LinearAreas = pLink->next;
+
+ free(pLink);
+}
+
+static void
+DumpDebug(FBLinearLinkPtr pLink)
+{
+#ifdef DEBUG
+ if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n");
+
+ while (pLink) {
+ ErrorF(" Offset:%08x, Size:%08x, %s,%s\n",
+ pLink->linear.offset,
+ pLink->linear.size,
+ pLink->free ? "Free" : "Used",
+ pLink->area ? "Area" : "Linear");
+
+ pLink = pLink->next;
+ }
+#endif
+}
+
+static FBLinearPtr
+AllocateLinear(
+ FBManagerPtr offman,
+ int size,
+ int granularity,
+ pointer privData
+){
+ ScreenPtr pScreen = offman->pScreen;
+ FBLinearLinkPtr linear = NULL;
+ FBLinearLinkPtr newlink = NULL;
+ int offset, end;
+
+ if(size <= 0) return NULL;
+
+ if (!offman->LinearAreas) return NULL;
+
+ linear = offman->LinearAreas;
+ while (linear) {
+ /* Make sure we get a free area that's not an XY fallback case */
+ if (!linear->area && linear->free) {
+ offset = linear->linear.offset;
+ if (granularity > 1)
+ offset = ((offset + granularity - 1) / granularity) * granularity;
+ end = offset+size;
+ if (end <= (linear->linear.offset + linear->linear.size))
+ break;
+ }
+ linear = linear->next;
+ }
+ if (!linear)
+ return NULL;
+
+ /* break left */
+ if (offset > linear->linear.offset) {
+ newlink = malloc(sizeof(FBLinearLink));
+ if (!newlink)
+ return NULL;
+ newlink->area = NULL;
+ newlink->linear.offset = offset;
+ newlink->linear.size = linear->linear.size - (offset - linear->linear.offset);
+ newlink->free = 1;
+ newlink->next = linear->next;
+ linear->linear.size -= newlink->linear.size;
+ linear->next = newlink;
+ linear = newlink;
+ }
+
+ /* break right */
+ if (size < linear->linear.size) {
+ newlink = malloc(sizeof(FBLinearLink));
+ if (!newlink)
+ return NULL;
+ newlink->area = NULL;
+ newlink->linear.offset = offset + size;
+ newlink->linear.size = linear->linear.size - size;
+ newlink->free = 1;
+ newlink->next = linear->next;
+ linear->linear.size = size;
+ linear->next = newlink;
+ }
+
+ /* p = middle block */
+ linear->linear.granularity = granularity;
+ linear->free = 0;
+ linear->linear.pScreen = pScreen;
+ linear->linear.MoveLinearCallback = NULL;
+ linear->linear.RemoveLinearCallback = NULL;
+ linear->linear.devPrivate.ptr = NULL;
+
+ DumpDebug(offman->LinearAreas);
+
+ return &(linear->linear);
+}
+
+static FBLinearPtr
+localAllocateOffscreenLinear(
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerPtr offman;
+ FBLinearLinkPtr link;
+ FBAreaPtr area;
+ FBLinearPtr linear = NULL;
+ BoxPtr extents;
+ int w, h, pitch;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+
+ /* Try to allocate from linear memory first...... */
+ DebugF("ALLOCATING LINEAR\n");
+ if ((linear = AllocateLinear(offman, length, gran, privData)))
+ return linear;
+
+ DebugF("NOPE, ALLOCATING AREA\n");
+
+ if(!(link = malloc(sizeof(FBLinearLink))))
+ return NULL;
+
+ /* No linear available, so try and pinch some from the XY areas */
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ pitch = extents->x2 - extents->x1;
+
+ if (gran > 1) {
+ if (gran > pitch) {
+ /* we can't match the specified alignment with XY allocations */
+ free(link);
+ return NULL;
+ }
+
+ if (pitch % gran) {
+ /* pitch and granularity aren't a perfect match, let's allocate
+ * a bit more so we can align later on
+ */
+ length += gran - 1;
+ }
+ }
+
+ if(length < pitch) { /* special case */
+ w = length;
+ h = 1;
+ } else {
+ w = pitch;
+ h = (length + pitch - 1) / pitch;
+ }
+
+ if((area = localAllocateOffscreenArea(pScreen, w, h, gran,
+ moveCB ? LinearMoveCBWrapper : NULL,
+ removeCB ? LinearRemoveCBWrapper : NULL,
+ privData)))
+ {
+ link->area = area;
+ link->free = 0;
+ link->next = offman->LinearAreas;
+ offman->LinearAreas = link;
+ linear = &(link->linear);
+ linear->pScreen = pScreen;
+ linear->size = h * w;
+ linear->offset = (pitch * area->box.y1) + area->box.x1;
+ if (gran > 1)
+ linear->offset = ((linear->offset + gran - 1) / gran) * gran;
+ linear->granularity = gran;
+ linear->MoveLinearCallback = moveCB;
+ linear->RemoveLinearCallback = removeCB;
+ linear->devPrivate.ptr = privData;
+ } else
+ free(link);
+
+ DumpDebug(offman->LinearAreas);
+
+ return linear;
+}
+
+
+static void
+localFreeOffscreenLinear(FBLinearPtr linear)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink, pLinkPrev = NULL;
+ ScreenPtr pScreen = linear->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return;
+
+ while(&(pLink->linear) != linear) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ if(pLink->area) { /* really an XY area */
+ DebugF("FREEING AREA\n");
+ localFreeOffscreenArea(pLink->area);
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->LinearAreas = pLink->next;
+ free(pLink);
+ DumpDebug(offman->LinearAreas);
+ return;
+ }
+
+ pLink->free = 1;
+
+ if (pLink->next && pLink->next->free) {
+ FBLinearLinkPtr p = pLink->next;
+ pLink->linear.size += p->linear.size;
+ pLink->next = p->next;
+ free(p);
+ }
+
+ if(pLinkPrev) {
+ if (pLinkPrev->next && pLinkPrev->next->free && !pLinkPrev->area) {
+ FBLinearLinkPtr p = pLinkPrev->next;
+ pLinkPrev->linear.size += p->linear.size;
+ pLinkPrev->next = p->next;
+ free(p);
+ }
+ }
+
+ DebugF("FREEING LINEAR\n");
+ DumpDebug(offman->LinearAreas);
+}
+
+
+static Bool
+localResizeOffscreenLinear(FBLinearPtr resize, int length)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink;
+ ScreenPtr pScreen = resize->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return FALSE;
+
+ while(&(pLink->linear) != resize) {
+ pLink = pLink->next;
+ if(!pLink) return FALSE;
+ }
+
+ /* This could actually be alot smarter and try to move allocations
+ from XY to linear when available. For now if it was XY, we keep
+ it XY */
+
+ if(pLink->area) { /* really an XY area */
+ BoxPtr extents;
+ int pitch, w, h;
+
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ pitch = extents->x2 - extents->x1;
+
+ if(length < pitch) { /* special case */
+ w = length;
+ h = 1;
+ } else {
+ w = pitch;
+ h = (length + pitch - 1) / pitch;
+ }
+
+ if(localResizeOffscreenArea(pLink->area, w, h)) {
+ resize->size = h * w;
+ resize->offset = (pitch * pLink->area->box.y1) + pLink->area->box.x1;
+ return TRUE;
+ }
+ } else {
+ /* TODO!!!! resize the linear area */
+ }
+
+ return FALSE;
+}
+
+
+static Bool
+localQueryLargestOffscreenLinear(
+ ScreenPtr pScreen,
+ int *size,
+ int gran,
+ int priority
+)
+{
+ FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ FBLinearLinkPtr pLink;
+ FBLinearLinkPtr pLinkRet;
+
+ *size = 0;
+
+ pLink = offman->LinearAreas;
+
+ if (pLink && !pLink->area) {
+ pLinkRet = pLink;
+ while (pLink) {
+ if (pLink->free) {
+ if (pLink->linear.size > pLinkRet->linear.size)
+ pLinkRet = pLink;
+ }
+ pLink = pLink->next;
+ }
+
+ if (pLinkRet->free) {
+ *size = pLinkRet->linear.size;
+ return TRUE;
+ }
+ } else {
+ int w, h;
+
+ if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran,
+ FAVOR_WIDTH_THEN_AREA, priority))
+ {
+ FBManagerPtr offman;
+ BoxPtr extents;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ if((extents->x2 - extents->x1) == w)
+ *size = w * h;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
+static FBManagerFuncs xf86FBManFuncs = {
+ localAllocateOffscreenArea,
+ localFreeOffscreenArea,
+ localResizeOffscreenArea,
+ localQueryLargestOffscreenArea,
+ localRegisterFreeBoxCallback,
+ localAllocateOffscreenLinear,
+ localFreeOffscreenLinear,
+ localResizeOffscreenLinear,
+ localQueryLargestOffscreenLinear,
+ localPurgeUnlockedOffscreenAreas
+ };
+
+
+static Bool
+xf86FBCloseScreen (int i, ScreenPtr pScreen)
+{
+ FBLinkPtr pLink, tmp;
+ FBLinearLinkPtr pLinearLink, tmp2;
+ FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+
+ pScreen->CloseScreen = offman->CloseScreen;
+
+ pLink = offman->UsedAreas;
+ while(pLink) {
+ tmp = pLink;
+ pLink = pLink->next;
+ free(tmp);
+ }
+
+ pLinearLink = offman->LinearAreas;
+ while(pLinearLink) {
+ tmp2 = pLinearLink;
+ pLinearLink = pLinearLink->next;
+ free(tmp2);
+ }
+
+ REGION_DESTROY(pScreen, offman->InitialBoxes);
+ REGION_DESTROY(pScreen, offman->FreeBoxes);
+
+ free(offman->FreeBoxesUpdateCallback);
+ free(offman->devPrivates);
+ free(offman);
+ dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, NULL);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+xf86InitFBManager(
+ ScreenPtr pScreen,
+ BoxPtr FullBox
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RegionRec ScreenRegion;
+ RegionRec FullRegion;
+ BoxRec ScreenBox;
+ Bool ret;
+
+ ScreenBox.x1 = 0;
+ ScreenBox.y1 = 0;
+ ScreenBox.x2 = pScrn->virtualX;
+ ScreenBox.y2 = pScrn->virtualY;
+
+ if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
+ (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
+ return FALSE;
+ }
+
+ if (FullBox->y2 < FullBox->y1) return FALSE;
+ if (FullBox->x2 < FullBox->x1) return FALSE;
+
+ REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
+ REGION_INIT(pScreen, &FullRegion, FullBox, 1);
+
+ REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
+
+ ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
+
+ REGION_UNINIT(pScreen, &ScreenRegion);
+ REGION_UNINIT(pScreen, &FullRegion);
+
+ return ret;
+}
+
+Bool
+xf86InitFBManagerArea(
+ ScreenPtr pScreen,
+ int PixelArea,
+ int Verbosity
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xRectangle Rect[3];
+ RegionPtr pRegion, pScreenRegion;
+ int nRect;
+ Bool ret = FALSE;
+
+ if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
+ return FALSE;
+
+ Rect[0].x = Rect[0].y = 0;
+ Rect[0].width = pScrn->displayWidth;
+ Rect[0].height = PixelArea / pScrn->displayWidth;
+ nRect = 1;
+
+ /* Add a possible partial scanline */
+ if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
+ Rect[1].x = 0;
+ Rect[1].y = Rect[0].height;
+ Rect[1].height = 1;
+ nRect++;
+ }
+
+ /* Factor out virtual resolution */
+ pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
+ if (pRegion) {
+ if (!REGION_NAR(pRegion)) {
+ Rect[2].x = Rect[2].y = 0;
+ Rect[2].width = pScrn->virtualX;
+ Rect[2].height = pScrn->virtualY;
+
+ pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
+ if (pScreenRegion) {
+ if (!REGION_NAR(pScreenRegion)) {
+ REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);
+
+ ret = xf86InitFBManagerRegion(pScreen, pRegion);
+
+ if (ret && xf86GetVerbosity() >= Verbosity) {
+ int scrnIndex = pScrn->scrnIndex;
+
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "Largest offscreen areas (with overlaps):\n");
+
+ if (Rect[2].width < Rect[0].width) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at %d,0\n",
+ Rect[0].width - Rect[2].width,
+ Rect[0].height,
+ Rect[2].width);
+ }
+ if (Rect[2].width < Rect[1].width) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at %d,0\n",
+ Rect[1].width - Rect[2].width,
+ Rect[0].height + Rect[1].height,
+ Rect[2].width);
+ }
+ if (Rect[2].height < Rect[0].height) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at 0,%d\n",
+ Rect[0].width,
+ Rect[0].height - Rect[2].height,
+ Rect[2].height);
+ }
+ if (Rect[1].height) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at 0,%d\n",
+ Rect[1].width,
+ Rect[0].height - Rect[2].height +
+ Rect[1].height,
+ Rect[2].height);
+ }
+ }
+ }
+
+ REGION_DESTROY(pScreen, pScreenRegion);
+ }
+ }
+
+ REGION_DESTROY(pScreen, pRegion);
+ }
+
+ return ret;
+}
+
+Bool
+xf86InitFBManagerRegion(
+ ScreenPtr pScreen,
+ RegionPtr FullRegion
+){
+ FBManagerPtr offman;
+
+ if(REGION_NIL(FullRegion))
+ return FALSE;
+
+ if(!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
+ return FALSE;
+
+ offman = malloc(sizeof(FBManager));
+ if(!offman) return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman);
+
+ offman->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86FBCloseScreen;
+
+ offman->InitialBoxes = REGION_CREATE(pScreen, NULL, 1);
+ offman->FreeBoxes = REGION_CREATE(pScreen, NULL, 1);
+
+ REGION_COPY(pScreen, offman->InitialBoxes, FullRegion);
+ REGION_COPY(pScreen, offman->FreeBoxes, FullRegion);
+
+ offman->pScreen = pScreen;
+ offman->UsedAreas = NULL;
+ offman->LinearAreas = NULL;
+ offman->NumUsedAreas = 0;
+ offman->NumCallbacks = 0;
+ offman->FreeBoxesUpdateCallback = NULL;
+ offman->devPrivates = NULL;
+
+ return TRUE;
+}
+
+Bool
+xf86InitFBManagerLinear(
+ ScreenPtr pScreen,
+ int offset,
+ int size
+){
+ FBManagerPtr offman;
+ FBLinearLinkPtr link;
+ FBLinearPtr linear;
+
+ if (size <= 0)
+ return FALSE;
+
+ /* we expect people to have called the Area setup first for pixmap cache */
+ if (!dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey))
+ return FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ offman->LinearAreas = malloc(sizeof(FBLinearLink));
+ if (!offman->LinearAreas)
+ return FALSE;
+
+ link = offman->LinearAreas;
+ link->area = NULL;
+ link->next = NULL;
+ link->free = 1;
+ linear = &(link->linear);
+ linear->pScreen = pScreen;
+ linear->size = size;
+ linear->offset = offset;
+ linear->granularity = 0;
+ linear->MoveLinearCallback = NULL;
+ linear->RemoveLinearCallback = NULL;
+ linear->devPrivate.ptr = NULL;
+
+ return TRUE;
+}
+
+
+/* This is an implementation specific function and should
+ disappear after the next release. People should use the
+ real linear functions instead */
+
+FBAreaPtr
+xf86AllocateLinearOffscreenArea (
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+ FBManagerPtr offman;
+ BoxPtr extents;
+ int w, h;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ w = extents->x2 - extents->x1;
+
+ if (gran > 1) {
+ if (gran > w)
+ return NULL;
+
+ if (w % gran)
+ length += gran - 1;
+ }
+
+ if(length <= w) { /* special case */
+ h = 1;
+ w = length;
+ } else {
+ h = (length + w - 1) / w;
+ }
+
+ return (*funcs->AllocateOffscreenArea)(
+ pScreen, w, h, gran, moveCB, removeCB, privData);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c
index ac018e739..b3164730c 100644
--- a/xorg-server/hw/xfree86/common/xf86pciBus.c
+++ b/xorg-server/hw/xfree86/common/xf86pciBus.c
@@ -1,423 +1,423 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the interfaces to the bus-specific code
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include <pciaccess.h>
-#include "os.h"
-#include "Pci.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-/* Bus-specific headers */
-#include "xf86Bus.h"
-
-#define XF86_OS_PRIVS
-#include "xf86_OSproc.h"
-
-
-/* Bus-specific globals */
-Bool pciSlotClaimed = FALSE;
-
-#define PCIINFOCLASSES(c) \
- ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
- || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
-
-/*
- * PCI classes that have messages printed always. The others are only
- * have a message printed when the vendor/dev IDs are recognised.
- */
-#define PCIALWAYSPRINTCLASSES(c) \
- ( (((c) & 0x00ffff00) \
- == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \
- || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) )
-
-#define IS_VGA(c) \
- (((c) & 0x00ffff00) \
- == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
-
-void
-xf86FormatPciBusNumber(int busnum, char *buffer)
-{
- /* 'buffer' should be at least 8 characters long */
- if (busnum < 256)
- sprintf(buffer, "%d", busnum);
- else
- sprintf(buffer, "%d@%d", busnum & 0x00ff, busnum >> 8);
-}
-
-/*
- * xf86Bus.c interface
- */
-
-void
-xf86PciProbe(void)
-{
- int i = 0, k;
- int num = 0;
- struct pci_device *info;
- struct pci_device_iterator *iter;
- struct pci_device ** xf86PciVideoInfo = NULL;
-
-
- if (!xf86scanpci()) {
- xf86PciVideoInfo = NULL;
- return;
- }
-
- iter = pci_slot_match_iterator_create(& xf86IsolateDevice);
- while ((info = pci_device_next(iter)) != NULL) {
- if (PCIINFOCLASSES(info->device_class)) {
- num++;
- xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
- (sizeof(struct pci_device *)
- * (num + 1)));
- xf86PciVideoInfo[num] = NULL;
- xf86PciVideoInfo[num - 1] = info;
-
- pci_device_probe(info);
-#ifdef HAVE_PCI_DEVICE_IS_BOOT_VGA
- if (pci_device_is_boot_vga(info)) {
- primaryBus.type = BUS_PCI;
- primaryBus.id.pci = info;
- }
-#endif
- info->user_data = 0;
- }
- }
- free(iter);
-
- /* If we haven't found a primary device try a different heuristic */
- if (primaryBus.type == BUS_NONE && num) {
- for (i = 0; i < num; i++) {
- uint16_t command;
-
- info = xf86PciVideoInfo[i];
- pci_device_cfg_read_u16(info, & command, 4);
-
- if ((command & PCI_CMD_MEM_ENABLE)
- && ((num == 1) || IS_VGA(info->device_class))) {
- if (primaryBus.type == BUS_NONE) {
- primaryBus.type = BUS_PCI;
- primaryBus.id.pci = info;
- } else {
- xf86Msg(X_NOTICE,
- "More than one possible primary device found\n");
- primaryBus.type ^= (BusType)(-1);
- }
- }
- }
- }
-
- /* Print a summary of the video devices found */
- for (k = 0; k < num; k++) {
- const char *vendorname = NULL, *chipname = NULL;
- const char *prim = " ";
- Bool memdone = FALSE, iodone = FALSE;
-
-
- info = xf86PciVideoInfo[k];
-
- vendorname = pci_device_get_vendor_name( info );
- chipname = pci_device_get_device_name( info );
-
- if ((!vendorname || !chipname) &&
- !PCIALWAYSPRINTCLASSES(info->device_class))
- continue;
-
- if (xf86IsPrimaryPci(info))
- prim = "*";
-
- xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
- info->domain, info->bus, info->dev, info->func,
- info->vendor_id, info->device_id,
- info->subvendor_id, info->subdevice_id);
-
- if (vendorname)
- xf86ErrorF("%s ", vendorname);
-
- if (chipname)
- xf86ErrorF("%s ", chipname);
-
- xf86ErrorF("rev %d", info->revision);
-
- for (i = 0; i < 6; i++) {
- struct pci_mem_region * r = & info->regions[i];
-
- if ( r->size && ! r->is_IO ) {
- if (!memdone) {
- xf86ErrorF(", Mem @ ");
- memdone = TRUE;
- } else
- xf86ErrorF(", ");
- xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
- }
- }
-
- for (i = 0; i < 6; i++) {
- struct pci_mem_region * r = & info->regions[i];
-
- if ( r->size && r->is_IO ) {
- if (!iodone) {
- xf86ErrorF(", I/O @ ");
- iodone = TRUE;
- } else
- xf86ErrorF(", ");
- xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
- }
- }
-
- if ( info->rom_size ) {
- xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld", (long)info->rom_size);
- }
-
- xf86ErrorF("\n");
- }
- xfree(xf86PciVideoInfo);
-}
-
-/*
- * If the slot requested is already in use, return -1.
- * Otherwise, claim the slot for the screen requesting it.
- */
-
-int
-xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp,
- int chipset, GDevPtr dev, Bool active)
-{
- EntityPtr p = NULL;
- int num;
-
- if (xf86CheckPciSlot(d)) {
- num = xf86AllocateEntity();
- p = xf86Entities[num];
- p->driver = drvp;
- p->chipset = chipset;
- p->bus.type = BUS_PCI;
- p->bus.id.pci = d;
- p->active = active;
- p->inUse = FALSE;
- if (dev)
- xf86AddDevToEntity(num, dev);
- pciSlotClaimed = TRUE;
-
- if (active) {
- /* Map in this domain's I/O space */
- p->domainIO = xf86MapLegacyIO(d);
- }
-
- return num;
- } else
- return -1;
-}
-
-/*
- * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
- */
-void
-xf86UnclaimPciSlot(struct pci_device *d)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- const EntityPtr p = xf86Entities[i];
-
- if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
- /* Probably the slot should be deallocated? */
- p->bus.type = BUS_NONE;
- return;
- }
- }
-}
-
-/*
- * Parse a BUS ID string, and return the PCI bus parameters if it was
- * in the correct format for a PCI bus id.
- */
-
-Bool
-xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func)
-{
- /*
- * The format is assumed to be "bus[@domain]:device[:func]", where domain,
- * bus, device and func are decimal integers. domain and func may be
- * omitted and assumed to be zero, although doing this isn't encouraged.
- */
-
- char *p, *s, *d;
- const char *id;
- int i;
-
- if (StringToBusType(busID, &id) != BUS_PCI)
- return FALSE;
-
- s = xstrdup(id);
- p = strtok(s, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return FALSE;
- }
- d = strpbrk(p, "@");
- if (d != NULL) {
- *(d++) = 0;
- for (i = 0; d[i] != 0; i++) {
- if (!isdigit(d[i])) {
- xfree(s);
- return FALSE;
- }
- }
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *bus = atoi(p);
- if (d != NULL && *d != 0)
- *bus += atoi(d) << 8;
- p = strtok(NULL, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return FALSE;
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *device = atoi(p);
- *func = 0;
- p = strtok(NULL, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return TRUE;
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *func = atoi(p);
- xfree(s);
- return TRUE;
-}
-
-/*
- * Compare a BUS ID string with a PCI bus id. Return TRUE if they match.
- */
-
-Bool
-xf86ComparePciBusString(const char *busID, int bus, int device, int func)
-{
- int ibus, idevice, ifunc;
-
- if (xf86ParsePciBusString(busID, &ibus, &idevice, &ifunc)) {
- return bus == ibus && device == idevice && func == ifunc;
- } else {
- return FALSE;
- }
-}
-
-/*
- * xf86IsPrimaryPci() -- return TRUE if primary device
- * is PCI and bus, dev and func numbers match.
- */
-
-Bool
-xf86IsPrimaryPci(struct pci_device *pPci)
-{
- return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
-}
-
-/*
- * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
- */
-struct pci_device *
-xf86GetPciInfoForEntity(int entityIndex)
-{
- EntityPtr p;
-
- if (entityIndex >= xf86NumEntities)
- return NULL;
-
- p = xf86Entities[entityIndex];
- return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
-}
-
-/*
- * xf86CheckPciMemBase() checks that the memory base value matches one of the
- * PCI base address register values for the given PCI device.
- */
-Bool
-xf86CheckPciMemBase( struct pci_device * pPci, memType base )
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (base == pPci->regions[i].base_addr)
- return TRUE;
- return FALSE;
-}
-
-/*
- * Check if the slot requested is free. If it is already in use, return FALSE.
- */
-
-Bool
-xf86CheckPciSlot(const struct pci_device *d)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- const EntityPtr p = xf86Entities[i];
-
- if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the interfaces to the bus-specific code
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include <pciaccess.h>
+#include "os.h"
+#include "Pci.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+/* Bus-specific headers */
+#include "xf86Bus.h"
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+
+
+/* Bus-specific globals */
+Bool pciSlotClaimed = FALSE;
+
+#define PCIINFOCLASSES(c) \
+ ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
+ || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
+
+/*
+ * PCI classes that have messages printed always. The others are only
+ * have a message printed when the vendor/dev IDs are recognised.
+ */
+#define PCIALWAYSPRINTCLASSES(c) \
+ ( (((c) & 0x00ffff00) \
+ == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \
+ || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) )
+
+#define IS_VGA(c) \
+ (((c) & 0x00ffff00) \
+ == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
+
+void
+xf86FormatPciBusNumber(int busnum, char *buffer)
+{
+ /* 'buffer' should be at least 8 characters long */
+ if (busnum < 256)
+ sprintf(buffer, "%d", busnum);
+ else
+ sprintf(buffer, "%d@%d", busnum & 0x00ff, busnum >> 8);
+}
+
+/*
+ * xf86Bus.c interface
+ */
+
+void
+xf86PciProbe(void)
+{
+ int i = 0, k;
+ int num = 0;
+ struct pci_device *info;
+ struct pci_device_iterator *iter;
+ struct pci_device ** xf86PciVideoInfo = NULL;
+
+
+ if (!xf86scanpci()) {
+ xf86PciVideoInfo = NULL;
+ return;
+ }
+
+ iter = pci_slot_match_iterator_create(& xf86IsolateDevice);
+ while ((info = pci_device_next(iter)) != NULL) {
+ if (PCIINFOCLASSES(info->device_class)) {
+ num++;
+ xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
+ (sizeof(struct pci_device *)
+ * (num + 1)));
+ xf86PciVideoInfo[num] = NULL;
+ xf86PciVideoInfo[num - 1] = info;
+
+ pci_device_probe(info);
+#ifdef HAVE_PCI_DEVICE_IS_BOOT_VGA
+ if (pci_device_is_boot_vga(info)) {
+ primaryBus.type = BUS_PCI;
+ primaryBus.id.pci = info;
+ }
+#endif
+ info->user_data = 0;
+ }
+ }
+ free(iter);
+
+ /* If we haven't found a primary device try a different heuristic */
+ if (primaryBus.type == BUS_NONE && num) {
+ for (i = 0; i < num; i++) {
+ uint16_t command;
+
+ info = xf86PciVideoInfo[i];
+ pci_device_cfg_read_u16(info, & command, 4);
+
+ if ((command & PCI_CMD_MEM_ENABLE)
+ && ((num == 1) || IS_VGA(info->device_class))) {
+ if (primaryBus.type == BUS_NONE) {
+ primaryBus.type = BUS_PCI;
+ primaryBus.id.pci = info;
+ } else {
+ xf86Msg(X_NOTICE,
+ "More than one possible primary device found\n");
+ primaryBus.type ^= (BusType)(-1);
+ }
+ }
+ }
+ }
+
+ /* Print a summary of the video devices found */
+ for (k = 0; k < num; k++) {
+ const char *vendorname = NULL, *chipname = NULL;
+ const char *prim = " ";
+ Bool memdone = FALSE, iodone = FALSE;
+
+
+ info = xf86PciVideoInfo[k];
+
+ vendorname = pci_device_get_vendor_name( info );
+ chipname = pci_device_get_device_name( info );
+
+ if ((!vendorname || !chipname) &&
+ !PCIALWAYSPRINTCLASSES(info->device_class))
+ continue;
+
+ if (xf86IsPrimaryPci(info))
+ prim = "*";
+
+ xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
+ info->domain, info->bus, info->dev, info->func,
+ info->vendor_id, info->device_id,
+ info->subvendor_id, info->subdevice_id);
+
+ if (vendorname)
+ xf86ErrorF("%s ", vendorname);
+
+ if (chipname)
+ xf86ErrorF("%s ", chipname);
+
+ xf86ErrorF("rev %d", info->revision);
+
+ for (i = 0; i < 6; i++) {
+ struct pci_mem_region * r = & info->regions[i];
+
+ if ( r->size && ! r->is_IO ) {
+ if (!memdone) {
+ xf86ErrorF(", Mem @ ");
+ memdone = TRUE;
+ } else
+ xf86ErrorF(", ");
+ xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
+ }
+ }
+
+ for (i = 0; i < 6; i++) {
+ struct pci_mem_region * r = & info->regions[i];
+
+ if ( r->size && r->is_IO ) {
+ if (!iodone) {
+ xf86ErrorF(", I/O @ ");
+ iodone = TRUE;
+ } else
+ xf86ErrorF(", ");
+ xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
+ }
+ }
+
+ if ( info->rom_size ) {
+ xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld", (long)info->rom_size);
+ }
+
+ xf86ErrorF("\n");
+ }
+ free(xf86PciVideoInfo);
+}
+
+/*
+ * If the slot requested is already in use, return -1.
+ * Otherwise, claim the slot for the screen requesting it.
+ */
+
+int
+xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+ int num;
+
+ if (xf86CheckPciSlot(d)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = chipset;
+ p->bus.type = BUS_PCI;
+ p->bus.id.pci = d;
+ p->active = active;
+ p->inUse = FALSE;
+ if (dev)
+ xf86AddDevToEntity(num, dev);
+ pciSlotClaimed = TRUE;
+
+ if (active) {
+ /* Map in this domain's I/O space */
+ p->domainIO = xf86MapLegacyIO(d);
+ }
+
+ return num;
+ } else
+ return -1;
+}
+
+/*
+ * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
+ */
+void
+xf86UnclaimPciSlot(struct pci_device *d)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr p = xf86Entities[i];
+
+ if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
+ /* Probably the slot should be deallocated? */
+ p->bus.type = BUS_NONE;
+ return;
+ }
+ }
+}
+
+/*
+ * Parse a BUS ID string, and return the PCI bus parameters if it was
+ * in the correct format for a PCI bus id.
+ */
+
+Bool
+xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func)
+{
+ /*
+ * The format is assumed to be "bus[@domain]:device[:func]", where domain,
+ * bus, device and func are decimal integers. domain and func may be
+ * omitted and assumed to be zero, although doing this isn't encouraged.
+ */
+
+ char *p, *s, *d;
+ const char *id;
+ int i;
+
+ if (StringToBusType(busID, &id) != BUS_PCI)
+ return FALSE;
+
+ s = xstrdup(id);
+ p = strtok(s, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return FALSE;
+ }
+ d = strpbrk(p, "@");
+ if (d != NULL) {
+ *(d++) = 0;
+ for (i = 0; d[i] != 0; i++) {
+ if (!isdigit(d[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *bus = atoi(p);
+ if (d != NULL && *d != 0)
+ *bus += atoi(d) << 8;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return FALSE;
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *device = atoi(p);
+ *func = 0;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return TRUE;
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *func = atoi(p);
+ free(s);
+ return TRUE;
+}
+
+/*
+ * Compare a BUS ID string with a PCI bus id. Return TRUE if they match.
+ */
+
+Bool
+xf86ComparePciBusString(const char *busID, int bus, int device, int func)
+{
+ int ibus, idevice, ifunc;
+
+ if (xf86ParsePciBusString(busID, &ibus, &idevice, &ifunc)) {
+ return bus == ibus && device == idevice && func == ifunc;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * xf86IsPrimaryPci() -- return TRUE if primary device
+ * is PCI and bus, dev and func numbers match.
+ */
+
+Bool
+xf86IsPrimaryPci(struct pci_device *pPci)
+{
+ return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
+}
+
+/*
+ * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
+ */
+struct pci_device *
+xf86GetPciInfoForEntity(int entityIndex)
+{
+ EntityPtr p;
+
+ if (entityIndex >= xf86NumEntities)
+ return NULL;
+
+ p = xf86Entities[entityIndex];
+ return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
+}
+
+/*
+ * xf86CheckPciMemBase() checks that the memory base value matches one of the
+ * PCI base address register values for the given PCI device.
+ */
+Bool
+xf86CheckPciMemBase( struct pci_device * pPci, memType base )
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ if (base == pPci->regions[i].base_addr)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Check if the slot requested is free. If it is already in use, return FALSE.
+ */
+
+Bool
+xf86CheckPciSlot(const struct pci_device *d)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr p = xf86Entities[i];
+
+ if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c
index 7b23233aa..8df3a6c7a 100644
--- a/xorg-server/hw/xfree86/common/xf86sbusBus.c
+++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c
@@ -1,688 +1,688 @@
-/*
- * SBUS bus-specific code.
- *
- * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86cmap.h"
-
-#include "xf86Bus.h"
-
-#include "xf86sbusBus.h"
-#include "xf86Sbus.h"
-
-Bool sbusSlotClaimed = FALSE;
-
-static int xf86nSbusInfo;
-
-static void
-CheckSbusDevice(const char *device, int fbNum)
-{
- int fd, i;
- struct fbgattr fbattr;
- sbusDevicePtr psdp;
-
- fd = open(device, O_RDONLY, 0);
- if (fd < 0)
- return;
- memset(&fbattr, 0, sizeof(fbattr));
- if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
- if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
- close(fd);
- return;
- }
- }
- close(fd);
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
- break;
- if (! sbusDeviceTable[i].devId)
- return;
- xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
- xf86SbusInfo[xf86nSbusInfo] = NULL;
- xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
- psdp->devId = sbusDeviceTable[i].devId;
- psdp->fbNum = fbNum;
- psdp->device = xnfstrdup(device);
- psdp->width = fbattr.fbtype.fb_width;
- psdp->height = fbattr.fbtype.fb_height;
- psdp->fd = -1;
-}
-
-void
-xf86SbusProbe(void)
-{
- int i, useProm = 0;
- char fbDevName[32];
- sbusDevicePtr psdp, *psdpp;
-
- xf86SbusInfo = xalloc(sizeof(psdp));
- *xf86SbusInfo = NULL;
- for (i = 0; i < 32; i++) {
- sprintf(fbDevName, "/dev/fb%d", i);
- CheckSbusDevice(fbDevName, i);
- }
- if (sparcPromInit() >= 0) {
- useProm = 1;
- sparcPromAssignNodes();
- }
- for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].devId == psdp->devId)
- psdp->descr = sbusDeviceTable[i].descr;
- /*
- * If we can use PROM information and found the PROM node for this
- * device, we can tell more about the card.
- */
- if (useProm && psdp->node.node) {
- char *prop, *promPath;
- int len, chiprev, vmsize;
-
- switch (psdp->devId) {
- case SBUS_DEVICE_MGX:
- prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
- if (prop && len == 4 && *(int *)prop == 0x400000)
- psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
- break;
- case SBUS_DEVICE_CG6:
- chiprev = 0;
- vmsize = 0;
- prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
- if (prop && len == 4)
- vmsize = *(int *)prop;
- switch (chiprev) {
- case 1:
- case 2:
- case 3:
- case 4:
- psdp->descr = "Sun Double width GX"; break;
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- psdp->descr = "Sun Single width GX"; break;
- case 11:
- switch (vmsize) {
- case 2:
- psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
- case 4:
- psdp->descr = "Sun Turbo GX Plus"; break;
- default:
- psdp->descr = "Sun Turbo GX"; break;
- }
- }
- break;
- case SBUS_DEVICE_CG14:
- prop = sparcPromGetProperty(&psdp->node, "reg", &len);
- vmsize = 0;
- if (prop && !(len % 12) && len > 0)
- vmsize = *(int *)(prop + len - 4);
- switch (vmsize) {
- case 0x400000:
- psdp->descr = "Sun SX with 4M VSIMM"; break;
- case 0x800000:
- psdp->descr = "Sun SX with 8M VSIMM"; break;
- }
- break;
- case SBUS_DEVICE_LEO:
- prop = sparcPromGetProperty(&psdp->node, "model", &len);
- if (prop && len > 0 && !strstr(prop, "501-2503"))
- psdp->descr = "Sun Turbo ZX";
- break;
- case SBUS_DEVICE_TCX:
- if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
- psdp->descr = "Sun TCX (8bit)";
- else
- psdp->descr = "Sun TCX (S24)";
- break;
- case SBUS_DEVICE_FFB:
- prop = sparcPromGetProperty(&psdp->node, "name", &len);
- chiprev = 0;
- prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- if (strstr (prop, "afb")) {
- if (chiprev == 3)
- psdp->descr = "Sun|Elite3D-M6 Horizontal";
- } else {
- switch (chiprev) {
- case 0x08:
- psdp->descr = "Sun FFB 67MHz Creator"; break;
- case 0x0b:
- psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
- case 0x1b:
- psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
- case 0x20:
- case 0x28:
- psdp->descr = "Sun FFB2 Vertical Creator"; break;
- case 0x23:
- case 0x2b:
- psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
- case 0x30:
- psdp->descr = "Sun FFB2+ Vertical Creator"; break;
- case 0x33:
- psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
- case 0x40:
- case 0x48:
- psdp->descr = "Sun FFB2 Horizontal Creator"; break;
- case 0x43:
- case 0x4b:
- psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
- }
- }
- break;
- }
-
- xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
- promPath = sparcPromNode2Pathname (&psdp->node);
- if (promPath) {
- xf86ErrorF(" at %s", promPath);
- xfree(promPath);
- }
- } else
- xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
- xf86ErrorF("\n");
- }
- if (useProm)
- sparcPromClose();
-}
-
-/*
- * Parse a BUS ID string, and return the SBUS bus parameters if it was
- * in the correct format for a SBUS bus id.
- */
-
-Bool
-xf86ParseSbusBusString(const char *busID, int *fbNum)
-{
- /*
- * The format is assumed to be one of:
- * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
- * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
- * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
- * to the device.
- */
-
- const char *id;
- int i, len;
-
- if (StringToBusType(busID, &id) != BUS_SBUS)
- return FALSE;
-
- if (*id != '/') {
- if (!strncmp (id, "fb", 2)) {
- if (!isdigit(id[2]))
- return FALSE;
- *fbNum = atoi(id + 2);
- return TRUE;
- } else {
- sbusDevicePtr *psdpp;
- int devId;
-
- for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
- len = strlen(sbusDeviceTable[i].promName);
- if (!strncmp (sbusDeviceTable[i].promName, id, len)
- && isdigit(id[len]))
- break;
- }
- devId = sbusDeviceTable[i].devId;
- if (!devId) return FALSE;
- i = atoi(id + len);
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->devId != devId)
- continue;
- if (!i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- i--;
- }
- }
- return FALSE;
- }
-
- if (sparcPromInit() >= 0) {
- i = sparcPromPathname2Node(id);
- sparcPromClose();
- if (i) {
- sbusDevicePtr *psdpp;
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->node.node == i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
-}
-
-/*
- * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
- */
-
-Bool
-xf86CompareSbusBusString(const char *busID, int fbNum)
-{
- int iFbNum;
-
- if (xf86ParseSbusBusString(busID, &iFbNum)) {
- return fbNum == iFbNum;
- } else {
- return FALSE;
- }
-}
-
-/*
- * Check if the slot requested is free. If it is already in use, return FALSE.
- */
-
-Bool
-xf86CheckSbusSlot(int fbNum)
-{
- int i;
- EntityPtr p;
-
- for (i = 0; i < xf86NumEntities; i++) {
- p = xf86Entities[i];
- /* Check if this SBUS slot is taken */
- if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * If the slot requested is already in use, return -1.
- * Otherwise, claim the slot for the screen requesting it.
- */
-
-int
-xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
- GDevPtr dev, Bool active)
-{
- EntityPtr p = NULL;
-
- int num;
-
- if (xf86CheckSbusSlot(psdp->fbNum)) {
- num = xf86AllocateEntity();
- p = xf86Entities[num];
- p->driver = drvp;
- p->chipset = -1;
- p->bus.type = BUS_SBUS;
- xf86AddDevToEntity(num, dev);
- p->bus.id.sbus.fbNum = psdp->fbNum;
- p->active = active;
- p->inUse = FALSE;
- sbusSlotClaimed = TRUE;
- return num;
- } else
- return -1;
-}
-
-int
-xf86MatchSbusInstances(const char *driverName, int sbusDevId,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities)
-{
- int i,j;
- sbusDevicePtr psdp, *psdpp;
- int numClaimedInstances = 0;
- int allocatedInstances = 0;
- int numFound = 0;
- GDevPtr devBus = NULL;
- GDevPtr dev = NULL;
- int *retEntities = NULL;
- int useProm = 0;
-
- struct Inst {
- sbusDevicePtr sbus;
- GDevPtr dev;
- Bool claimed; /* BusID matches with a device section */
- } *instances = NULL;
-
- *foundEntities = NULL;
- for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
- if (psdp->devId != sbusDevId)
- continue;
- if (psdp->fd == -2)
- continue;
- ++allocatedInstances;
- instances = xnfrealloc(instances,
- allocatedInstances * sizeof(struct Inst));
- instances[allocatedInstances - 1].sbus = psdp;
- instances[allocatedInstances - 1].dev = NULL;
- instances[allocatedInstances - 1].claimed = FALSE;
- numFound++;
- }
-
- /*
- * This may be debatable, but if no SBUS devices with a matching vendor
- * type is found, return zero now. It is probably not desirable to
- * allow the config file to override this.
- */
- if (allocatedInstances <= 0) {
- xfree(instances);
- return 0;
- }
-
- if (sparcPromInit() >= 0)
- useProm = 1;
-
- if (xf86DoConfigure && xf86DoConfigurePass1) {
- GDevPtr pGDev;
- int actualcards = 0;
- for (i = 0; i < allocatedInstances; i++) {
- actualcards++;
- pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
- instances[i].sbus, -1);
- if (pGDev) {
- /*
- * XF86Match???Instances() treat chipID and chipRev as
- * overrides, so clobber them here.
- */
- pGDev->chipID = pGDev->chipRev = -1;
- }
- }
- xfree(instances);
- if (useProm)
- sparcPromClose();
- return actualcards;
- }
-
- DebugF("%s instances found: %d\n", driverName, allocatedInstances);
-
- for (i = 0; i < allocatedInstances; i++) {
- char *promPath = NULL;
-
- psdp = instances[i].sbus;
- devBus = NULL;
- dev = NULL;
- if (useProm && psdp->node.node)
- promPath = sparcPromNode2Pathname(&psdp->node);
-
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->busID && *devList[j]->busID) {
- if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
- if (devBus)
- xf86MsgVerb(X_WARNING,0,
- "%s: More than one matching Device section for "
- "instance (BusID: %s) found: %s\n",
- driverName,devList[j]->identifier,
- devList[j]->busID);
- else
- devBus = devList[j];
- }
- } else {
- if (!dev && !devBus) {
- if (promPath)
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
- promPath);
- else
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
- psdp->fbNum);
- dev = devList[j];
- } else
- xf86MsgVerb(X_WARNING, 0,
- "%s: More than one matching Device section "
- "found: %s\n", driverName, devList[j]->identifier);
- }
- }
- if (devBus) dev = devBus; /* busID preferred */
- if (!dev && psdp->fd != -2) {
- if (promPath) {
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:%s) found\n",
- driverName, promPath);
- } else
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:fb%d) found\n",
- driverName, psdp->fbNum);
- } else if (dev) {
- numClaimedInstances++;
- instances[i].claimed = TRUE;
- instances[i].dev = dev;
- }
- if (promPath)
- xfree(promPath);
- }
-
- DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
-
- /*
- * Of the claimed instances, check that another driver hasn't already
- * claimed its slot.
- */
- numFound = 0;
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
- if (!instances[i].claimed)
- continue;
- psdp = instances[i].sbus;
- if (!xf86CheckSbusSlot(psdp->fbNum))
- continue;
-
- DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
- driverName, psdp->fbNum, psdp->node.node);
-
- /* Allocate an entry in the lists to be returned */
- numFound++;
- retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
- retEntities[numFound - 1]
- = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
- TRUE : FALSE);
- }
- xfree(instances);
- if (numFound > 0) {
- *foundEntities = retEntities;
- }
-
- if (useProm)
- sparcPromClose();
-
- return numFound;
-}
-
-/*
- * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
- */
-sbusDevicePtr
-xf86GetSbusInfoForEntity(int entityIndex)
-{
- sbusDevicePtr *psdpp;
- EntityPtr p = xf86Entities[entityIndex];
-
- if (entityIndex >= xf86NumEntities
- || p->bus.type != BUS_SBUS) return NULL;
-
- for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
- if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
- return (*psdpp);
- }
- return NULL;
-}
-
-int
-xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- EntityPtr p = xf86Entities[i];
- if (p->bus.type != BUS_SBUS) continue;
-
- if (p->bus.id.sbus.fbNum == psdp->fbNum)
- return i;
- }
- return -1;
-}
-
-void
-xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
-{
- DisplayModePtr mode;
-
- mode = xnfcalloc(sizeof(DisplayModeRec), 1);
- mode->name = "current";
- mode->next = mode;
- mode->prev = mode;
- mode->type = M_T_BUILTIN;
- mode->Clock = 100000000;
- mode->HDisplay = psdp->width;
- mode->HSyncStart = psdp->width;
- mode->HSyncEnd = psdp->width;
- mode->HTotal = psdp->width;
- mode->VDisplay = psdp->height;
- mode->VSyncStart = psdp->height;
- mode->VSyncEnd = psdp->height;
- mode->VTotal = psdp->height;
- 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;
- pScrn->modes = mode;
- pScrn->virtualX = psdp->width;
- pScrn->virtualY = psdp->height;
-}
-
-static sbusPaletteKeyIndex;
-static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
-typedef struct _sbusCmap {
- sbusDevicePtr psdp;
- CloseScreenProcPtr CloseScreen;
- Bool origCmapValid;
- unsigned char origRed[16];
- unsigned char origGreen[16];
- unsigned char origBlue[16];
-} sbusCmapRec, *sbusCmapPtr;
-
-#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
-
-static void
-xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- int i, index;
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char *data = xalloc(numColors*3);
-
- cmap = SBUSCMAPPTR(pScrn->pScreen);
- if (!cmap) return;
- fbcmap.count = 0;
- fbcmap.index = indices[0];
- fbcmap.red = data;
- fbcmap.green = data + numColors;
- fbcmap.blue = fbcmap.green + numColors;
- for (i = 0; i < numColors; i++) {
- index = indices[i];
- if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- fbcmap.count = 0;
- fbcmap.index = index;
- }
- fbcmap.red[fbcmap.count] = colors[index].red;
- fbcmap.green[fbcmap.count] = colors[index].green;
- fbcmap.blue[fbcmap.count++] = colors[index].blue;
- }
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- xfree(data);
-}
-
-static Bool
-xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
-
- cmap = SBUSCMAPPTR(pScreen);
- if (cmap->origCmapValid) {
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- }
- pScreen->CloseScreen = cmap->CloseScreen;
- xfree (cmap);
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char data[2];
-
- cmap = xnfcalloc(1, sizeof(sbusCmapRec));
- dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
- cmap->psdp = psdp;
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
- cmap->origCmapValid = TRUE;
- fbcmap.index = 0;
- fbcmap.count = 2;
- fbcmap.red = data;
- fbcmap.green = data;
- fbcmap.blue = data;
- if (pScreen->whitePixel == 0) {
- data[0] = 255;
- data[1] = 0;
- } else {
- data[0] = 0;
- data[1] = 255;
- }
- ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
- cmap->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86SbusCmapCloseScreen;
- return xf86HandleColormaps(pScreen, 256, 8,
- xf86SbusCmapLoadPalette, NULL, 0);
-}
+/*
+ * SBUS bus-specific code.
+ *
+ * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86cmap.h"
+
+#include "xf86Bus.h"
+
+#include "xf86sbusBus.h"
+#include "xf86Sbus.h"
+
+Bool sbusSlotClaimed = FALSE;
+
+static int xf86nSbusInfo;
+
+static void
+CheckSbusDevice(const char *device, int fbNum)
+{
+ int fd, i;
+ struct fbgattr fbattr;
+ sbusDevicePtr psdp;
+
+ fd = open(device, O_RDONLY, 0);
+ if (fd < 0)
+ return;
+ memset(&fbattr, 0, sizeof(fbattr));
+ if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
+ if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
+ close(fd);
+ return;
+ }
+ }
+ close(fd);
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
+ break;
+ if (! sbusDeviceTable[i].devId)
+ return;
+ xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
+ xf86SbusInfo[xf86nSbusInfo] = NULL;
+ xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
+ psdp->devId = sbusDeviceTable[i].devId;
+ psdp->fbNum = fbNum;
+ psdp->device = xnfstrdup(device);
+ psdp->width = fbattr.fbtype.fb_width;
+ psdp->height = fbattr.fbtype.fb_height;
+ psdp->fd = -1;
+}
+
+void
+xf86SbusProbe(void)
+{
+ int i, useProm = 0;
+ char fbDevName[32];
+ sbusDevicePtr psdp, *psdpp;
+
+ xf86SbusInfo = malloc(sizeof(psdp));
+ *xf86SbusInfo = NULL;
+ for (i = 0; i < 32; i++) {
+ sprintf(fbDevName, "/dev/fb%d", i);
+ CheckSbusDevice(fbDevName, i);
+ }
+ if (sparcPromInit() >= 0) {
+ useProm = 1;
+ sparcPromAssignNodes();
+ }
+ for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].devId == psdp->devId)
+ psdp->descr = sbusDeviceTable[i].descr;
+ /*
+ * If we can use PROM information and found the PROM node for this
+ * device, we can tell more about the card.
+ */
+ if (useProm && psdp->node.node) {
+ char *prop, *promPath;
+ int len, chiprev, vmsize;
+
+ switch (psdp->devId) {
+ case SBUS_DEVICE_MGX:
+ prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
+ if (prop && len == 4 && *(int *)prop == 0x400000)
+ psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
+ break;
+ case SBUS_DEVICE_CG6:
+ chiprev = 0;
+ vmsize = 0;
+ prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
+ if (prop && len == 4)
+ vmsize = *(int *)prop;
+ switch (chiprev) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ psdp->descr = "Sun Double width GX"; break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ psdp->descr = "Sun Single width GX"; break;
+ case 11:
+ switch (vmsize) {
+ case 2:
+ psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
+ case 4:
+ psdp->descr = "Sun Turbo GX Plus"; break;
+ default:
+ psdp->descr = "Sun Turbo GX"; break;
+ }
+ }
+ break;
+ case SBUS_DEVICE_CG14:
+ prop = sparcPromGetProperty(&psdp->node, "reg", &len);
+ vmsize = 0;
+ if (prop && !(len % 12) && len > 0)
+ vmsize = *(int *)(prop + len - 4);
+ switch (vmsize) {
+ case 0x400000:
+ psdp->descr = "Sun SX with 4M VSIMM"; break;
+ case 0x800000:
+ psdp->descr = "Sun SX with 8M VSIMM"; break;
+ }
+ break;
+ case SBUS_DEVICE_LEO:
+ prop = sparcPromGetProperty(&psdp->node, "model", &len);
+ if (prop && len > 0 && !strstr(prop, "501-2503"))
+ psdp->descr = "Sun Turbo ZX";
+ break;
+ case SBUS_DEVICE_TCX:
+ if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
+ psdp->descr = "Sun TCX (8bit)";
+ else
+ psdp->descr = "Sun TCX (S24)";
+ break;
+ case SBUS_DEVICE_FFB:
+ prop = sparcPromGetProperty(&psdp->node, "name", &len);
+ chiprev = 0;
+ prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ if (strstr (prop, "afb")) {
+ if (chiprev == 3)
+ psdp->descr = "Sun|Elite3D-M6 Horizontal";
+ } else {
+ switch (chiprev) {
+ case 0x08:
+ psdp->descr = "Sun FFB 67MHz Creator"; break;
+ case 0x0b:
+ psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
+ case 0x1b:
+ psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
+ case 0x20:
+ case 0x28:
+ psdp->descr = "Sun FFB2 Vertical Creator"; break;
+ case 0x23:
+ case 0x2b:
+ psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
+ case 0x30:
+ psdp->descr = "Sun FFB2+ Vertical Creator"; break;
+ case 0x33:
+ psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
+ case 0x40:
+ case 0x48:
+ psdp->descr = "Sun FFB2 Horizontal Creator"; break;
+ case 0x43:
+ case 0x4b:
+ psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
+ }
+ }
+ break;
+ }
+
+ xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
+ promPath = sparcPromNode2Pathname (&psdp->node);
+ if (promPath) {
+ xf86ErrorF(" at %s", promPath);
+ free(promPath);
+ }
+ } else
+ xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
+ xf86ErrorF("\n");
+ }
+ if (useProm)
+ sparcPromClose();
+}
+
+/*
+ * Parse a BUS ID string, and return the SBUS bus parameters if it was
+ * in the correct format for a SBUS bus id.
+ */
+
+Bool
+xf86ParseSbusBusString(const char *busID, int *fbNum)
+{
+ /*
+ * The format is assumed to be one of:
+ * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
+ * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
+ * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
+ * to the device.
+ */
+
+ const char *id;
+ int i, len;
+
+ if (StringToBusType(busID, &id) != BUS_SBUS)
+ return FALSE;
+
+ if (*id != '/') {
+ if (!strncmp (id, "fb", 2)) {
+ if (!isdigit(id[2]))
+ return FALSE;
+ *fbNum = atoi(id + 2);
+ return TRUE;
+ } else {
+ sbusDevicePtr *psdpp;
+ int devId;
+
+ for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
+ len = strlen(sbusDeviceTable[i].promName);
+ if (!strncmp (sbusDeviceTable[i].promName, id, len)
+ && isdigit(id[len]))
+ break;
+ }
+ devId = sbusDeviceTable[i].devId;
+ if (!devId) return FALSE;
+ i = atoi(id + len);
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->devId != devId)
+ continue;
+ if (!i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ i--;
+ }
+ }
+ return FALSE;
+ }
+
+ if (sparcPromInit() >= 0) {
+ i = sparcPromPathname2Node(id);
+ sparcPromClose();
+ if (i) {
+ sbusDevicePtr *psdpp;
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->node.node == i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
+ */
+
+Bool
+xf86CompareSbusBusString(const char *busID, int fbNum)
+{
+ int iFbNum;
+
+ if (xf86ParseSbusBusString(busID, &iFbNum)) {
+ return fbNum == iFbNum;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * Check if the slot requested is free. If it is already in use, return FALSE.
+ */
+
+Bool
+xf86CheckSbusSlot(int fbNum)
+{
+ int i;
+ EntityPtr p;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ p = xf86Entities[i];
+ /* Check if this SBUS slot is taken */
+ if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * If the slot requested is already in use, return -1.
+ * Otherwise, claim the slot for the screen requesting it.
+ */
+
+int
+xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
+ GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+
+ int num;
+
+ if (xf86CheckSbusSlot(psdp->fbNum)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = -1;
+ p->bus.type = BUS_SBUS;
+ xf86AddDevToEntity(num, dev);
+ p->bus.id.sbus.fbNum = psdp->fbNum;
+ p->active = active;
+ p->inUse = FALSE;
+ sbusSlotClaimed = TRUE;
+ return num;
+ } else
+ return -1;
+}
+
+int
+xf86MatchSbusInstances(const char *driverName, int sbusDevId,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities)
+{
+ int i,j;
+ sbusDevicePtr psdp, *psdpp;
+ int numClaimedInstances = 0;
+ int allocatedInstances = 0;
+ int numFound = 0;
+ GDevPtr devBus = NULL;
+ GDevPtr dev = NULL;
+ int *retEntities = NULL;
+ int useProm = 0;
+
+ struct Inst {
+ sbusDevicePtr sbus;
+ GDevPtr dev;
+ Bool claimed; /* BusID matches with a device section */
+ } *instances = NULL;
+
+ *foundEntities = NULL;
+ for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
+ if (psdp->devId != sbusDevId)
+ continue;
+ if (psdp->fd == -2)
+ continue;
+ ++allocatedInstances;
+ instances = xnfrealloc(instances,
+ allocatedInstances * sizeof(struct Inst));
+ instances[allocatedInstances - 1].sbus = psdp;
+ instances[allocatedInstances - 1].dev = NULL;
+ instances[allocatedInstances - 1].claimed = FALSE;
+ numFound++;
+ }
+
+ /*
+ * This may be debatable, but if no SBUS devices with a matching vendor
+ * type is found, return zero now. It is probably not desirable to
+ * allow the config file to override this.
+ */
+ if (allocatedInstances <= 0) {
+ free(instances);
+ return 0;
+ }
+
+ if (sparcPromInit() >= 0)
+ useProm = 1;
+
+ if (xf86DoConfigure && xf86DoConfigurePass1) {
+ GDevPtr pGDev;
+ int actualcards = 0;
+ for (i = 0; i < allocatedInstances; i++) {
+ actualcards++;
+ pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
+ instances[i].sbus, -1);
+ if (pGDev) {
+ /*
+ * XF86Match???Instances() treat chipID and chipRev as
+ * overrides, so clobber them here.
+ */
+ pGDev->chipID = pGDev->chipRev = -1;
+ }
+ }
+ free(instances);
+ if (useProm)
+ sparcPromClose();
+ return actualcards;
+ }
+
+ DebugF("%s instances found: %d\n", driverName, allocatedInstances);
+
+ for (i = 0; i < allocatedInstances; i++) {
+ char *promPath = NULL;
+
+ psdp = instances[i].sbus;
+ devBus = NULL;
+ dev = NULL;
+ if (useProm && psdp->node.node)
+ promPath = sparcPromNode2Pathname(&psdp->node);
+
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->busID && *devList[j]->busID) {
+ if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
+ if (devBus)
+ xf86MsgVerb(X_WARNING,0,
+ "%s: More than one matching Device section for "
+ "instance (BusID: %s) found: %s\n",
+ driverName,devList[j]->identifier,
+ devList[j]->busID);
+ else
+ devBus = devList[j];
+ }
+ } else {
+ if (!dev && !devBus) {
+ if (promPath)
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
+ promPath);
+ else
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
+ psdp->fbNum);
+ dev = devList[j];
+ } else
+ xf86MsgVerb(X_WARNING, 0,
+ "%s: More than one matching Device section "
+ "found: %s\n", driverName, devList[j]->identifier);
+ }
+ }
+ if (devBus) dev = devBus; /* busID preferred */
+ if (!dev && psdp->fd != -2) {
+ if (promPath) {
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:%s) found\n",
+ driverName, promPath);
+ } else
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:fb%d) found\n",
+ driverName, psdp->fbNum);
+ } else if (dev) {
+ numClaimedInstances++;
+ instances[i].claimed = TRUE;
+ instances[i].dev = dev;
+ }
+ if (promPath)
+ free(promPath);
+ }
+
+ DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
+
+ /*
+ * Of the claimed instances, check that another driver hasn't already
+ * claimed its slot.
+ */
+ numFound = 0;
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+ if (!instances[i].claimed)
+ continue;
+ psdp = instances[i].sbus;
+ if (!xf86CheckSbusSlot(psdp->fbNum))
+ continue;
+
+ DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
+ driverName, psdp->fbNum, psdp->node.node);
+
+ /* Allocate an entry in the lists to be returned */
+ numFound++;
+ retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+ retEntities[numFound - 1]
+ = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
+ TRUE : FALSE);
+ }
+ free(instances);
+ if (numFound > 0) {
+ *foundEntities = retEntities;
+ }
+
+ if (useProm)
+ sparcPromClose();
+
+ return numFound;
+}
+
+/*
+ * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
+ */
+sbusDevicePtr
+xf86GetSbusInfoForEntity(int entityIndex)
+{
+ sbusDevicePtr *psdpp;
+ EntityPtr p = xf86Entities[entityIndex];
+
+ if (entityIndex >= xf86NumEntities
+ || p->bus.type != BUS_SBUS) return NULL;
+
+ for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
+ if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
+ return (*psdpp);
+ }
+ return NULL;
+}
+
+int
+xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ EntityPtr p = xf86Entities[i];
+ if (p->bus.type != BUS_SBUS) continue;
+
+ if (p->bus.id.sbus.fbNum == psdp->fbNum)
+ return i;
+ }
+ return -1;
+}
+
+void
+xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
+{
+ DisplayModePtr mode;
+
+ mode = xnfcalloc(sizeof(DisplayModeRec), 1);
+ mode->name = "current";
+ mode->next = mode;
+ mode->prev = mode;
+ mode->type = M_T_BUILTIN;
+ mode->Clock = 100000000;
+ mode->HDisplay = psdp->width;
+ mode->HSyncStart = psdp->width;
+ mode->HSyncEnd = psdp->width;
+ mode->HTotal = psdp->width;
+ mode->VDisplay = psdp->height;
+ mode->VSyncStart = psdp->height;
+ mode->VSyncEnd = psdp->height;
+ mode->VTotal = psdp->height;
+ 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;
+ pScrn->modes = mode;
+ pScrn->virtualX = psdp->width;
+ pScrn->virtualY = psdp->height;
+}
+
+static sbusPaletteKeyIndex;
+static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
+typedef struct _sbusCmap {
+ sbusDevicePtr psdp;
+ CloseScreenProcPtr CloseScreen;
+ Bool origCmapValid;
+ unsigned char origRed[16];
+ unsigned char origGreen[16];
+ unsigned char origBlue[16];
+} sbusCmapRec, *sbusCmapPtr;
+
+#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
+
+static void
+xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ int i, index;
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char *data = malloc(numColors*3);
+
+ cmap = SBUSCMAPPTR(pScrn->pScreen);
+ if (!cmap) return;
+ fbcmap.count = 0;
+ fbcmap.index = indices[0];
+ fbcmap.red = data;
+ fbcmap.green = data + numColors;
+ fbcmap.blue = fbcmap.green + numColors;
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ fbcmap.count = 0;
+ fbcmap.index = index;
+ }
+ fbcmap.red[fbcmap.count] = colors[index].red;
+ fbcmap.green[fbcmap.count] = colors[index].green;
+ fbcmap.blue[fbcmap.count++] = colors[index].blue;
+ }
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ free(data);
+}
+
+static Bool
+xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+
+ cmap = SBUSCMAPPTR(pScreen);
+ if (cmap->origCmapValid) {
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ }
+ pScreen->CloseScreen = cmap->CloseScreen;
+ free(cmap);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char data[2];
+
+ cmap = xnfcalloc(1, sizeof(sbusCmapRec));
+ dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
+ cmap->psdp = psdp;
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
+ cmap->origCmapValid = TRUE;
+ fbcmap.index = 0;
+ fbcmap.count = 2;
+ fbcmap.red = data;
+ fbcmap.green = data;
+ fbcmap.blue = data;
+ if (pScreen->whitePixel == 0) {
+ data[0] = 255;
+ data[1] = 0;
+ } else {
+ data[0] = 0;
+ data[1] = 255;
+ }
+ ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
+ cmap->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86SbusCmapCloseScreen;
+ return xf86HandleColormaps(pScreen, 256, 8,
+ xf86SbusCmapLoadPalette, NULL, 0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c
index 2cc2f6093..e35b8d667 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.c
+++ b/xorg-server/hw/xfree86/common/xf86xv.c
@@ -1,2101 +1,2102 @@
-/*
- * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
- */
-/*
- * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "mivalidate.h"
-#include "validate.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-#include "xvmodproc.h"
-
-#include "xf86xvpriv.h"
-
-
-/* XvScreenRec fields */
-
-static Bool xf86XVCloseScreen(int, ScreenPtr);
-static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
-
-/* XvAdaptorRec fields */
-
-static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
-static int xf86XVFreePort(XvPortPtr);
-static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
-static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
-static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
-static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
- CARD16, CARD16,CARD16, CARD16,
- unsigned int*, unsigned int*);
-static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
-static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
- CARD16*, CARD16*, int*, int*);
-
-
-/* ScreenRec fields */
-
-static Bool xf86XVDestroyWindow(WindowPtr pWin);
-static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
-static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
-
-/* ScrnInfoRec functions */
-
-static Bool xf86XVEnterVT(int, int);
-static void xf86XVLeaveVT(int, int);
-static void xf86XVAdjustFrame(int index, int x, int y, int flags);
-
-/* misc */
-
-static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
-
-
-static int XF86XVWindowKeyIndex;
-static DevPrivateKey XF86XVWindowKey = &XF86XVWindowKeyIndex;
-static int XF86XvScreenKeyIndex;
-DevPrivateKey XF86XvScreenKey = &XF86XvScreenKeyIndex;
-static unsigned long PortResource = 0;
-
-DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
-unsigned long (*XvGetRTPortProc)(void) = NULL;
-int (*XvScreenInitProc)(ScreenPtr) = NULL;
-
-#define GET_XV_SCREEN(pScreen) \
- ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
-
-#define GET_XF86XV_SCREEN(pScreen) \
- ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
-
-#define GET_XF86XV_WINDOW(pWin) \
- ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
-
-static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
-static int NumGenDrivers = 0;
-
-int
-xf86XVRegisterGenericAdaptorDriver(
- xf86XVInitGenericAdaptorPtr InitFunc
-){
- xf86XVInitGenericAdaptorPtr *newdrivers;
-
- newdrivers = xrealloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
- (1 + NumGenDrivers));
- if (!newdrivers)
- return 0;
- GenDrivers = newdrivers;
-
- GenDrivers[NumGenDrivers++] = InitFunc;
-
- return 1;
-}
-
-int
-xf86XVListGenericAdaptors(
- ScrnInfoPtr pScrn,
- XF86VideoAdaptorPtr **adaptors
-){
- int i,j,n,num;
- XF86VideoAdaptorPtr *DrivAdap,*new;
-
- num = 0;
- *adaptors = NULL;
- /*
- * The v4l driver registers itself first, but can use surfaces registered
- * by other drivers. So, call the v4l driver last.
- */
- for (i = NumGenDrivers; --i >= 0; ) {
- DrivAdap = NULL;
- n = (*GenDrivers[i])(pScrn, &DrivAdap);
- if (0 == n)
- continue;
- new = xrealloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
- if (NULL == new)
- continue;
- *adaptors = new;
- for (j = 0; j < n; j++, num++)
- (*adaptors)[num] = DrivAdap[j];
- }
- return num;
-}
-
-
-/**************** Offscreen surface stuff *******************/
-
-typedef struct {
- XF86OffscreenImagePtr images;
- int num;
-} OffscreenImageRec;
-
-static int OffscreenPrivateKeyIndex;
-static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
-#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
-
-Bool
-xf86XVRegisterOffscreenImages(
- ScreenPtr pScreen,
- XF86OffscreenImagePtr images,
- int num
-){
- OffscreenImageRec *OffscreenImage;
- /* This function may be called before xf86XVScreenInit, so there's
- * no better place than this to call dixRequestPrivate to ensure we
- * have space reserved. After the first call it is a no-op. */
- if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
- !(OffscreenImage = GetOffscreenImage(pScreen)))
- /* Every X.org driver assumes this function always succeeds, so
- * just die on allocation failure. */
- FatalError("Could not allocate private storage for XV offscreen images.\n");
-
- OffscreenImage->num = num;
- OffscreenImage->images = images;
- return TRUE;
-}
-
-XF86OffscreenImagePtr
-xf86XVQueryOffscreenImages(
- ScreenPtr pScreen,
- int *num
-){
- OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
- *num = OffscreenImage->num;
- return OffscreenImage->images;
-}
-
-
-XF86VideoAdaptorPtr
-xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
-{
- return xcalloc(1, sizeof(XF86VideoAdaptorRec));
-}
-
-void
-xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
-{
- xfree(ptr);
-}
-
-
-Bool
-xf86XVScreenInit(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *adaptors,
- int num
-){
- ScrnInfoPtr pScrn;
- XF86XVScreenPtr ScreenPriv;
- XvScreenPtr pxvs;
-
- if(num <= 0 ||
- !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
- return FALSE;
-
- if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
-
- XF86XvScreenKey = (*XvGetScreenKeyProc)();
- PortResource = (*XvGetRTPortProc)();
-
- pxvs = GET_XV_SCREEN(pScreen);
-
- /* Anyone initializing the Xv layer must provide these two.
- The Xv di layer calls them without even checking if they exist! */
-
- pxvs->ddCloseScreen = xf86XVCloseScreen;
- pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
-
- /* The Xv di layer provides us with a private hook so that we don't
- have to allocate our own screen private. They also provide
- a CloseScreen hook so that we don't have to wrap it. I'm not
- sure that I appreciate that. */
-
- ScreenPriv = xalloc(sizeof(XF86XVScreenRec));
- pxvs->devPriv.ptr = (pointer)ScreenPriv;
-
- if(!ScreenPriv) return FALSE;
-
- pScrn = xf86Screens[pScreen->myNum];
-
- ScreenPriv->videoGC = NULL; /* for the helper */
-
- ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
- ScreenPriv->WindowExposures = pScreen->WindowExposures;
- ScreenPriv->ClipNotify = pScreen->ClipNotify;
- ScreenPriv->EnterVT = pScrn->EnterVT;
- ScreenPriv->LeaveVT = pScrn->LeaveVT;
- ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
-
- pScreen->DestroyWindow = xf86XVDestroyWindow;
- pScreen->WindowExposures = xf86XVWindowExposures;
- pScreen->ClipNotify = xf86XVClipNotify;
- pScrn->EnterVT = xf86XVEnterVT;
- pScrn->LeaveVT = xf86XVLeaveVT;
- if(pScrn->AdjustFrame)
- pScrn->AdjustFrame = xf86XVAdjustFrame;
-
- if(!xf86XVInitAdaptors(pScreen, adaptors, num))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
-{
- int i;
-
- xfree(pAdaptor->name);
-
- if(pAdaptor->pEncodings) {
- XvEncodingPtr pEncode = pAdaptor->pEncodings;
-
- for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
- xfree(pEncode->name);
- xfree(pAdaptor->pEncodings);
- }
-
- xfree(pAdaptor->pFormats);
-
- if(pAdaptor->pPorts) {
- XvPortPtr pPort = pAdaptor->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv) {
- if(pPriv->clientClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
- xfree(pPriv);
- }
- }
- xfree(pAdaptor->pPorts);
- }
-
- if(pAdaptor->nAttributes) {
- XvAttributePtr pAttribute = pAdaptor->pAttributes;
-
- for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
- xfree(pAttribute->name);
- xfree(pAdaptor->pAttributes);
- }
-
- xfree(pAdaptor->pImages);
- xfree(pAdaptor->devPriv.ptr);
-}
-
-static Bool
-xf86XVInitAdaptors(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *infoPtr,
- int number
-) {
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86VideoAdaptorPtr adaptorPtr;
- XvAdaptorPtr pAdaptor, pa;
- XvAdaptorRecPrivatePtr adaptorPriv;
- int na, numAdaptor;
- XvPortRecPrivatePtr portPriv;
- XvPortPtr pPort, pp;
- int numPort;
- XF86AttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
- XF86VideoFormatPtr formatPtr;
- XvFormatPtr pFormat, pf;
- int numFormat, totFormat;
- XF86VideoEncodingPtr encodingPtr;
- XvEncodingPtr pEncode, pe;
- XF86ImagePtr imagePtr;
- XvImagePtr pImage, pi;
- int numVisuals;
- VisualPtr pVisual;
- int i;
-
- pxvs->nAdaptors = 0;
- pxvs->pAdaptors = NULL;
-
- if(!(pAdaptor = xcalloc(number, sizeof(XvAdaptorRec))))
- return FALSE;
-
- for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
- adaptorPtr = infoPtr[na];
-
- if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
- !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
- continue;
-
- /* client libs expect at least one encoding */
- if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
- continue;
-
- pa->type = adaptorPtr->type;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
- pa->type &= ~XvVideoMask;
-
- if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
- pa->type &= ~XvStillMask;
-
- if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
- pa->type &= ~XvImageMask;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
- !adaptorPtr->PutStill)
- pa->type &= ~XvInputMask;
-
- if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
- pa->type &= ~XvOutputMask;
-
- if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
- continue;
- if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
- continue;
-
- pa->pScreen = pScreen;
- pa->ddAllocatePort = xf86XVAllocatePort;
- pa->ddFreePort = xf86XVFreePort;
- pa->ddPutVideo = xf86XVPutVideo;
- pa->ddPutStill = xf86XVPutStill;
- pa->ddGetVideo = xf86XVGetVideo;
- pa->ddGetStill = xf86XVGetStill;
- pa->ddStopVideo = xf86XVStopVideo;
- pa->ddPutImage = xf86XVPutImage;
- pa->ddSetPortAttribute = xf86XVSetPortAttribute;
- pa->ddGetPortAttribute = xf86XVGetPortAttribute;
- pa->ddQueryBestSize = xf86XVQueryBestSize;
- pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
- if((pa->name = xalloc(strlen(adaptorPtr->name) + 1)))
- strcpy(pa->name, adaptorPtr->name);
-
- if(adaptorPtr->nEncodings &&
- (pEncode = xcalloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
-
- for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
- i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
- {
- pe->id = encodingPtr->id;
- pe->pScreen = pScreen;
- if((pe->name = xalloc(strlen(encodingPtr->name) + 1)))
- strcpy(pe->name, encodingPtr->name);
- pe->width = encodingPtr->width;
- pe->height = encodingPtr->height;
- pe->rate.numerator = encodingPtr->rate.numerator;
- pe->rate.denominator = encodingPtr->rate.denominator;
- }
- pa->nEncodings = adaptorPtr->nEncodings;
- pa->pEncodings = pEncode;
- }
-
- if(adaptorPtr->nImages &&
- (pImage = xcalloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- i < adaptorPtr->nImages; i++, pi++, imagePtr++)
- {
- pi->id = imagePtr->id;
- pi->type = imagePtr->type;
- pi->byte_order = imagePtr->byte_order;
- memcpy(pi->guid, imagePtr->guid, 16);
- pi->bits_per_pixel = imagePtr->bits_per_pixel;
- pi->format = imagePtr->format;
- pi->num_planes = imagePtr->num_planes;
- pi->depth = imagePtr->depth;
- pi->red_mask = imagePtr->red_mask;
- pi->green_mask = imagePtr->green_mask;
- pi->blue_mask = imagePtr->blue_mask;
- pi->y_sample_bits = imagePtr->y_sample_bits;
- pi->u_sample_bits = imagePtr->u_sample_bits;
- pi->v_sample_bits = imagePtr->v_sample_bits;
- pi->horz_y_period = imagePtr->horz_y_period;
- pi->horz_u_period = imagePtr->horz_u_period;
- pi->horz_v_period = imagePtr->horz_v_period;
- pi->vert_y_period = imagePtr->vert_y_period;
- pi->vert_u_period = imagePtr->vert_u_period;
- pi->vert_v_period = imagePtr->vert_v_period;
- memcpy(pi->component_order, imagePtr->component_order, 32);
- pi->scanline_order = imagePtr->scanline_order;
- }
- pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
- }
-
- if(adaptorPtr->nAttributes &&
- (pAttribute = xcalloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
- {
- for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
- i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
- {
- pat->flags = attributePtr->flags;
- pat->min_value = attributePtr->min_value;
- pat->max_value = attributePtr->max_value;
- if((pat->name = xalloc(strlen(attributePtr->name) + 1)))
- strcpy(pat->name, attributePtr->name);
- }
- pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
- }
-
-
- totFormat = adaptorPtr->nFormats;
-
- if(!(pFormat = xcalloc(totFormat, sizeof(XvFormatRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
- i < adaptorPtr->nFormats; i++, formatPtr++)
- {
- numVisuals = pScreen->numVisuals;
- pVisual = pScreen->visuals;
-
- while(numVisuals--) {
- if((pVisual->class == formatPtr->class) &&
- (pVisual->nplanes == formatPtr->depth)) {
-
- if(numFormat >= totFormat) {
- void *moreSpace;
- totFormat *= 2;
- moreSpace = xrealloc(pFormat,
- totFormat * sizeof(XvFormatRec));
- if(!moreSpace) break;
- pFormat = moreSpace;
- pf = pFormat + numFormat;
- }
-
- pf->visual = pVisual->vid;
- pf->depth = formatPtr->depth;
-
- pf++;
- numFormat++;
- }
- pVisual++;
- }
- }
- pa->nFormats = numFormat;
- pa->pFormats = pFormat;
- if(!numFormat) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- if(!(adaptorPriv = xcalloc(1, sizeof(XvAdaptorRecPrivate)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- adaptorPriv->flags = adaptorPtr->flags;
- adaptorPriv->PutVideo = adaptorPtr->PutVideo;
- adaptorPriv->PutStill = adaptorPtr->PutStill;
- adaptorPriv->GetVideo = adaptorPtr->GetVideo;
- adaptorPriv->GetStill = adaptorPtr->GetStill;
- adaptorPriv->StopVideo = adaptorPtr->StopVideo;
- adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
- adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
- adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
- adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
- adaptorPriv->PutImage = adaptorPtr->PutImage;
- adaptorPriv->ReputImage = adaptorPtr->ReputImage;
-
- pa->devPriv.ptr = (pointer)adaptorPriv;
-
- if(!(pPort = xcalloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pp = pPort, i = 0, numPort = 0;
- i < adaptorPtr->nPorts; i++) {
-
- if(!(pp->id = FakeClientID(0)))
- continue;
-
- if(!(portPriv = xcalloc(1, sizeof(XvPortRecPrivate))))
- continue;
-
- if(!AddResource(pp->id, PortResource, pp)) {
- xfree(portPriv);
- continue;
- }
-
- pp->pAdaptor = pa;
- pp->pNotify = (XvPortNotifyPtr)NULL;
- pp->pDraw = (DrawablePtr)NULL;
- pp->client = (ClientPtr)NULL;
- pp->grab.client = (ClientPtr)NULL;
- pp->time = currentTime;
- pp->devPriv.ptr = portPriv;
-
- portPriv->pScrn = pScrn;
- portPriv->AdaptorRec = adaptorPriv;
- portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
-
- pp++;
- numPort++;
- }
- pa->nPorts = numPort;
- pa->pPorts = pPort;
- if(!numPort) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- pa->base_id = pPort->id;
-
- pa++;
- numAdaptor++;
- }
-
- if(numAdaptor) {
- pxvs->nAdaptors = numAdaptor;
- pxvs->pAdaptors = pAdaptor;
- } else {
- xfree(pAdaptor);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Video should be clipped to the intersection of the window cliplist
- and the client cliplist specified in the GC for which the video was
- initialized. When we need to reclip a window, the GC that started
- the video may not even be around anymore. That's why we save the
- client clip from the GC when the video is initialized. We then
- use xf86XVUpdateCompositeClip to calculate the new composite clip
- when we need it. This is different from what DEC did. They saved
- the GC and used it's clip list when they needed to reclip the window,
- even if the client clip was different from the one the video was
- initialized with. If the original GC was destroyed, they had to stop
- the video. I like the new method better (MArk).
-
- This function only works for windows. Will need to rewrite when
- (if) we support pixmap rendering.
-*/
-
-static void
-xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
-{
- RegionPtr pregWin, pCompositeClip;
- WindowPtr pWin;
- ScreenPtr pScreen;
- Bool freeCompClip = FALSE;
-
- if(portPriv->pCompositeClip)
- return;
-
- pWin = (WindowPtr)portPriv->pDraw;
- pScreen = pWin->drawable.pScreen;
-
- /* get window clip list */
- if(portPriv->subWindowMode == IncludeInferiors) {
- pregWin = NotClippedByChildren(pWin);
- freeCompClip = TRUE;
- } else
- pregWin = &pWin->clipList;
-
- if(!portPriv->clientClip) {
- portPriv->pCompositeClip = pregWin;
- portPriv->FreeCompositeClip = freeCompClip;
- return;
- }
-
- pCompositeClip = REGION_CREATE(pScreen, NullBox, 1);
- REGION_COPY(pScreen, pCompositeClip, portPriv->clientClip);
- REGION_TRANSLATE(pScreen, pCompositeClip,
- portPriv->pDraw->x + portPriv->clipOrg.x,
- portPriv->pDraw->y + portPriv->clipOrg.y);
- REGION_INTERSECT(pScreen, pCompositeClip, pregWin, pCompositeClip);
-
- portPriv->pCompositeClip = pCompositeClip;
- portPriv->FreeCompositeClip = TRUE;
-
- if(freeCompClip) {
- REGION_DESTROY(pScreen, pregWin);
- }
-}
-
-/* Save the current clientClip and update the CompositeClip whenever
- we have a fresh GC */
-
-static void
-xf86XVCopyClip(
- XvPortRecPrivatePtr portPriv,
- GCPtr pGC
-){
- /* copy the new clip if it exists */
- if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
- if(!portPriv->clientClip)
- portPriv->clientClip = REGION_CREATE(pScreen, NullBox, 1);
- /* Note: this is in window coordinates */
- REGION_COPY(pScreen, portPriv->clientClip, pGC->clientClip);
- } else if(portPriv->clientClip) { /* free the old clientClip */
- REGION_DESTROY(pScreen, portPriv->clientClip);
- portPriv->clientClip = NULL;
- }
-
- /* get rid of the old clip list */
- if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
- REGION_DESTROY(pScreen, portPriv->pCompositeClip);
- }
-
- portPriv->clipOrg = pGC->clipOrg;
- portPriv->pCompositeClip = pGC->pCompositeClip;
- portPriv->FreeCompositeClip = FALSE;
- portPriv->subWindowMode = pGC->subWindowMode;
-}
-
-static int
-xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success)
- portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success) portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-xf86XVReputImage(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
- WinBox.x1, WinBox.y1,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputAllVideo(WindowPtr pWin, pointer data)
-{
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
-
- while(WinPriv) {
- if(WinPriv->PortRec->type == XvInputMask)
- xf86XVReputVideo(WinPriv->PortRec);
- else
- xf86XVRegetVideo(WinPriv->PortRec);
- WinPriv = WinPriv->next;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static int
-xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, PrivRoot;
-
- winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
-
- /* Enlist our port in the window private */
- while(winPriv) {
- if(winPriv->PortRec == portPriv) /* we're already listed */
- break;
- winPriv = winPriv->next;
- }
-
- if(!winPriv) {
- winPriv = xcalloc(1, sizeof(XF86XVWindowRec));
- if(!winPriv) return BadAlloc;
- winPriv->PortRec = portPriv;
- winPriv->next = PrivRoot;
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
- }
-
- portPriv->pDraw = (DrawablePtr)pWin;
-
- return Success;
-}
-
-
-static void
-xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, prevPriv = NULL;
-
- winPriv = GET_XF86XV_WINDOW(pWin);
-
- while(winPriv) {
- if(winPriv->PortRec == portPriv) {
- if(prevPriv)
- prevPriv->next = winPriv->next;
- else
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- winPriv->next);
- xfree(winPriv);
- break;
- }
- prevPriv = winPriv;
- winPriv = winPriv->next;
- }
- portPriv->pDraw = NULL;
-}
-
-/**** ScreenRec fields ****/
-
-static Bool
-xf86XVDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
- int ret;
-
- while(WinPriv) {
- XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
-
- if(pPriv->isOn > XV_OFF) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
- }
-
- pPriv->pDraw = NULL;
- tmp = WinPriv;
- if(WinPriv->pGC) {
- FreeGC(WinPriv->pGC, 0);
- }
- WinPriv = WinPriv->next;
- xfree(tmp);
- }
-
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- ret = (*pScreen->DestroyWindow)(pWin);
- pScreen->DestroyWindow = xf86XVDestroyWindow;
-
- return ret;
-}
-
-
-static void
-xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XF86XVWindowPtr pPrev;
- XvPortRecPrivatePtr pPriv;
- Bool AreasExposed;
-
- AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
-
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- (*pScreen->WindowExposures)(pWin, reg1, reg2);
- pScreen->WindowExposures = xf86XVWindowExposures;
-
- /* filter out XClearWindow/Area */
- if (!pWin->valdata) return;
-
- pPrev = NULL;
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- /* Reput anyone with a reput function */
-
- switch(pPriv->type) {
- case XvInputMask:
- xf86XVReputVideo(pPriv);
- break;
- case XvOutputMask:
- xf86XVRegetVideo(pPriv);
- break;
- default: /* overlaid still/image*/
- if (pPriv->AdaptorRec->ReputImage)
- xf86XVReputImage(pPriv);
- else if(AreasExposed) {
- XF86XVWindowPtr tmp;
-
- if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- break;
- }
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-}
-
-
-static void
-xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XF86XVWindowPtr tmp, pPrev = NULL;
- XvPortRecPrivatePtr pPriv;
- Bool visible = (pWin->visibility == VisibilityUnobscured) ||
- (pWin->visibility == VisibilityPartiallyObscured);
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- if(!pPriv) goto next;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if (pPriv->AdaptorRec->ClipNotify)
- (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
- pWin, dx, dy);
-
- /* Stop everything except images, but stop them too if the
- window isn't visible. But we only remove the images. */
-
- if(pPriv->type || !visible) {
- if(pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
-
- if(!pPriv->type) { /* overlaid still/image */
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- }
-
-next:
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-
- if(ScreenPriv->ClipNotify) {
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
- (*pScreen->ClipNotify)(pWin, dx, dy);
- pScreen->ClipNotify = xf86XVClipNotify;
- }
-}
-
-
-
-/**** Required XvScreenRec fields ****/
-
-static Bool
-xf86XVCloseScreen(int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pa;
- int c;
-
- if(!ScreenPriv) return TRUE;
-
- if(ScreenPriv->videoGC) {
- FreeGC(ScreenPriv->videoGC, 0);
- ScreenPriv->videoGC = NULL;
- }
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
-
- pScrn->EnterVT = ScreenPriv->EnterVT;
- pScrn->LeaveVT = ScreenPriv->LeaveVT;
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
-
- for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
- xf86XVFreeAdaptor(pa);
- }
-
- xfree(pxvs->pAdaptors);
- xfree(ScreenPriv);
- return TRUE;
-}
-
-
-static int
-xf86XVQueryAdaptors(
- ScreenPtr pScreen,
- XvAdaptorPtr *p_pAdaptors,
- int *p_nAdaptors
-){
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
-
- *p_nAdaptors = pxvs->nAdaptors;
- *p_pAdaptors = pxvs->pAdaptors;
-
- return (Success);
-}
-
-
-/**** ScrnInfoRec fields ****/
-
-static Bool
-xf86XVEnterVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- Bool ret;
-
- ret = (*ScreenPriv->EnterVT)(index, flags);
-
- if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
-
- return ret;
-}
-
-static void
-xf86XVLeaveVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pAdaptor;
- XvPortPtr pPort;
- XvPortRecPrivatePtr pPriv;
- int i, j;
-
- for(i = 0; i < pxvs->nAdaptors; i++) {
- pAdaptor = &pxvs->pAdaptors[i];
- for(j = 0; j < pAdaptor->nPorts; j++) {
- pPort = &pAdaptor->pPorts[j];
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv->isOn > XV_OFF) {
-
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if(!pPriv->type && pPriv->pDraw) { /* still */
- xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
- }
- }
- }
- }
-
- (*ScreenPriv->LeaveVT)(index, flags);
-}
-
-static void
-xf86XVAdjustFrame(int index, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = pScrn->pScreen;
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- WindowPtr pWin;
- XvAdaptorPtr pa;
- int c, i;
-
- if(ScreenPriv->AdjustFrame) {
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
- (*pScrn->AdjustFrame)(index, x, y, flags);
- pScrn->AdjustFrame = xf86XVAdjustFrame;
- }
-
- for(c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
- XvPortPtr pPort = pa->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = pa->nPorts; i > 0; i--, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
-
- if(!pPriv->type && (pPriv->isOn != XV_OFF)) { /* overlaid still/image */
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- pWin = (WindowPtr)pPriv->pDraw;
-
- if ((pPriv->AdaptorRec->ReputImage) &&
- ((pWin->visibility == VisibilityUnobscured) ||
- (pWin->visibility == VisibilityPartiallyObscured)))
- {
- xf86XVReputImage(pPriv);
- } else if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- xf86XVRemovePortFromWindow(pWin, pPriv);
- pPriv->isOn = XV_PENDING;
- continue;
- }
- }
- }
- }
-}
-
-
-/**** XvAdaptorRec fields ****/
-
-static int
-xf86XVAllocatePort(
- unsigned long port,
- XvPortPtr pPort,
- XvPortPtr *ppPort
-){
- *ppPort = pPort;
- return Success;
-}
-
-
-
-static int
-xf86XVFreePort(XvPortPtr pPort)
-{
- return Success;
-}
-
-
-static int
-xf86XVPutVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No dumping video to pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvInputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVReputVideo(portPriv));
-}
-
-static int
-xf86XVPutStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
-
- xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- portPriv->isOn = XV_ON;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-xf86XVGetVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvOutputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVRegetVideo(portPriv));
-}
-
-static int
-xf86XVGetStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto GET_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
-GET_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-
-static int
-xf86XVStopVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- if(pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- /* Must free resources. */
-
- if(portPriv->isOn > XV_OFF) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
- portPriv->isOn = XV_OFF;
- }
-
- return Success;
-}
-
-static int
-xf86XVSetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
- attribute, value, portPriv->DevPriv.ptr));
-}
-
-
-static int
-xf86XVGetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 *p_value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
- attribute, p_value, portPriv->DevPriv.ptr));
-}
-
-
-
-static int
-xf86XVQueryBestSize(
- ClientPtr client,
- XvPortPtr pPort,
- CARD8 motion,
- CARD16 vid_w, CARD16 vid_h,
- CARD16 drw_w, CARD16 drw_h,
- unsigned int *p_w, unsigned int *p_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
- (Bool)motion, vid_w, vid_h, drw_w, drw_h,
- p_w, p_h, portPriv->DevPriv.ptr);
-
- return Success;
-}
-
-
-static int
-xf86XVPutImage(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 src_x, INT16 src_y,
- CARD16 src_w, CARD16 src_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h,
- XvImagePtr format,
- unsigned char* data,
- Bool sync,
- CARD16 width, CARD16 height
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(ret != Success) goto PUT_IMAGE_BAILOUT;
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
- src_x, src_y, WinBox.x1, WinBox.y1,
- src_w, src_h, drw_w, drw_h, format->id, data, width, height,
- sync, &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
-
- portPriv->isOn = XV_ON;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_IMAGE_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVQueryImageAttributes(
- ClientPtr client,
- XvPortPtr pPort,
- XvImagePtr format,
- CARD16 *width,
- CARD16 *height,
- int *pitches,
- int *offsets
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
- format->id, width, height, pitches, offsets);
-}
-
-
-void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- WindowPtr pWin = (WindowPtr)pDraw;
- XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
- GCPtr pGC = NULL;
- XID pval[2];
- BoxPtr pbox = REGION_RECTS(clipboxes);
- int i, nbox = REGION_NUM_RECTS(clipboxes);
- xRectangle *rects;
-
- if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
- if(pPriv)
- pGC = pPriv->pGC;
-
- if(!pGC) {
- int status;
- pval[0] = key;
- pval[1] = IncludeInferiors;
- pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
- (XID)0, serverClient);
- if(!pGC) return;
- ValidateGC(pDraw, pGC);
- if (pPriv) pPriv->pGC = pGC;
- } else if (key != pGC->fgPixel){
- pval[0] = key;
- ChangeGC(pGC, GCForeground, pval);
- ValidateGC(pDraw, pGC);
- }
-
- REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y);
-
- rects = xalloc(nbox * sizeof(xRectangle));
-
- for(i = 0; i < nbox; i++, pbox++) {
- rects[i].x = pbox->x1;
- rects[i].y = pbox->y1;
- rects[i].width = pbox->x2 - pbox->x1;
- rects[i].height = pbox->y2 - pbox->y1;
- }
-
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
-
- if (!pPriv) FreeGC(pGC, 0);
-
- xfree(rects);
-}
-
-void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
-{
- DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
- XID pval[2];
- BoxPtr pbox = REGION_RECTS(clipboxes);
- int i, nbox = REGION_NUM_RECTS(clipboxes);
- xRectangle *rects;
- GCPtr gc;
-
- if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
- gc = GetScratchGC(root->depth, pScreen);
- pval[0] = key;
- pval[1] = IncludeInferiors;
- (void) ChangeGC(gc, GCForeground|GCSubwindowMode, pval);
- ValidateGC(root, gc);
-
- rects = xalloc (nbox * sizeof(xRectangle));
-
- for(i = 0; i < nbox; i++, pbox++)
- {
- rects[i].x = pbox->x1;
- rects[i].y = pbox->y1;
- rects[i].width = pbox->x2 - pbox->x1;
- rects[i].height = pbox->y2 - pbox->y1;
- }
-
- (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
-
- xfree (rects);
- FreeScratchGC (gc);
-}
-
-/* xf86XVClipVideoHelper -
-
- Takes the dst box in standard X BoxRec form (top and left
- edges inclusive, bottom and right exclusive). The new dst
- box is returned. The source boundaries are given (x1, y1
- inclusive, x2, y2 exclusive) and returned are the new source
- boundaries in 16.16 fixed point.
-*/
-
-#define DummyScreen screenInfo.screens[0]
-
-Bool
-xf86XVClipVideoHelper(
- BoxPtr dst,
- INT32 *xa,
- INT32 *xb,
- INT32 *ya,
- INT32 *yb,
- RegionPtr reg,
- INT32 width,
- INT32 height
-){
- double xsw, xdw, ysw, ydw;
- INT32 delta;
- BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
- int diff;
-
- xsw = (*xb - *xa) << 16;
- xdw = dst->x2 - dst->x1;
- ysw = (*yb - *ya) << 16;
- ydw = dst->y2 - dst->y1;
-
- *xa <<= 16; *xb <<= 16;
- *ya <<= 16; *yb <<= 16;
-
- diff = extents->x1 - dst->x1;
- if (diff > 0) {
- dst->x1 = extents->x1;
- *xa += (diff * xsw) / xdw;
- }
- diff = dst->x2 - extents->x2;
- if (diff > 0) {
- dst->x2 = extents->x2;
- *xb -= (diff * xsw) / xdw;
- }
- diff = extents->y1 - dst->y1;
- if (diff > 0) {
- dst->y1 = extents->y1;
- *ya += (diff * ysw) / ydw;
- }
- diff = dst->y2 - extents->y2;
- if (diff > 0) {
- dst->y2 = extents->y2;
- *yb -= (diff * ysw) / ydw;
- }
-
- if (*xa < 0) {
- diff = (((-*xa) * xdw) + xsw - 1) / xsw;
- dst->x1 += diff;
- *xa += (diff * xsw) / xdw;
- }
- delta = *xb - (width << 16);
- if (delta > 0) {
- diff = ((delta * xdw) + xsw - 1) / xsw;
- dst->x2 -= diff;
- *xb -= (diff * xsw) / xdw;
- }
- if (*xa >= *xb) return FALSE;
-
- if (*ya < 0) {
- diff = (((-*ya) * ydw) + ysw - 1) / ysw;
- dst->y1 += diff;
- *ya += (diff * ysw) / ydw;
- }
- delta = *yb - (height << 16);
- if (delta > 0) {
- diff = ((delta * ydw) + ysw - 1) / ysw;
- dst->y2 -= diff;
- *yb -= (diff * ysw) / ydw;
- }
- if (*ya >= *yb) return FALSE;
-
- if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
- (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
- {
- RegionRec clipReg;
- REGION_INIT(DummyScreen, &clipReg, dst, 1);
- REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
- REGION_UNINIT(DummyScreen, &clipReg);
- }
- return TRUE;
-}
-
-void
-xf86XVCopyYUV12ToPacked(
- const void *srcy,
- const void *srcv,
- const void *srcu,
- void *dst,
- int srcPitchy,
- int srcPitchuv,
- int dstPitch,
- int h,
- int w
-){
- CARD32 *Dst;
- const CARD8 *Y, *U, *V;
- int i, j;
-
- w >>= 1;
-
- for (j = 0; j < h; j++) {
- Dst = dst;
- Y = srcy; V = srcv; U = srcu;
- i = w;
- while (i >= 4) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
- Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
- Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
- Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
- Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
- Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
- Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
-#endif
- Dst += 4; Y += 8; V += 4; U += 4;
- i -= 4;
- }
-
- while (i--) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
-#endif
- Dst++; Y += 2; V++; U++;
- }
-
- dst = (CARD8 *)dst + dstPitch;
- srcy = (const CARD8 *)srcy + srcPitchy;
- if (j & 1) {
- srcu = (const CARD8 *)srcu + srcPitchuv;
- srcv = (const CARD8 *)srcv + srcPitchuv;
- }
- }
-}
-
-void
-xf86XVCopyPacked(
- const void *src,
- void *dst,
- int srcPitch,
- int dstPitch,
- int h,
- int w
-){
- const CARD32 *Src;
- CARD32 *Dst;
- int i;
-
- w >>= 1;
- while (--h >= 0) {
- do {
- Dst = dst; Src = src;
- i = w;
- while (i >= 4) {
- Dst[0] = Src[0];
- Dst[1] = Src[1];
- Dst[2] = Src[2];
- Dst[3] = Src[3];
- Dst += 4; Src += 4; i -= 4;
- }
- if (!i) break;
- Dst[0] = Src[0];
- if (i == 1) break;
- Dst[1] = Src[1];
- if (i == 2) break;
- Dst[2] = Src[2];
- } while (0);
-
- src = (const CARD8 *)src + srcPitch;
- dst = (CARD8 *)dst + dstPitch;
- }
-}
+/*
+ * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
+ */
+/*
+ * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#include "xvmodproc.h"
+
+#include "xf86xvpriv.h"
+
+
+/* XvScreenRec fields */
+
+static Bool xf86XVCloseScreen(int, ScreenPtr);
+static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
+
+/* XvAdaptorRec fields */
+
+static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
+static int xf86XVFreePort(XvPortPtr);
+static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
+static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
+static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
+static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
+ CARD16, CARD16,CARD16, CARD16,
+ unsigned int*, unsigned int*);
+static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
+ CARD16*, CARD16*, int*, int*);
+
+
+/* ScreenRec fields */
+
+static Bool xf86XVDestroyWindow(WindowPtr pWin);
+static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
+
+/* ScrnInfoRec functions */
+
+static Bool xf86XVEnterVT(int, int);
+static void xf86XVLeaveVT(int, int);
+static void xf86XVAdjustFrame(int index, int x, int y, int flags);
+
+/* misc */
+
+static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
+
+
+static int XF86XVWindowKeyIndex;
+static DevPrivateKey XF86XVWindowKey = &XF86XVWindowKeyIndex;
+static int XF86XvScreenKeyIndex;
+DevPrivateKey XF86XvScreenKey = &XF86XvScreenKeyIndex;
+static unsigned long PortResource = 0;
+
+DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
+unsigned long (*XvGetRTPortProc)(void) = NULL;
+int (*XvScreenInitProc)(ScreenPtr) = NULL;
+
+#define GET_XV_SCREEN(pScreen) \
+ ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
+
+#define GET_XF86XV_SCREEN(pScreen) \
+ ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
+
+#define GET_XF86XV_WINDOW(pWin) \
+ ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
+
+static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
+static int NumGenDrivers = 0;
+
+int
+xf86XVRegisterGenericAdaptorDriver(
+ xf86XVInitGenericAdaptorPtr InitFunc
+){
+ xf86XVInitGenericAdaptorPtr *newdrivers;
+
+ newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
+ (1 + NumGenDrivers));
+ if (!newdrivers)
+ return 0;
+ GenDrivers = newdrivers;
+
+ GenDrivers[NumGenDrivers++] = InitFunc;
+
+ return 1;
+}
+
+int
+xf86XVListGenericAdaptors(
+ ScrnInfoPtr pScrn,
+ XF86VideoAdaptorPtr **adaptors
+){
+ int i,j,n,num;
+ XF86VideoAdaptorPtr *DrivAdap,*new;
+
+ num = 0;
+ *adaptors = NULL;
+ /*
+ * The v4l driver registers itself first, but can use surfaces registered
+ * by other drivers. So, call the v4l driver last.
+ */
+ for (i = NumGenDrivers; --i >= 0; ) {
+ DrivAdap = NULL;
+ n = (*GenDrivers[i])(pScrn, &DrivAdap);
+ if (0 == n)
+ continue;
+ new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
+ if (NULL == new)
+ continue;
+ *adaptors = new;
+ for (j = 0; j < n; j++, num++)
+ (*adaptors)[num] = DrivAdap[j];
+ }
+ return num;
+}
+
+
+/**************** Offscreen surface stuff *******************/
+
+typedef struct {
+ XF86OffscreenImagePtr images;
+ int num;
+} OffscreenImageRec;
+
+static int OffscreenPrivateKeyIndex;
+static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
+#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
+
+Bool
+xf86XVRegisterOffscreenImages(
+ ScreenPtr pScreen,
+ XF86OffscreenImagePtr images,
+ int num
+){
+ OffscreenImageRec *OffscreenImage;
+ /* This function may be called before xf86XVScreenInit, so there's
+ * no better place than this to call dixRequestPrivate to ensure we
+ * have space reserved. After the first call it is a no-op. */
+ if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
+ !(OffscreenImage = GetOffscreenImage(pScreen)))
+ /* Every X.org driver assumes this function always succeeds, so
+ * just die on allocation failure. */
+ FatalError("Could not allocate private storage for XV offscreen images.\n");
+
+ OffscreenImage->num = num;
+ OffscreenImage->images = images;
+ return TRUE;
+}
+
+XF86OffscreenImagePtr
+xf86XVQueryOffscreenImages(
+ ScreenPtr pScreen,
+ int *num
+){
+ OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
+ *num = OffscreenImage->num;
+ return OffscreenImage->images;
+}
+
+
+XF86VideoAdaptorPtr
+xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
+{
+ return calloc(1, sizeof(XF86VideoAdaptorRec));
+}
+
+void
+xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
+{
+ free(ptr);
+}
+
+
+Bool
+xf86XVScreenInit(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *adaptors,
+ int num
+){
+ ScrnInfoPtr pScrn;
+ XF86XVScreenPtr ScreenPriv;
+ XvScreenPtr pxvs;
+
+ if(num <= 0 ||
+ !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
+ return FALSE;
+
+ if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
+
+ XF86XvScreenKey = (*XvGetScreenKeyProc)();
+ PortResource = (*XvGetRTPortProc)();
+
+ pxvs = GET_XV_SCREEN(pScreen);
+
+ /* Anyone initializing the Xv layer must provide these two.
+ The Xv di layer calls them without even checking if they exist! */
+
+ pxvs->ddCloseScreen = xf86XVCloseScreen;
+ pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
+
+ /* The Xv di layer provides us with a private hook so that we don't
+ have to allocate our own screen private. They also provide
+ a CloseScreen hook so that we don't have to wrap it. I'm not
+ sure that I appreciate that. */
+
+ ScreenPriv = malloc(sizeof(XF86XVScreenRec));
+ pxvs->devPriv.ptr = (pointer)ScreenPriv;
+
+ if(!ScreenPriv) return FALSE;
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ ScreenPriv->videoGC = NULL; /* for the helper */
+
+ ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ ScreenPriv->WindowExposures = pScreen->WindowExposures;
+ ScreenPriv->ClipNotify = pScreen->ClipNotify;
+ ScreenPriv->EnterVT = pScrn->EnterVT;
+ ScreenPriv->LeaveVT = pScrn->LeaveVT;
+ ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
+
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+ pScreen->WindowExposures = xf86XVWindowExposures;
+ pScreen->ClipNotify = xf86XVClipNotify;
+ pScrn->EnterVT = xf86XVEnterVT;
+ pScrn->LeaveVT = xf86XVLeaveVT;
+ if(pScrn->AdjustFrame)
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+
+ if(!xf86XVInitAdaptors(pScreen, adaptors, num))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
+{
+ int i;
+
+ free(pAdaptor->name);
+
+ if(pAdaptor->pEncodings) {
+ XvEncodingPtr pEncode = pAdaptor->pEncodings;
+
+ for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
+ free(pEncode->name);
+ free(pAdaptor->pEncodings);
+ }
+
+ free(pAdaptor->pFormats);
+
+ if(pAdaptor->pPorts) {
+ XvPortPtr pPort = pAdaptor->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv) {
+ if(pPriv->clientClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
+ free(pPriv);
+ }
+ }
+ free(pAdaptor->pPorts);
+ }
+
+ if(pAdaptor->nAttributes) {
+ XvAttributePtr pAttribute = pAdaptor->pAttributes;
+
+ for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
+ free(pAttribute->name);
+ free(pAdaptor->pAttributes);
+ }
+
+ free(pAdaptor->pImages);
+ free(pAdaptor->devPriv.ptr);
+}
+
+static Bool
+xf86XVInitAdaptors(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *infoPtr,
+ int number
+) {
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr adaptorPtr;
+ XvAdaptorPtr pAdaptor, pa;
+ XvAdaptorRecPrivatePtr adaptorPriv;
+ int na, numAdaptor;
+ XvPortRecPrivatePtr portPriv;
+ XvPortPtr pPort, pp;
+ int numPort;
+ XF86AttributePtr attributePtr;
+ XvAttributePtr pAttribute, pat;
+ XF86VideoFormatPtr formatPtr;
+ XvFormatPtr pFormat, pf;
+ int numFormat, totFormat;
+ XF86VideoEncodingPtr encodingPtr;
+ XvEncodingPtr pEncode, pe;
+ XF86ImagePtr imagePtr;
+ XvImagePtr pImage, pi;
+ int numVisuals;
+ VisualPtr pVisual;
+ int i;
+
+ pxvs->nAdaptors = 0;
+ pxvs->pAdaptors = NULL;
+
+ if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
+ return FALSE;
+
+ for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
+ adaptorPtr = infoPtr[na];
+
+ if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
+ !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
+ continue;
+
+ /* client libs expect at least one encoding */
+ if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
+ continue;
+
+ pa->type = adaptorPtr->type;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
+ pa->type &= ~XvVideoMask;
+
+ if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
+ pa->type &= ~XvStillMask;
+
+ if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
+ pa->type &= ~XvImageMask;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
+ !adaptorPtr->PutStill)
+ pa->type &= ~XvInputMask;
+
+ if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
+ pa->type &= ~XvOutputMask;
+
+ if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
+ continue;
+ if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
+ continue;
+
+ pa->pScreen = pScreen;
+ pa->ddAllocatePort = xf86XVAllocatePort;
+ pa->ddFreePort = xf86XVFreePort;
+ pa->ddPutVideo = xf86XVPutVideo;
+ pa->ddPutStill = xf86XVPutStill;
+ pa->ddGetVideo = xf86XVGetVideo;
+ pa->ddGetStill = xf86XVGetStill;
+ pa->ddStopVideo = xf86XVStopVideo;
+ pa->ddPutImage = xf86XVPutImage;
+ pa->ddSetPortAttribute = xf86XVSetPortAttribute;
+ pa->ddGetPortAttribute = xf86XVGetPortAttribute;
+ pa->ddQueryBestSize = xf86XVQueryBestSize;
+ pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
+ if((pa->name = malloc(strlen(adaptorPtr->name) + 1)))
+ strcpy(pa->name, adaptorPtr->name);
+
+ if(adaptorPtr->nEncodings &&
+ (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
+
+ for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
+ i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
+ {
+ pe->id = encodingPtr->id;
+ pe->pScreen = pScreen;
+ if((pe->name = malloc(strlen(encodingPtr->name) + 1)))
+ strcpy(pe->name, encodingPtr->name);
+ pe->width = encodingPtr->width;
+ pe->height = encodingPtr->height;
+ pe->rate.numerator = encodingPtr->rate.numerator;
+ pe->rate.denominator = encodingPtr->rate.denominator;
+ }
+ pa->nEncodings = adaptorPtr->nEncodings;
+ pa->pEncodings = pEncode;
+ }
+
+ if(adaptorPtr->nImages &&
+ (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+
+ for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
+ i < adaptorPtr->nImages; i++, pi++, imagePtr++)
+ {
+ pi->id = imagePtr->id;
+ pi->type = imagePtr->type;
+ pi->byte_order = imagePtr->byte_order;
+ memcpy(pi->guid, imagePtr->guid, 16);
+ pi->bits_per_pixel = imagePtr->bits_per_pixel;
+ pi->format = imagePtr->format;
+ pi->num_planes = imagePtr->num_planes;
+ pi->depth = imagePtr->depth;
+ pi->red_mask = imagePtr->red_mask;
+ pi->green_mask = imagePtr->green_mask;
+ pi->blue_mask = imagePtr->blue_mask;
+ pi->y_sample_bits = imagePtr->y_sample_bits;
+ pi->u_sample_bits = imagePtr->u_sample_bits;
+ pi->v_sample_bits = imagePtr->v_sample_bits;
+ pi->horz_y_period = imagePtr->horz_y_period;
+ pi->horz_u_period = imagePtr->horz_u_period;
+ pi->horz_v_period = imagePtr->horz_v_period;
+ pi->vert_y_period = imagePtr->vert_y_period;
+ pi->vert_u_period = imagePtr->vert_u_period;
+ pi->vert_v_period = imagePtr->vert_v_period;
+ memcpy(pi->component_order, imagePtr->component_order, 32);
+ pi->scanline_order = imagePtr->scanline_order;
+ }
+ pa->nImages = adaptorPtr->nImages;
+ pa->pImages = pImage;
+ }
+
+ if(adaptorPtr->nAttributes &&
+ (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
+ {
+ for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
+ i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
+ {
+ pat->flags = attributePtr->flags;
+ pat->min_value = attributePtr->min_value;
+ pat->max_value = attributePtr->max_value;
+ if((pat->name = malloc(strlen(attributePtr->name) + 1)))
+ strcpy(pat->name, attributePtr->name);
+ }
+ pa->nAttributes = adaptorPtr->nAttributes;
+ pa->pAttributes = pAttribute;
+ }
+
+
+ totFormat = adaptorPtr->nFormats;
+
+ if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
+ i < adaptorPtr->nFormats; i++, formatPtr++)
+ {
+ numVisuals = pScreen->numVisuals;
+ pVisual = pScreen->visuals;
+
+ while(numVisuals--) {
+ if((pVisual->class == formatPtr->class) &&
+ (pVisual->nplanes == formatPtr->depth)) {
+
+ if(numFormat >= totFormat) {
+ void *moreSpace;
+ totFormat *= 2;
+ moreSpace = realloc(pFormat,
+ totFormat * sizeof(XvFormatRec));
+ if(!moreSpace) break;
+ pFormat = moreSpace;
+ pf = pFormat + numFormat;
+ }
+
+ pf->visual = pVisual->vid;
+ pf->depth = formatPtr->depth;
+
+ pf++;
+ numFormat++;
+ }
+ pVisual++;
+ }
+ }
+ pa->nFormats = numFormat;
+ pa->pFormats = pFormat;
+ if(!numFormat) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ adaptorPriv->flags = adaptorPtr->flags;
+ adaptorPriv->PutVideo = adaptorPtr->PutVideo;
+ adaptorPriv->PutStill = adaptorPtr->PutStill;
+ adaptorPriv->GetVideo = adaptorPtr->GetVideo;
+ adaptorPriv->GetStill = adaptorPtr->GetStill;
+ adaptorPriv->StopVideo = adaptorPtr->StopVideo;
+ adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
+ adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
+ adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
+ adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
+ adaptorPriv->PutImage = adaptorPtr->PutImage;
+ adaptorPriv->ReputImage = adaptorPtr->ReputImage;
+
+ pa->devPriv.ptr = (pointer)adaptorPriv;
+
+ if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pp = pPort, i = 0, numPort = 0;
+ i < adaptorPtr->nPorts; i++) {
+
+ if(!(pp->id = FakeClientID(0)))
+ continue;
+
+ if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
+ continue;
+
+ if(!AddResource(pp->id, PortResource, pp)) {
+ free(portPriv);
+ continue;
+ }
+
+ pp->pAdaptor = pa;
+ pp->pNotify = (XvPortNotifyPtr)NULL;
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->grab.client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ pp->devPriv.ptr = portPriv;
+
+ portPriv->pScrn = pScrn;
+ portPriv->AdaptorRec = adaptorPriv;
+ portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
+
+ pp++;
+ numPort++;
+ }
+ pa->nPorts = numPort;
+ pa->pPorts = pPort;
+ if(!numPort) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ pa->base_id = pPort->id;
+
+ pa++;
+ numAdaptor++;
+ }
+
+ if(numAdaptor) {
+ pxvs->nAdaptors = numAdaptor;
+ pxvs->pAdaptors = pAdaptor;
+ } else {
+ free(pAdaptor);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Video should be clipped to the intersection of the window cliplist
+ and the client cliplist specified in the GC for which the video was
+ initialized. When we need to reclip a window, the GC that started
+ the video may not even be around anymore. That's why we save the
+ client clip from the GC when the video is initialized. We then
+ use xf86XVUpdateCompositeClip to calculate the new composite clip
+ when we need it. This is different from what DEC did. They saved
+ the GC and used it's clip list when they needed to reclip the window,
+ even if the client clip was different from the one the video was
+ initialized with. If the original GC was destroyed, they had to stop
+ the video. I like the new method better (MArk).
+
+ This function only works for windows. Will need to rewrite when
+ (if) we support pixmap rendering.
+*/
+
+static void
+xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
+{
+ RegionPtr pregWin, pCompositeClip;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ Bool freeCompClip = FALSE;
+
+ if(portPriv->pCompositeClip)
+ return;
+
+ pWin = (WindowPtr)portPriv->pDraw;
+ pScreen = pWin->drawable.pScreen;
+
+ /* get window clip list */
+ if(portPriv->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeCompClip = TRUE;
+ } else
+ pregWin = &pWin->clipList;
+
+ if(!portPriv->clientClip) {
+ portPriv->pCompositeClip = pregWin;
+ portPriv->FreeCompositeClip = freeCompClip;
+ return;
+ }
+
+ pCompositeClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pCompositeClip, portPriv->clientClip);
+ REGION_TRANSLATE(pScreen, pCompositeClip,
+ portPriv->pDraw->x + portPriv->clipOrg.x,
+ portPriv->pDraw->y + portPriv->clipOrg.y);
+ REGION_INTERSECT(pScreen, pCompositeClip, pregWin, pCompositeClip);
+
+ portPriv->pCompositeClip = pCompositeClip;
+ portPriv->FreeCompositeClip = TRUE;
+
+ if(freeCompClip) {
+ REGION_DESTROY(pScreen, pregWin);
+ }
+}
+
+/* Save the current clientClip and update the CompositeClip whenever
+ we have a fresh GC */
+
+static void
+xf86XVCopyClip(
+ XvPortRecPrivatePtr portPriv,
+ GCPtr pGC
+){
+ /* copy the new clip if it exists */
+ if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
+ if(!portPriv->clientClip)
+ portPriv->clientClip = REGION_CREATE(pScreen, NullBox, 1);
+ /* Note: this is in window coordinates */
+ REGION_COPY(pScreen, portPriv->clientClip, pGC->clientClip);
+ } else if(portPriv->clientClip) { /* free the old clientClip */
+ REGION_DESTROY(pScreen, portPriv->clientClip);
+ portPriv->clientClip = NULL;
+ }
+
+ /* get rid of the old clip list */
+ if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
+ REGION_DESTROY(pScreen, portPriv->pCompositeClip);
+ }
+
+ portPriv->clipOrg = pGC->clipOrg;
+ portPriv->pCompositeClip = pGC->pCompositeClip;
+ portPriv->FreeCompositeClip = FALSE;
+ portPriv->subWindowMode = pGC->subWindowMode;
+}
+
+static int
+xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success)
+ portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success) portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+xf86XVReputImage(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
+ WinBox.x1, WinBox.y1,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputAllVideo(WindowPtr pWin, pointer data)
+{
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(WinPriv) {
+ if(WinPriv->PortRec->type == XvInputMask)
+ xf86XVReputVideo(WinPriv->PortRec);
+ else
+ xf86XVRegetVideo(WinPriv->PortRec);
+ WinPriv = WinPriv->next;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int
+xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, PrivRoot;
+
+ winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
+
+ /* Enlist our port in the window private */
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) /* we're already listed */
+ break;
+ winPriv = winPriv->next;
+ }
+
+ if(!winPriv) {
+ winPriv = calloc(1, sizeof(XF86XVWindowRec));
+ if(!winPriv) return BadAlloc;
+ winPriv->PortRec = portPriv;
+ winPriv->next = PrivRoot;
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
+ }
+
+ portPriv->pDraw = (DrawablePtr)pWin;
+
+ return Success;
+}
+
+
+static void
+xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, prevPriv = NULL;
+
+ winPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) {
+ if(prevPriv)
+ prevPriv->next = winPriv->next;
+ else
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ winPriv->next);
+ free(winPriv);
+ break;
+ }
+ prevPriv = winPriv;
+ winPriv = winPriv->next;
+ }
+ portPriv->pDraw = NULL;
+}
+
+/**** ScreenRec fields ****/
+
+static Bool
+xf86XVDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
+ int ret;
+
+ while(WinPriv) {
+ XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+ if(pPriv->isOn > XV_OFF) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+ }
+
+ pPriv->pDraw = NULL;
+ tmp = WinPriv;
+ if(WinPriv->pGC) {
+ FreeGC(WinPriv->pGC, 0);
+ }
+ WinPriv = WinPriv->next;
+ free(tmp);
+ }
+
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ ret = (*pScreen->DestroyWindow)(pWin);
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+
+ return ret;
+}
+
+
+static void
+xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XF86XVWindowPtr pPrev;
+ XvPortRecPrivatePtr pPriv;
+ Bool AreasExposed;
+
+ AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
+
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ (*pScreen->WindowExposures)(pWin, reg1, reg2);
+ pScreen->WindowExposures = xf86XVWindowExposures;
+
+ /* filter out XClearWindow/Area */
+ if (!pWin->valdata) return;
+
+ pPrev = NULL;
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ /* Reput anyone with a reput function */
+
+ switch(pPriv->type) {
+ case XvInputMask:
+ xf86XVReputVideo(pPriv);
+ break;
+ case XvOutputMask:
+ xf86XVRegetVideo(pPriv);
+ break;
+ default: /* overlaid still/image*/
+ if (pPriv->AdaptorRec->ReputImage)
+ xf86XVReputImage(pPriv);
+ else if(AreasExposed) {
+ XF86XVWindowPtr tmp;
+
+ if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ break;
+ }
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+}
+
+
+static void
+xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XF86XVWindowPtr tmp, pPrev = NULL;
+ XvPortRecPrivatePtr pPriv;
+ Bool visible = (pWin->visibility == VisibilityUnobscured) ||
+ (pWin->visibility == VisibilityPartiallyObscured);
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ if(!pPriv) goto next;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if (pPriv->AdaptorRec->ClipNotify)
+ (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
+ pWin, dx, dy);
+
+ /* Stop everything except images, but stop them too if the
+ window isn't visible. But we only remove the images. */
+
+ if(pPriv->type || !visible) {
+ if(pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+
+ if(!pPriv->type) { /* overlaid still/image */
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ }
+
+next:
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+
+ if(ScreenPriv->ClipNotify) {
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+ pScreen->ClipNotify = xf86XVClipNotify;
+ }
+}
+
+
+
+/**** Required XvScreenRec fields ****/
+
+static Bool
+xf86XVCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pa;
+ int c;
+
+ if(!ScreenPriv) return TRUE;
+
+ if(ScreenPriv->videoGC) {
+ FreeGC(ScreenPriv->videoGC, 0);
+ ScreenPriv->videoGC = NULL;
+ }
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+
+ pScrn->EnterVT = ScreenPriv->EnterVT;
+ pScrn->LeaveVT = ScreenPriv->LeaveVT;
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+
+ for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
+ xf86XVFreeAdaptor(pa);
+ }
+
+ free(pxvs->pAdaptors);
+ free(ScreenPriv);
+ return TRUE;
+}
+
+
+static int
+xf86XVQueryAdaptors(
+ ScreenPtr pScreen,
+ XvAdaptorPtr *p_pAdaptors,
+ int *p_nAdaptors
+){
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+
+ *p_nAdaptors = pxvs->nAdaptors;
+ *p_pAdaptors = pxvs->pAdaptors;
+
+ return (Success);
+}
+
+
+/**** ScrnInfoRec fields ****/
+
+static Bool
+xf86XVEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ Bool ret;
+
+ ret = (*ScreenPriv->EnterVT)(index, flags);
+
+ if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
+
+ return ret;
+}
+
+static void
+xf86XVLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pAdaptor;
+ XvPortPtr pPort;
+ XvPortRecPrivatePtr pPriv;
+ int i, j;
+
+ for(i = 0; i < pxvs->nAdaptors; i++) {
+ pAdaptor = &pxvs->pAdaptors[i];
+ for(j = 0; j < pAdaptor->nPorts; j++) {
+ pPort = &pAdaptor->pPorts[j];
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv->isOn > XV_OFF) {
+
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if(!pPriv->type && pPriv->pDraw) { /* still */
+ xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
+ }
+ }
+ }
+ }
+
+ (*ScreenPriv->LeaveVT)(index, flags);
+}
+
+static void
+xf86XVAdjustFrame(int index, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = pScrn->pScreen;
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ WindowPtr pWin;
+ XvAdaptorPtr pa;
+ int c, i;
+
+ if(ScreenPriv->AdjustFrame) {
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+ (*pScrn->AdjustFrame)(index, x, y, flags);
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+ }
+
+ for(c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
+ XvPortPtr pPort = pa->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = pa->nPorts; i > 0; i--, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+
+ if(!pPriv->type && (pPriv->isOn != XV_OFF)) { /* overlaid still/image */
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ pWin = (WindowPtr)pPriv->pDraw;
+
+ if ((pPriv->AdaptorRec->ReputImage) &&
+ ((pWin->visibility == VisibilityUnobscured) ||
+ (pWin->visibility == VisibilityPartiallyObscured)))
+ {
+ xf86XVReputImage(pPriv);
+ } else if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ xf86XVRemovePortFromWindow(pWin, pPriv);
+ pPriv->isOn = XV_PENDING;
+ continue;
+ }
+ }
+ }
+ }
+}
+
+
+/**** XvAdaptorRec fields ****/
+
+static int
+xf86XVAllocatePort(
+ unsigned long port,
+ XvPortPtr pPort,
+ XvPortPtr *ppPort
+){
+ *ppPort = pPort;
+ return Success;
+}
+
+
+
+static int
+xf86XVFreePort(XvPortPtr pPort)
+{
+ return Success;
+}
+
+
+static int
+xf86XVPutVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No dumping video to pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvInputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVReputVideo(portPriv));
+}
+
+static int
+xf86XVPutStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
+
+ xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ portPriv->isOn = XV_ON;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+xf86XVGetVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvOutputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVRegetVideo(portPriv));
+}
+
+static int
+xf86XVGetStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto GET_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+GET_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+
+static int
+xf86XVStopVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ if(pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ /* Must free resources. */
+
+ if(portPriv->isOn > XV_OFF) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
+ portPriv->isOn = XV_OFF;
+ }
+
+ return Success;
+}
+
+static int
+xf86XVSetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
+ attribute, value, portPriv->DevPriv.ptr));
+}
+
+
+static int
+xf86XVGetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 *p_value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
+ attribute, p_value, portPriv->DevPriv.ptr));
+}
+
+
+
+static int
+xf86XVQueryBestSize(
+ ClientPtr client,
+ XvPortPtr pPort,
+ CARD8 motion,
+ CARD16 vid_w, CARD16 vid_h,
+ CARD16 drw_w, CARD16 drw_h,
+ unsigned int *p_w, unsigned int *p_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
+ (Bool)motion, vid_w, vid_h, drw_w, drw_h,
+ p_w, p_h, portPriv->DevPriv.ptr);
+
+ return Success;
+}
+
+
+static int
+xf86XVPutImage(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 src_x, INT16 src_y,
+ CARD16 src_w, CARD16 src_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h,
+ XvImagePtr format,
+ unsigned char* data,
+ Bool sync,
+ CARD16 width, CARD16 height
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(ret != Success) goto PUT_IMAGE_BAILOUT;
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
+ src_x, src_y, WinBox.x1, WinBox.y1,
+ src_w, src_h, drw_w, drw_h, format->id, data, width, height,
+ sync, &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
+
+ portPriv->isOn = XV_ON;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_IMAGE_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVQueryImageAttributes(
+ ClientPtr client,
+ XvPortPtr pPort,
+ XvImagePtr format,
+ CARD16 *width,
+ CARD16 *height,
+ int *pitches,
+ int *offsets
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
+ format->id, width, height, pitches, offsets);
+}
+
+
+void
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin = (WindowPtr)pDraw;
+ XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
+ GCPtr pGC = NULL;
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle *rects;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ if(pPriv)
+ pGC = pPriv->pGC;
+
+ if(!pGC) {
+ int status;
+ XID pval[2];
+ pval[0] = key;
+ pval[1] = IncludeInferiors;
+ pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
+ (XID)0, serverClient);
+ if(!pGC) return;
+ ValidateGC(pDraw, pGC);
+ if (pPriv) pPriv->pGC = pGC;
+ } else if (key != pGC->fgPixel){
+ ChangeGCVal val;
+ val.val = key;
+ ChangeGC(NullClient, pGC, GCForeground, &val);
+ ValidateGC(pDraw, pGC);
+ }
+
+ REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y);
+
+ rects = malloc(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++) {
+ rects[i].x = pbox->x1;
+ rects[i].y = pbox->y1;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
+
+ if (!pPriv) FreeGC(pGC, 0);
+
+ free(rects);
+}
+
+void
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+{
+ DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
+ ChangeGCVal pval[2];
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle *rects;
+ GCPtr gc;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ gc = GetScratchGC(root->depth, pScreen);
+ pval[0].val = key;
+ pval[1].val = IncludeInferiors;
+ (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
+ ValidateGC(root, gc);
+
+ rects = malloc(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++)
+ {
+ rects[i].x = pbox->x1;
+ rects[i].y = pbox->y1;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+
+ free(rects);
+ FreeScratchGC (gc);
+}
+
+/* xf86XVClipVideoHelper -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+#define DummyScreen screenInfo.screens[0]
+
+Bool
+xf86XVClipVideoHelper(
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height
+){
+ double xsw, xdw, ysw, ydw;
+ INT32 delta;
+ BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
+ int diff;
+
+ xsw = (*xb - *xa) << 16;
+ xdw = dst->x2 - dst->x1;
+ ysw = (*yb - *ya) << 16;
+ ydw = dst->y2 - dst->y1;
+
+ *xa <<= 16; *xb <<= 16;
+ *ya <<= 16; *yb <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if (diff > 0) {
+ dst->x1 = extents->x1;
+ *xa += (diff * xsw) / xdw;
+ }
+ diff = dst->x2 - extents->x2;
+ if (diff > 0) {
+ dst->x2 = extents->x2;
+ *xb -= (diff * xsw) / xdw;
+ }
+ diff = extents->y1 - dst->y1;
+ if (diff > 0) {
+ dst->y1 = extents->y1;
+ *ya += (diff * ysw) / ydw;
+ }
+ diff = dst->y2 - extents->y2;
+ if (diff > 0) {
+ dst->y2 = extents->y2;
+ *yb -= (diff * ysw) / ydw;
+ }
+
+ if (*xa < 0) {
+ diff = (((-*xa) * xdw) + xsw - 1) / xsw;
+ dst->x1 += diff;
+ *xa += (diff * xsw) / xdw;
+ }
+ delta = *xb - (width << 16);
+ if (delta > 0) {
+ diff = ((delta * xdw) + xsw - 1) / xsw;
+ dst->x2 -= diff;
+ *xb -= (diff * xsw) / xdw;
+ }
+ if (*xa >= *xb) return FALSE;
+
+ if (*ya < 0) {
+ diff = (((-*ya) * ydw) + ysw - 1) / ysw;
+ dst->y1 += diff;
+ *ya += (diff * ysw) / ydw;
+ }
+ delta = *yb - (height << 16);
+ if (delta > 0) {
+ diff = ((delta * ydw) + ysw - 1) / ysw;
+ dst->y2 -= diff;
+ *yb -= (diff * ysw) / ydw;
+ }
+ if (*ya >= *yb) return FALSE;
+
+ if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
+ (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
+ {
+ RegionRec clipReg;
+ REGION_INIT(DummyScreen, &clipReg, dst, 1);
+ REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
+ REGION_UNINIT(DummyScreen, &clipReg);
+ }
+ return TRUE;
+}
+
+void
+xf86XVCopyYUV12ToPacked(
+ const void *srcy,
+ const void *srcv,
+ const void *srcu,
+ void *dst,
+ int srcPitchy,
+ int srcPitchuv,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *Dst;
+ const CARD8 *Y, *U, *V;
+ int i, j;
+
+ w >>= 1;
+
+ for (j = 0; j < h; j++) {
+ Dst = dst;
+ Y = srcy; V = srcv; U = srcu;
+ i = w;
+ while (i >= 4) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+ Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
+ Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
+ Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+ Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
+ Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
+ Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
+#endif
+ Dst += 4; Y += 8; V += 4; U += 4;
+ i -= 4;
+ }
+
+ while (i--) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+#endif
+ Dst++; Y += 2; V++; U++;
+ }
+
+ dst = (CARD8 *)dst + dstPitch;
+ srcy = (const CARD8 *)srcy + srcPitchy;
+ if (j & 1) {
+ srcu = (const CARD8 *)srcu + srcPitchuv;
+ srcv = (const CARD8 *)srcv + srcPitchuv;
+ }
+ }
+}
+
+void
+xf86XVCopyPacked(
+ const void *src,
+ void *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ const CARD32 *Src;
+ CARD32 *Dst;
+ int i;
+
+ w >>= 1;
+ while (--h >= 0) {
+ do {
+ Dst = dst; Src = src;
+ i = w;
+ while (i >= 4) {
+ Dst[0] = Src[0];
+ Dst[1] = Src[1];
+ Dst[2] = Src[2];
+ Dst[3] = Src[3];
+ Dst += 4; Src += 4; i -= 4;
+ }
+ if (!i) break;
+ Dst[0] = Src[0];
+ if (i == 1) break;
+ Dst[1] = Src[1];
+ if (i == 2) break;
+ Dst[2] = Src[2];
+ } while (0);
+
+ src = (const CARD8 *)src + srcPitch;
+ dst = (CARD8 *)dst + dstPitch;
+ }
+}
diff --git a/xorg-server/hw/xfree86/common/xf86xvmc.c b/xorg-server/hw/xfree86/common/xf86xvmc.c
index 39d33da08..9cf36f526 100644
--- a/xorg-server/hw/xfree86/common/xf86xvmc.c
+++ b/xorg-server/hw/xfree86/common/xf86xvmc.c
@@ -1,229 +1,229 @@
-
-/*
- * Copyright (c) 2001-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "resource.h"
-#include "dixstruct.h"
-
-#include "xvmodproc.h"
-
-#include "xf86xvpriv.h"
-#include "xf86xvmc.h"
-
-XvMCScreenInitProcPtr XvMCScreenInitProc = NULL;
-
-
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- int num_adaptors;
- XF86MCAdaptorPtr *adaptors;
- XvMCAdaptorPtr dixinfo;
-} xf86XvMCScreenRec, *xf86XvMCScreenPtr;
-
-static int XF86XvMCScreenKeyIndex;
-static DevPrivateKey XF86XvMCScreenKey = &XF86XvMCScreenKeyIndex;
-
-#define XF86XVMC_GET_PRIVATE(pScreen) (xf86XvMCScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, XF86XvMCScreenKey)
-
-
-static int
-xf86XvMCCreateContext (
- XvPortPtr pPort,
- XvMCContextPtr pContext,
- int *num_priv,
- CARD32 **priv
-)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- pContext->port_priv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateContext)(
- pScrn, pContext, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroyContext ( XvMCContextPtr pContext)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroyContext)(
- pScrn, pContext);
-}
-
-static int
-xf86XvMCCreateSurface (
- XvMCSurfacePtr pSurface,
- int *num_priv,
- CARD32 **priv
-)
-{
- XvMCContextPtr pContext = pSurface->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSurface)(
- pScrn, pSurface, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroySurface (XvMCSurfacePtr pSurface)
-{
- XvMCContextPtr pContext = pSurface->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySurface)(
- pScrn, pSurface);
-}
-
-static int
-xf86XvMCCreateSubpicture (
- XvMCSubpicturePtr pSubpicture,
- int *num_priv,
- CARD32 **priv
-)
-{
- XvMCContextPtr pContext = pSubpicture->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSubpicture)(
- pScrn, pSubpicture, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroySubpicture (XvMCSubpicturePtr pSubpicture)
-{
- XvMCContextPtr pContext = pSubpicture->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySubpicture)(
- pScrn, pSubpicture);
-}
-
-
-static Bool
-xf86XvMCCloseScreen (int i, ScreenPtr pScreen)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
-
- xfree(pScreenPriv->dixinfo);
- xfree(pScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-Bool xf86XvMCScreenInit(
- ScreenPtr pScreen,
- int num_adaptors,
- XF86MCAdaptorPtr *adaptors
-)
-{
- XvMCAdaptorPtr pAdapt;
- xf86XvMCScreenPtr pScreenPriv;
- XvScreenPtr pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- XF86XvScreenKey);
- int i, j;
-
- if(!XvMCScreenInitProc) return FALSE;
-
- if(!(pAdapt = xalloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
- return FALSE;
-
- if(!(pScreenPriv = xalloc(sizeof(xf86XvMCScreenRec)))) {
- xfree(pAdapt);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, XF86XvMCScreenKey, pScreenPriv);
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86XvMCCloseScreen;
-
- pScreenPriv->num_adaptors = num_adaptors;
- pScreenPriv->adaptors = adaptors;
- pScreenPriv->dixinfo = pAdapt;
-
- for(i = 0; i < num_adaptors; i++) {
- pAdapt[i].xv_adaptor = NULL;
- for(j = 0; j < pxvs->nAdaptors; j++) {
- if(!strcmp((*adaptors)->name, pxvs->pAdaptors[j].name)) {
- pAdapt[i].xv_adaptor = &(pxvs->pAdaptors[j]);
- break;
- }
- }
- if(!pAdapt[i].xv_adaptor) {
- /* no adaptor by that name */
- xfree(pAdapt);
- return FALSE;
- }
- pAdapt[i].num_surfaces = (*adaptors)->num_surfaces;
- pAdapt[i].surfaces = (XvMCSurfaceInfoPtr*)((*adaptors)->surfaces);
- pAdapt[i].num_subpictures = (*adaptors)->num_subpictures;
- pAdapt[i].subpictures = (XvImagePtr*)((*adaptors)->subpictures);
- pAdapt[i].CreateContext = xf86XvMCCreateContext;
- pAdapt[i].DestroyContext = xf86XvMCDestroyContext;
- pAdapt[i].CreateSurface = xf86XvMCCreateSurface;
- pAdapt[i].DestroySurface = xf86XvMCDestroySurface;
- pAdapt[i].CreateSubpicture = xf86XvMCCreateSubpicture;
- pAdapt[i].DestroySubpicture = xf86XvMCDestroySubpicture;
- adaptors++;
- }
-
- if(Success != (*XvMCScreenInitProc)(pScreen, num_adaptors, pAdapt))
- return FALSE;
-
- return TRUE;
-}
-
-XF86MCAdaptorPtr xf86XvMCCreateAdaptorRec (void)
-{
- return xcalloc(1, sizeof(XF86MCAdaptorRec));
-}
-
-void xf86XvMCDestroyAdaptorRec(XF86MCAdaptorPtr adaptor)
-{
- xfree(adaptor);
-}
+
+/*
+ * Copyright (c) 2001-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+
+#include "xvmodproc.h"
+
+#include "xf86xvpriv.h"
+#include "xf86xvmc.h"
+
+XvMCScreenInitProcPtr XvMCScreenInitProc = NULL;
+
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ int num_adaptors;
+ XF86MCAdaptorPtr *adaptors;
+ XvMCAdaptorPtr dixinfo;
+} xf86XvMCScreenRec, *xf86XvMCScreenPtr;
+
+static int XF86XvMCScreenKeyIndex;
+static DevPrivateKey XF86XvMCScreenKey = &XF86XvMCScreenKeyIndex;
+
+#define XF86XVMC_GET_PRIVATE(pScreen) (xf86XvMCScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, XF86XvMCScreenKey)
+
+
+static int
+xf86XvMCCreateContext (
+ XvPortPtr pPort,
+ XvMCContextPtr pContext,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ pContext->port_priv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateContext)(
+ pScrn, pContext, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroyContext ( XvMCContextPtr pContext)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroyContext)(
+ pScrn, pContext);
+}
+
+static int
+xf86XvMCCreateSurface (
+ XvMCSurfacePtr pSurface,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ XvMCContextPtr pContext = pSurface->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSurface)(
+ pScrn, pSurface, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroySurface (XvMCSurfacePtr pSurface)
+{
+ XvMCContextPtr pContext = pSurface->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySurface)(
+ pScrn, pSurface);
+}
+
+static int
+xf86XvMCCreateSubpicture (
+ XvMCSubpicturePtr pSubpicture,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ XvMCContextPtr pContext = pSubpicture->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSubpicture)(
+ pScrn, pSubpicture, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroySubpicture (XvMCSubpicturePtr pSubpicture)
+{
+ XvMCContextPtr pContext = pSubpicture->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySubpicture)(
+ pScrn, pSubpicture);
+}
+
+
+static Bool
+xf86XvMCCloseScreen (int i, ScreenPtr pScreen)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
+ free(pScreenPriv->dixinfo);
+ free(pScreenPriv);
+
+ return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+Bool xf86XvMCScreenInit(
+ ScreenPtr pScreen,
+ int num_adaptors,
+ XF86MCAdaptorPtr *adaptors
+)
+{
+ XvMCAdaptorPtr pAdapt;
+ xf86XvMCScreenPtr pScreenPriv;
+ XvScreenPtr pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ XF86XvScreenKey);
+ int i, j;
+
+ if(!XvMCScreenInitProc) return FALSE;
+
+ if(!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
+ return FALSE;
+
+ if(!(pScreenPriv = malloc(sizeof(xf86XvMCScreenRec)))) {
+ free(pAdapt);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, XF86XvMCScreenKey, pScreenPriv);
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86XvMCCloseScreen;
+
+ pScreenPriv->num_adaptors = num_adaptors;
+ pScreenPriv->adaptors = adaptors;
+ pScreenPriv->dixinfo = pAdapt;
+
+ for(i = 0; i < num_adaptors; i++) {
+ pAdapt[i].xv_adaptor = NULL;
+ for(j = 0; j < pxvs->nAdaptors; j++) {
+ if(!strcmp((*adaptors)->name, pxvs->pAdaptors[j].name)) {
+ pAdapt[i].xv_adaptor = &(pxvs->pAdaptors[j]);
+ break;
+ }
+ }
+ if(!pAdapt[i].xv_adaptor) {
+ /* no adaptor by that name */
+ free(pAdapt);
+ return FALSE;
+ }
+ pAdapt[i].num_surfaces = (*adaptors)->num_surfaces;
+ pAdapt[i].surfaces = (XvMCSurfaceInfoPtr*)((*adaptors)->surfaces);
+ pAdapt[i].num_subpictures = (*adaptors)->num_subpictures;
+ pAdapt[i].subpictures = (XvImagePtr*)((*adaptors)->subpictures);
+ pAdapt[i].CreateContext = xf86XvMCCreateContext;
+ pAdapt[i].DestroyContext = xf86XvMCDestroyContext;
+ pAdapt[i].CreateSurface = xf86XvMCCreateSurface;
+ pAdapt[i].DestroySurface = xf86XvMCDestroySurface;
+ pAdapt[i].CreateSubpicture = xf86XvMCCreateSubpicture;
+ pAdapt[i].DestroySubpicture = xf86XvMCDestroySubpicture;
+ adaptors++;
+ }
+
+ if(Success != (*XvMCScreenInitProc)(pScreen, num_adaptors, pAdapt))
+ return FALSE;
+
+ return TRUE;
+}
+
+XF86MCAdaptorPtr xf86XvMCCreateAdaptorRec (void)
+{
+ return calloc(1, sizeof(XF86MCAdaptorRec));
+}
+
+void xf86XvMCDestroyAdaptorRec(XF86MCAdaptorPtr adaptor)
+{
+ free(adaptor);
+}
diff --git a/xorg-server/hw/xfree86/common/xisb.c b/xorg-server/hw/xfree86/common/xisb.c
index 1cb9e4854..f08327fb3 100644
--- a/xorg-server/hw/xfree86/common/xisb.c
+++ b/xorg-server/hw/xfree86/common/xisb.c
@@ -1,174 +1,174 @@
-/*
- * Copyright (c) 1997 Metro Link Incorporated
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- *
- */
-
-/*
- X Input Serial Buffer routines for use in any XInput driver that accesses
- a serial device.
-*/
-
-
-/*****************************************************************************
- * Standard Headers
- ****************************************************************************/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <misc.h>
-#include <xf86.h>
-#include <xf86_OSproc.h>
-#include <xf86_OSlib.h>
-#include <xf86Xinput.h>
-#include "xisb.h"
-
-/*****************************************************************************
- * Local Headers
- ****************************************************************************/
-
-/*****************************************************************************
- * Variables without includable headers
- ****************************************************************************/
-
-/*****************************************************************************
- * Local Variables
- ****************************************************************************/
-
-/*****************************************************************************
- * Function Definitions
- ****************************************************************************/
-
-XISBuffer *
-XisbNew (int fd, ssize_t size)
-{
- XISBuffer *b;
-
- b = xalloc (sizeof (XISBuffer));
- if (!b)
- return (NULL);
- b->buf = xalloc ((sizeof (unsigned char) * size));
- if (!b->buf)
- {
- xfree (b);
- return (NULL);
- }
-
- b->fd = fd;
- b->trace = 0;
- b->block_duration = 0;
- b->current = 1; /* force it to be past the end to trigger initial read */
- b->end = 0;
- b->buffer_size = size;
- return (b);
-}
-
-void
-XisbFree (XISBuffer *b)
-{
- xfree (b->buf);
- xfree (b);
-}
-
-int
-XisbRead (XISBuffer *b)
-{
- int ret;
-
- if (b->current >= b->end)
- {
- if (b->block_duration >= 0)
- {
- if (xf86WaitForInput (b->fd, b->block_duration) < 1)
- return (-1);
- }
- else
- {
- /*
- * automatically clear it so if XisbRead is called in a loop
- * the next call will make sure there is data with select and
- * thus prevent a blocking read
- */
- b->block_duration = 0;
- }
-
- ret = xf86ReadSerial (b->fd, b->buf, b->buffer_size);
- switch (ret)
- {
- case 0:
- return (-1); /* timeout */
- case -1:
- return (-2); /* error */
- default:
- b->end = ret;
- b->current = 0;
- break;
- }
- }
- if (b->trace)
- ErrorF ("read 0x%02x (%c)\n", b->buf[b->current],
- isprint(b->buf[b->current])?b->buf[b->current]:'.');
-
- return (b->buf[b->current++]);
-}
-
-/* the only purpose of this function is to provide output tracing */
-ssize_t
-XisbWrite (XISBuffer *b, unsigned char *msg, ssize_t len)
-{
- if (b->trace)
- {
- int i = 0;
- for (i = 0; i < len; i++)
- ErrorF ("\t\twrote 0x%02x (%c)\n", msg[i], msg[i]);
- }
- return (xf86WriteSerial (b->fd, msg, len));
-}
-
-/* turn tracing of this buffer on (1) or off (0) */
-void
-XisbTrace (XISBuffer *b, int trace)
-{
- b->trace = trace;
-}
-
-/*
- * specify a block_duration of -1 when you know the buffer's fd is ready to
- * read. After a read, it is automatically set to 0 so that the next read
- * will use check to select for data and prevent a block.
- * It is the caller's responsibility to set the block_duration to -1 if it
- * knows that there is data to read (because the main select loop triggered
- * the read) and want's to avoid the unnecessary overhead of the select call
- *
- * a zero or positive block duration will cause the select to block for the
- * give duration in usecs.
- */
-
-void
-XisbBlockDuration (XISBuffer *b, int block_duration)
-{
- b->block_duration = block_duration;
-}
+/*
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/*
+ X Input Serial Buffer routines for use in any XInput driver that accesses
+ a serial device.
+*/
+
+
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#include <xf86_OSproc.h>
+#include <xf86_OSlib.h>
+#include <xf86Xinput.h>
+#include "xisb.h"
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+XISBuffer *
+XisbNew (int fd, ssize_t size)
+{
+ XISBuffer *b;
+
+ b = malloc(sizeof (XISBuffer));
+ if (!b)
+ return (NULL);
+ b->buf = malloc((sizeof (unsigned char) * size));
+ if (!b->buf)
+ {
+ free(b);
+ return (NULL);
+ }
+
+ b->fd = fd;
+ b->trace = 0;
+ b->block_duration = 0;
+ b->current = 1; /* force it to be past the end to trigger initial read */
+ b->end = 0;
+ b->buffer_size = size;
+ return (b);
+}
+
+void
+XisbFree (XISBuffer *b)
+{
+ free(b->buf);
+ free(b);
+}
+
+int
+XisbRead (XISBuffer *b)
+{
+ int ret;
+
+ if (b->current >= b->end)
+ {
+ if (b->block_duration >= 0)
+ {
+ if (xf86WaitForInput (b->fd, b->block_duration) < 1)
+ return (-1);
+ }
+ else
+ {
+ /*
+ * automatically clear it so if XisbRead is called in a loop
+ * the next call will make sure there is data with select and
+ * thus prevent a blocking read
+ */
+ b->block_duration = 0;
+ }
+
+ ret = xf86ReadSerial (b->fd, b->buf, b->buffer_size);
+ switch (ret)
+ {
+ case 0:
+ return (-1); /* timeout */
+ case -1:
+ return (-2); /* error */
+ default:
+ b->end = ret;
+ b->current = 0;
+ break;
+ }
+ }
+ if (b->trace)
+ ErrorF ("read 0x%02x (%c)\n", b->buf[b->current],
+ isprint(b->buf[b->current])?b->buf[b->current]:'.');
+
+ return (b->buf[b->current++]);
+}
+
+/* the only purpose of this function is to provide output tracing */
+ssize_t
+XisbWrite (XISBuffer *b, unsigned char *msg, ssize_t len)
+{
+ if (b->trace)
+ {
+ int i = 0;
+ for (i = 0; i < len; i++)
+ ErrorF ("\t\twrote 0x%02x (%c)\n", msg[i], msg[i]);
+ }
+ return (xf86WriteSerial (b->fd, msg, len));
+}
+
+/* turn tracing of this buffer on (1) or off (0) */
+void
+XisbTrace (XISBuffer *b, int trace)
+{
+ b->trace = trace;
+}
+
+/*
+ * specify a block_duration of -1 when you know the buffer's fd is ready to
+ * read. After a read, it is automatically set to 0 so that the next read
+ * will use check to select for data and prevent a block.
+ * It is the caller's responsibility to set the block_duration to -1 if it
+ * knows that there is data to read (because the main select loop triggered
+ * the read) and want's to avoid the unnecessary overhead of the select call
+ *
+ * a zero or positive block duration will cause the select to block for the
+ * give duration in usecs.
+ */
+
+void
+XisbBlockDuration (XISBuffer *b, int block_duration)
+{
+ b->block_duration = block_duration;
+}