diff options
Diffstat (limited to 'xorg-server/hw/xfree86')
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86Cursor.c | 2 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86RandR.c | 3 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86Xinput.c | 40 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86Xinput.h | 1 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86pciBus.c | 10 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/modes/xf86RandR12.c | 2 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/alpha_video.c | 69 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/arm_video.c | 7 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/bsd_init.c | 1 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/i386_video.c | 5 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/ppc_video.c | 9 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c | 4 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/linux/lnx_video.c | 1758 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/shared/bios_mmap.c | 278 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/os-support/xf86_OSlib.h | 23 | ||||
-rw-r--r-- | xorg-server/hw/xfree86/parser/scan.c | 2343 |
16 files changed, 2241 insertions, 2314 deletions
diff --git a/xorg-server/hw/xfree86/common/xf86Cursor.c b/xorg-server/hw/xfree86/common/xf86Cursor.c index 929f047cc..6f5d726f0 100644 --- a/xorg-server/hw/xfree86/common/xf86Cursor.c +++ b/xorg-server/hw/xfree86/common/xf86Cursor.c @@ -838,6 +838,8 @@ xf86InitOrigins(void) FillOutEdge(pLayout->down, pScreen->width); } } + + update_desktop_dimensions(); } void diff --git a/xorg-server/hw/xfree86/common/xf86RandR.c b/xorg-server/hw/xfree86/common/xf86RandR.c index 4663d0366..d0e47841e 100644 --- a/xorg-server/hw/xfree86/common/xf86RandR.c +++ b/xorg-server/hw/xfree86/common/xf86RandR.c @@ -313,6 +313,9 @@ xf86RandRSetConfig (ScreenPtr pScreen, return FALSE; } + + update_desktop_dimensions(); + /* * Move the cursor back where it belongs; SwitchMode repositions it * FIXME: duplicated code, see modes/xf86RandR12.c diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c index 425b35957..c3ffc27d0 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.c +++ b/xorg-server/hw/xfree86/common/xf86Xinput.c @@ -910,35 +910,38 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs, return BadAlloc; nt_list_for_each_entry(option, options, list.next) { - if (strcasecmp(input_option_get_key(option), "driver") == 0) { + const char *key = input_option_get_key(option); + const char *value = input_option_get_value(option); + + if (strcasecmp(key, "driver") == 0) { if (pInfo->driver) { rval = BadRequest; goto unwind; } - pInfo->driver = xstrdup(input_option_get_value(option)); + pInfo->driver = xstrdup(value); if (!pInfo->driver) { rval = BadAlloc; goto unwind; } } - if (strcasecmp(input_option_get_key(option), "name") == 0 || - strcasecmp(input_option_get_key(option), "identifier") == 0) { + if (strcasecmp(key, "name") == 0 || + strcasecmp(key, "identifier") == 0) { if (pInfo->name) { rval = BadRequest; goto unwind; } - pInfo->name = xstrdup(input_option_get_value(option)); + pInfo->name = xstrdup(value); if (!pInfo->name) { rval = BadAlloc; goto unwind; } } - if (strcmp(input_option_get_key(option), "_source") == 0 && - (strcmp(input_option_get_value(option), "server/hal") == 0 || - strcmp(input_option_get_value(option), "server/udev") == 0 || - strcmp(input_option_get_value(option), "server/wscons") == 0)) { + if (strcmp(key, "_source") == 0 && + (strcmp(value, "server/hal") == 0 || + strcmp(value, "server/udev") == 0 || + strcmp(value, "server/wscons") == 0)) { is_auto = 1; if (!xf86Info.autoAddDevices) { rval = BadMatch; @@ -1346,25 +1349,6 @@ xf86ScaleAxis(int Cx, 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(InputInfoPtr pInfo, - int screen_number, - int x, - int y) -{ - if (miPointerGetScreen(pInfo->dev) != - screenInfo.screens[screen_number]) { - miPointerSetScreen(pInfo->dev, screen_number, x, y); - } -} - - Bool xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, int resolution, int min_res, int max_res, int mode) diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.h b/xorg-server/hw/xfree86/common/xf86Xinput.h index 189f7abaf..909fb57d6 100644 --- a/xorg-server/hw/xfree86/common/xf86Xinput.h +++ b/xorg-server/hw/xfree86/common/xf86Xinput.h @@ -143,7 +143,6 @@ extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int ke int is_down); extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void); extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min); -extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y); extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, XF86OptionPtr options); extern _X_EXPORT Bool xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, int resolution, int min_res, diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c index eb5323cf0..bc09bd20c 100644 --- a/xorg-server/hw/xfree86/common/xf86pciBus.c +++ b/xorg-server/hw/xfree86/common/xf86pciBus.c @@ -1116,7 +1116,15 @@ videoPtrToDriverList(struct pci_device *dev, break; case 0x102b: driverList[0] = "mga"; break; case 0x10c8: driverList[0] = "neomagic"; break; - case 0x10de: case 0x12d2: driverList[0] = "nv"; break; + case 0x10de: case 0x12d2: + { + int idx = 0; +#ifdef __linux__ + driverList[idx++] = "nouveau"; +#endif + driverList[idx++] = "nv"; + break; + } case 0x1106: driverList[0] = "openchrome"; break; case 0x1b36: driverList[0] = "qxl"; break; case 0x1163: driverList[0] = "rendition"; break; diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c index cb20d1c35..d5031a2f1 100644 --- a/xorg-server/hw/xfree86/modes/xf86RandR12.c +++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c @@ -736,6 +736,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, xf86SetViewport (pScreen, 0, 0); finish: + update_desktop_dimensions(); + if (pRoot && pScrn->vtSema) (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE); #if RANDR_12_INTERFACE diff --git a/xorg-server/hw/xfree86/os-support/bsd/alpha_video.c b/xorg-server/hw/xfree86/os-support/bsd/alpha_video.c index 15eb2a422..882fb3b46 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/alpha_video.c +++ b/xorg-server/hw/xfree86/os-support/bsd/alpha_video.c @@ -33,12 +33,10 @@ #include <sys/param.h> #ifndef __NetBSD__ -# include <sys/sysctl.h> -# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -# include <machine/sysarch.h> -# endif -# else -# include <machine/sysarch.h> +#include <sys/sysctl.h> +#endif +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) +#include <machine/sysarch.h> #endif #include "xf86Axp.h" @@ -52,10 +50,6 @@ #define MAP_FLAGS (MAP_FILE | MAP_SHARED) #endif -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t)-1) -#endif - axpDevice bsdGetAXP(void); #ifndef __NetBSD__ @@ -64,8 +58,6 @@ extern unsigned long dense_base(void); static int axpSystem = -1; static unsigned long hae_thresh; static unsigned long hae_mask; -static unsigned long bus_base; -static unsigned long sparse_size; static unsigned long memory_base(void) @@ -197,7 +189,6 @@ static int devMemFd = -1; #ifdef HAS_APERTURE_DRV #define DEV_APERTURE "/dev/xf86" #endif -#define DEV_MEM "/dev/mem" static pointer mapVidMem(int, unsigned long, unsigned long, int); static void unmapVidMem(int, pointer, unsigned long); @@ -297,7 +288,6 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem) axpSystem = bsdGetAXP(); hae_thresh = xf86AXPParams[axpSystem].hae_thresh; hae_mask = xf86AXPParams[axpSystem].hae_mask; - sparse_size = xf86AXPParams[axpSystem].size; #endif /* __NetBSD__ */ } pVidMem->initialised = TRUE; @@ -440,7 +430,6 @@ xf86DisableIO() #define vuip volatile unsigned int * -static unsigned long msb_set = 0; static pointer memSBase = 0; static pointer memBase = 0; @@ -478,29 +467,25 @@ writeSparse32(int Value, pointer Base, register unsigned long Offset); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) extern int sysarch(int, void *); -#endif struct parms { u_int64_t hae; }; -#ifndef __NetBSD__ -static int +static void sethae(u_int64_t hae) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #ifndef ALPHA_SETHAE #define ALPHA_SETHAE 0 #endif - struct parms p; - p.hae = hae; - return (sysarch(ALPHA_SETHAE, (char *)&p)); -#endif -#ifdef __OpenBSD__ - return -1; -#endif + static struct parms p; + + if (p.hae != hae) { + p.hae = hae; + sysarch(ALPHA_SETHAE, (char *)&p); + } } -#endif /* __NetBSD__ */ +#endif static pointer mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags) @@ -555,12 +540,9 @@ readSparse8(pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } result = *(vuip) ((unsigned long)memSBase + (Offset << 5)); result >>= shift; @@ -579,12 +561,9 @@ readSparse16(pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } result = *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))); result >>= shift; @@ -609,12 +588,9 @@ writeSparse8(int Value, pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } *(vuip) ((unsigned long)memSBase + (Offset << 5)) = b * 0x01010101; } @@ -630,12 +606,9 @@ writeSparse16(int Value, pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) = w * 0x00010001; @@ -660,12 +633,9 @@ writeSparseNB8(int Value, pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } *(vuip) ((unsigned long)memSBase + (Offset << 5)) = b * 0x01010101; } @@ -680,12 +650,9 @@ writeSparseNB16(int Value, pointer Base, register unsigned long Offset) if (Offset >= (hae_thresh)) { msb = Offset & hae_mask ; Offset -= msb; - if (msb_set != msb) { -#ifndef __NetBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) sethae(msb); #endif - msb_set = msb; - } } *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) = w * 0x00010001; diff --git a/xorg-server/hw/xfree86/os-support/bsd/arm_video.c b/xorg-server/hw/xfree86/os-support/bsd/arm_video.c index eb631a7f3..1de6c87d6 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/arm_video.c +++ b/xorg-server/hw/xfree86/os-support/bsd/arm_video.c @@ -97,11 +97,6 @@ struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL, #define MAP_FLAGS (MAP_FILE | MAP_SHARED) #endif -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t)-1) -#endif - - #define BUS_BASE 0L #define BUS_BASE_BWX 0L @@ -113,8 +108,6 @@ struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL, static Bool useDevMem = FALSE; static int devMemFd = -1; -#define DEV_MEM "/dev/mem" - static pointer mapVidMem(int, unsigned long, unsigned long, int); static void unmapVidMem(int, pointer, unsigned long); diff --git a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c index 844617980..b58d6a790 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c +++ b/xorg-server/hw/xfree86/os-support/bsd/bsd_init.c @@ -710,7 +710,6 @@ xf86UseMsg() { #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) ErrorF("vtXX use the specified VT number (1-12)\n"); - ErrorF("-sharevts share VTs with another X server\n"); #endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ ErrorF("-keeptty "); ErrorF("don't detach controlling tty (for debugging only)\n"); diff --git a/xorg-server/hw/xfree86/os-support/bsd/i386_video.c b/xorg-server/hw/xfree86/os-support/bsd/i386_video.c index 20dbde86a..35e00fce7 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/i386_video.c +++ b/xorg-server/hw/xfree86/os-support/bsd/i386_video.c @@ -64,10 +64,6 @@ #define MAP_FLAGS (MAP_FILE | MAP_SHARED) #endif -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t)-1) -#endif - #ifdef __OpenBSD__ #define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\ "\tin /etc/sysctl.conf and reboot your machine\n" \ @@ -88,7 +84,6 @@ static int devMemFd = -1; #ifdef HAS_APERTURE_DRV #define DEV_APERTURE "/dev/xf86" #endif -#define DEV_MEM "/dev/mem" static pointer mapVidMem(int, unsigned long, unsigned long, int); static void unmapVidMem(int, pointer, unsigned long); diff --git a/xorg-server/hw/xfree86/os-support/bsd/ppc_video.c b/xorg-server/hw/xfree86/os-support/bsd/ppc_video.c index aeaf18305..e5d832eed 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/ppc_video.c +++ b/xorg-server/hw/xfree86/os-support/bsd/ppc_video.c @@ -36,18 +36,11 @@ #include "bus/Pci.h" -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t)-1) -#endif - - /***************************************************************************/ /* Video Memory Mapping section */ /***************************************************************************/ -#ifndef __OpenBSD__ -#define DEV_MEM "/dev/mem" -#else +#ifdef __OpenBSD__ #define DEV_MEM "/dev/xf86" #endif diff --git a/xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c b/xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c index a2a30c9d7..960c850a8 100644 --- a/xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c +++ b/xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c @@ -34,10 +34,6 @@ #include "xf86_OSlib.h" #include "xf86OSpriv.h" -#ifndef MAP_FAILED -#define MAP_FAILED ((caddr_t)-1) -#endif - /***************************************************************************/ /* Video Memory Mapping section */ /***************************************************************************/ diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_video.c b/xorg-server/hw/xfree86/os-support/linux/lnx_video.c index 697c9fe30..e711784e7 100644 --- a/xorg-server/hw/xfree86/os-support/linux/lnx_video.c +++ b/xorg-server/hw/xfree86/os-support/linux/lnx_video.c @@ -1,881 +1,877 @@ -/*
- * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
- * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Orest Zborowski and David Wexelblat
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Orest Zborowski
- * and David Wexelblat make no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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 <errno.h>
-#include <string.h>
-
-#include <X11/X.h>
-#include "input.h"
-#include "scrnintstr.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86OSpriv.h"
-#ifdef __alpha__
-#include "shared/xf86Axp.h"
-#endif
-
-#ifdef HAS_MTRR_SUPPORT
-#include <asm/mtrr.h>
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
-static Bool ExtendedEnabled = FALSE;
-
-#ifdef __ia64__
-
-#include "compiler.h"
-#include <sys/io.h>
-
-#elif !defined(__powerpc__) && \
- !defined(__mc68000__) && \
- !defined(__sparc__) && \
- !defined(__mips__) && \
- !defined(__nds32__) && \
- !defined(__arm__)
-
-/*
- * Due to conflicts with "compiler.h", don't rely on <sys/io.h> to declare
- * these.
- */
-extern int ioperm(unsigned long __from, unsigned long __num, int __turn_on);
-extern int iopl(int __level);
-
-#endif
-
-#ifdef __alpha__
-# define BUS_BASE bus_base
-#else
-#define BUS_BASE (0)
-#endif /* __alpha__ */
-
-/***************************************************************************/
-/* Video Memory Mapping section */
-/***************************************************************************/
-
-static pointer mapVidMem(int, unsigned long, unsigned long, int);
-static void unmapVidMem(int, pointer, unsigned long);
-#if defined (__alpha__)
-extern void sethae(unsigned long hae);
-extern unsigned long _bus_base __P ((void)) __attribute__ ((const));
-extern unsigned long _bus_base_sparse __P ((void)) __attribute__ ((const));
-
-static pointer mapVidMemSparse(int, unsigned long, unsigned long, int);
-extern axpDevice lnxGetAXP(void);
-static void unmapVidMemSparse(int, pointer, unsigned long);
-static axpDevice axpSystem = -1;
-static Bool needSparse;
-static unsigned long hae_thresh;
-static unsigned long hae_mask;
-static unsigned long bus_base;
-#endif
-
-#ifdef HAS_MTRR_SUPPORT
-
-#define SPLIT_WC_REGIONS 1
-
-static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
-static void undoWC(int, pointer);
-
-/* The file desc for /proc/mtrr. Once opened, left opened, and the mtrr
- driver will clean up when we exit. */
-#define MTRR_FD_UNOPENED (-1) /* We have yet to open /proc/mtrr */
-#define MTRR_FD_PROBLEM (-2) /* We tried to open /proc/mtrr, but had
- a problem. */
-static int mtrr_fd = MTRR_FD_UNOPENED;
-
-/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0,
- and will fail on Linux 2.2 with MTRR support configured out,
- so verbosity should be chosen appropriately. */
-static Bool
-mtrr_open(int verbosity)
-{
- /* Only report absence of /proc/mtrr once. */
- static Bool warned = FALSE;
-
- if (mtrr_fd == MTRR_FD_UNOPENED) {
- mtrr_fd = open("/proc/mtrr", O_WRONLY);
-
- if (mtrr_fd < 0)
- mtrr_fd = MTRR_FD_PROBLEM;
- }
-
- if (mtrr_fd == MTRR_FD_PROBLEM) {
- /* To make sure we only ever warn once, need to check
- verbosity outside xf86MsgVerb */
- if (!warned && verbosity <= xf86GetVerbosity()) {
- xf86MsgVerb(X_WARNING, verbosity,
- "System lacks support for changing MTRRs\n");
- warned = TRUE;
- }
-
- return FALSE;
- }
- else
- return TRUE;
-}
-
-/*
- * We maintain a list of WC regions for each physical mapping so they can
- * be undone when unmapping.
- */
-
-struct mtrr_wc_region {
- struct mtrr_sentry sentry;
- Bool added; /* added WC or removed it */
- struct mtrr_wc_region * next;
-};
-
-
-static struct mtrr_wc_region *
-mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size,
- MessageType from)
-{
- /* Some BIOS writers thought that setting wc over the mmio
- region of a graphics devices was a good idea. Try to fix
- it. */
-
- struct mtrr_gentry gent;
- struct mtrr_wc_region *wcreturn = NULL, *wcr;
- int count, ret=0;
-
- /* Linux 2.0 users should not get a warning without -verbose */
- if (!mtrr_open(2))
- return NULL;
-
- for (gent.regnum = 0;
- ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0;
- gent.regnum++) {
- if (gent.type != MTRR_TYPE_WRCOMB
- || gent.base + gent.size <= base
- || base + size <= gent.base)
- continue;
-
- /* Found an overlapping region. Delete it. */
-
- wcr = malloc(sizeof(*wcr));
- if (!wcr)
- return NULL;
- wcr->sentry.base = gent.base;
- wcr->sentry.size = gent.size;
- wcr->sentry.type = MTRR_TYPE_WRCOMB;
- wcr->added = FALSE;
-
- count = 3;
- while (count-- &&
- (ret = ioctl(mtrr_fd, MTRRIOC_KILL_ENTRY, &(wcr->sentry))) < 0);
-
- if (ret >= 0) {
- xf86DrvMsg(screenNum, from,
- "Removed MMIO write-combining range "
- "(0x%lx,0x%lx)\n",
- (unsigned long) gent.base, (unsigned long) gent.size);
- wcr->next = wcreturn;
- wcreturn = wcr;
- gent.regnum--;
- } else {
- free(wcr);
- xf86DrvMsgVerb(screenNum, X_WARNING, 0,
- "Failed to remove MMIO "
- "write-combining range (0x%lx,0x%lx)\n",
- gent.base, (unsigned long) gent.size);
- }
- }
- return wcreturn;
-}
-
-
-static struct mtrr_wc_region *
-mtrr_remove_offending(int screenNum, unsigned long base, unsigned long size,
- MessageType from)
-{
- struct mtrr_gentry gent;
- struct mtrr_wc_region *wcreturn = NULL, **wcr;
-
- if (!mtrr_open(2))
- return NULL;
-
- wcr = &wcreturn;
- for (gent.regnum = 0;
- ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0; gent.regnum++ ) {
- if (gent.type == MTRR_TYPE_WRCOMB
- && ((gent.base >= base && gent.base + gent.size < base + size) ||
- (gent.base > base && gent.base + gent.size <= base + size))) {
- *wcr = mtrr_cull_wc_region(screenNum, gent.base, gent.size, from);
- if (*wcr) gent.regnum--;
- while(*wcr) {
- wcr = &((*wcr)->next);
- }
- }
- }
- return wcreturn;
-}
-
-
-static struct mtrr_wc_region *
-mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
- MessageType from)
-{
- struct mtrr_wc_region **wcr, *wcreturn, *curwcr;
-
- /*
- * There can be only one....
- */
-
- wcreturn = mtrr_remove_offending(screenNum, base, size, from);
- wcr = &wcreturn;
- while (*wcr) {
- wcr = &((*wcr)->next);
- }
-
- /* Linux 2.0 should not warn, unless the user explicitly asks for
- WC. */
-
- if (!mtrr_open(from == X_CONFIG ? 0 : 2))
- return wcreturn;
-
- *wcr = curwcr = malloc(sizeof(**wcr));
- if (!curwcr)
- return wcreturn;
-
- curwcr->sentry.base = base;
- curwcr->sentry.size = size;
- curwcr->sentry.type = MTRR_TYPE_WRCOMB;
- curwcr->added = TRUE;
- curwcr->next = NULL;
-
-#if SPLIT_WC_REGIONS
- /*
- * Splits up the write-combining region if it is not aligned on a
- * size boundary.
- */
-
- {
- unsigned long lbase, d_size = 1;
- unsigned long n_size = size;
- unsigned long n_base = base;
-
- for (lbase = n_base, d_size = 1; !(lbase & 1);
- lbase = lbase >> 1, d_size <<= 1);
- while (d_size > n_size)
- d_size = d_size >> 1;
- DebugF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1);
- n_base += d_size;
- n_size -= d_size;
- if (n_size) {
- xf86DrvMsgVerb(screenNum,X_INFO,3,"Splitting WC range: "
- "base: 0x%lx, size: 0x%lx\n",base,size);
- curwcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from);
- }
- curwcr->sentry.size = d_size;
- }
-
- /*****************************************************************/
-#endif /* SPLIT_WC_REGIONS */
-
- if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &curwcr->sentry) >= 0) {
- /* Avoid printing on every VT switch */
- if (xf86ServerIsInitialising()) {
- xf86DrvMsg(screenNum, from,
- "Write-combining range (0x%lx,0x%lx)\n",
- base, size);
- }
- return wcreturn;
- }
- else {
- *wcr = curwcr->next;
- free(curwcr);
-
- /* Don't complain about the VGA region: MTRR fixed
- regions aren't currently supported, but might be in
- the future. */
- if ((unsigned long)base >= 0x100000) {
- xf86DrvMsgVerb(screenNum, X_WARNING, 0,
- "Failed to set up write-combining range "
- "(0x%lx,0x%lx)\n", base, size);
- }
- return wcreturn;
- }
-}
-
-static void
-mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr)
-{
- struct mtrr_wc_region *p, *prev;
-
- if (mtrr_fd >= 0) {
- p = wcr;
- while (p) {
- if (p->added)
- ioctl(mtrr_fd, MTRRIOC_DEL_ENTRY, &p->sentry);
- prev = p;
- p = p->next;
- free(prev);
- }
- }
-}
-
-static pointer
-setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
- MessageType from)
-{
- if (enable)
- return mtrr_add_wc_region(screenNum, base, size, from);
- else
- return mtrr_cull_wc_region(screenNum, base, size, from);
-}
-
-static void
-undoWC(int screenNum, pointer regioninfo)
-{
- mtrr_undo_wc_region(screenNum, regioninfo);
-}
-
-#endif /* HAS_MTRR_SUPPORT */
-
-void
-xf86OSInitVidMem(VidMemInfoPtr pVidMem)
-{
- pVidMem->linearSupported = TRUE;
-#ifdef __alpha__
- if (axpSystem == -1) {
- axpSystem = lnxGetAXP();
- if ((needSparse = (_bus_base_sparse() > 0))) {
- hae_thresh = xf86AXPParams[axpSystem].hae_thresh;
- hae_mask = xf86AXPParams[axpSystem].hae_mask;
- }
- bus_base = _bus_base();
- }
- if (needSparse) {
- xf86Msg(X_INFO,"Machine needs sparse mapping\n");
- pVidMem->mapMem = mapVidMemSparse;
- pVidMem->unmapMem = unmapVidMemSparse;
- } else {
- xf86Msg(X_INFO,"Machine type has 8/16 bit access\n");
- pVidMem->mapMem = mapVidMem;
- pVidMem->unmapMem = unmapVidMem;
- }
-#else
- pVidMem->mapMem = mapVidMem;
- pVidMem->unmapMem = unmapVidMem;
-#endif /* __alpha__ */
-
-
-#ifdef HAS_MTRR_SUPPORT
- pVidMem->setWC = setWC;
- pVidMem->undoWC = undoWC;
-#endif
- pVidMem->initialised = TRUE;
-}
-
-#ifdef __sparc__
-/* Basically, you simply cannot do this on Sparc. You have to do something portable
- * like use /dev/fb* or mmap() on /proc/bus/pci/X/Y nodes. -DaveM
- */
-static pointer mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
-{
- return NULL;
-}
-#else
-static pointer
-mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
-{
- pointer base;
- int fd;
- int mapflags = MAP_SHARED;
- int prot;
- memType realBase, alignOff;
-
- realBase = Base & ~(getpagesize() - 1);
- alignOff = Base - realBase;
- DebugF("base: %lx, realBase: %lx, alignOff: %lx \n",
- Base,realBase,alignOff);
-
-#if defined(__ia64__) || defined(__arm__) || defined(__s390__)
-#ifndef MAP_WRITECOMBINED
-#define MAP_WRITECOMBINED 0x00010000
-#endif
-#ifndef MAP_NONCACHED
-#define MAP_NONCACHED 0x00020000
-#endif
- if(flags & VIDMEM_FRAMEBUFFER)
- mapflags |= MAP_WRITECOMBINED;
- else
- mapflags |= MAP_NONCACHED;
-#endif
-
-#if 0
- /* this will disappear when people upgrade their kernels */
- fd = open(DEV_MEM,
- ((flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR) | O_SYNC);
-#else
- fd = open(DEV_MEM, (flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR);
-#endif
- if (fd < 0)
- {
- FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
- strerror(errno));
- }
-
- if (flags & VIDMEM_READONLY)
- prot = PROT_READ;
- else
- prot = PROT_READ | PROT_WRITE;
-
- /* This requires linux-0.99.pl10 or above */
- base = mmap((caddr_t)0, Size + alignOff, prot, mapflags, fd,
- (off_t)realBase + BUS_BASE);
- close(fd);
- if (base == MAP_FAILED) {
- FatalError("xf86MapVidMem: Could not mmap framebuffer"
- " (0x%08lx,0x%lx) (%s)\n", Base, Size,
- strerror(errno));
- }
- DebugF("base: %lx aligned base: %lx\n",base, (char *)base + alignOff);
- return (char *)base + alignOff;
-}
-#endif /* !(__sparc__) */
-
-static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
-{
- memType alignOff = (memType)Base
- - ((memType)Base & ~(getpagesize() - 1));
-
- DebugF("alignment offset: %lx\n",alignOff);
- munmap((caddr_t)((memType)Base - alignOff), (Size + alignOff));
-}
-
-
-/***************************************************************************/
-/* I/O Permissions section */
-/***************************************************************************/
-
-#if defined(__powerpc__)
-volatile unsigned char *ioBase = NULL;
-
-#ifndef __NR_pciconfig_iobase
-#define __NR_pciconfig_iobase 200
-#endif
-
-#endif
-
-Bool
-xf86EnableIO(void)
-{
-#if defined(__powerpc__)
- int fd;
- unsigned int ioBase_phys;
-#endif
-
- if (ExtendedEnabled)
- return TRUE;
-
-#if defined(__powerpc__)
- ioBase_phys = syscall(__NR_pciconfig_iobase, 2, 0, 0);
-
- fd = open("/dev/mem", O_RDWR);
- if (ioBase == NULL) {
- ioBase = (volatile unsigned char *)mmap(0, 0x20000,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd,
- ioBase_phys);
-/* Should this be fatal or just a warning? */
-#if 0
- if (ioBase == MAP_FAILED) {
- xf86Msg(X_WARNING,
- "xf86EnableIOPorts: Failed to map iobase (%s)\n",
- strerror(errno));
- return FALSE;
- }
-#endif
- }
- close(fd);
-#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__arm__) && !defined(__m32r__) && !defined(__nds32__)
- if (ioperm(0, 1024, 1) || iopl(3)) {
- if (errno == ENODEV)
- ErrorF("xf86EnableIOPorts: no I/O ports found\n");
- else
- FatalError("xf86EnableIOPorts: failed to set IOPL"
- " for I/O (%s)\n", strerror(errno));
- return FALSE;
- }
-# if !defined(__alpha__)
- /* XXX: this is actually not trapping anything because of iopl(3)
- * above */
- ioperm(0x40,4,0); /* trap access to the timer chip */
- ioperm(0x60,4,0); /* trap access to the keyboard controller */
-# endif
-#endif
- ExtendedEnabled = TRUE;
-
- return TRUE;
-}
-
-void
-xf86DisableIO(void)
-{
- if (!ExtendedEnabled)
- return;
-#if defined(__powerpc__)
- munmap(ioBase, 0x20000);
- ioBase = NULL;
-#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__arm__) && !defined(__s390__) && !defined(__m32r__) && !defined(__nds32__)
- iopl(0);
- ioperm(0, 1024, 0);
-#endif
- ExtendedEnabled = FALSE;
-
- return;
-}
-
-#if defined (__alpha__)
-
-#define vuip volatile unsigned int *
-
-extern int readDense8(pointer Base, register unsigned long Offset);
-extern int readDense16(pointer Base, register unsigned long Offset);
-extern int readDense32(pointer Base, register unsigned long Offset);
-extern void
-writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
-extern void
-writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
-extern void
-writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
-extern void
-writeDense8(int Value, pointer Base, register unsigned long Offset);
-extern void
-writeDense16(int Value, pointer Base, register unsigned long Offset);
-extern void
-writeDense32(int Value, pointer Base, register unsigned long Offset);
-
-static int readSparse8(pointer Base, register unsigned long Offset);
-static int readSparse16(pointer Base, register unsigned long Offset);
-static int readSparse32(pointer Base, register unsigned long Offset);
-static void
-writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
-static void
-writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
-static void
-writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
-static void
-writeSparse8(int Value, pointer Base, register unsigned long Offset);
-static void
-writeSparse16(int Value, pointer Base, register unsigned long Offset);
-static void
-writeSparse32(int Value, pointer Base, register unsigned long Offset);
-
-#define DENSE_BASE 0x2ff00000000UL
-#define SPARSE_BASE 0x30000000000UL
-
-static unsigned long msb_set = 0;
-
-static pointer
-mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
-{
- int fd, prot;
- unsigned long ret, rets = 0;
-
- static Bool was_here = FALSE;
-
- if (!was_here) {
- was_here = TRUE;
-
- xf86WriteMmio8 = writeSparse8;
- xf86WriteMmio16 = writeSparse16;
- xf86WriteMmio32 = writeSparse32;
- xf86WriteMmioNB8 = writeSparseNB8;
- xf86WriteMmioNB16 = writeSparseNB16;
- xf86WriteMmioNB32 = writeSparseNB32;
- xf86ReadMmio8 = readSparse8;
- xf86ReadMmio16 = readSparse16;
- xf86ReadMmio32 = readSparse32;
- }
-
- fd = open(DEV_MEM, (flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR);
- if (fd < 0) {
- FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n",
- strerror(errno));
- }
-
-#if 0
- xf86Msg(X_INFO,"mapVidMemSparse: try Base 0x%lx size 0x%lx flags 0x%x\n",
- Base, Size, flags);
-#endif
-
- if (flags & VIDMEM_READONLY)
- prot = PROT_READ;
- else
- prot = PROT_READ | PROT_WRITE;
-
- /* This requirers linux-0.99.pl10 or above */
-
- /*
- * Always do DENSE mmap, since read32/write32 currently require it.
- */
- ret = (unsigned long)mmap((caddr_t)(DENSE_BASE + Base), Size,
- prot, MAP_SHARED, fd,
- (off_t) (bus_base + Base));
-
- /*
- * Do SPARSE mmap only when MMIO and not MMIO_32BIT, or FRAMEBUFFER
- * and SPARSE (which should require the use of read/write macros).
- *
- * By not SPARSE mmapping an 8MB framebuffer, we can save approx. 256K
- * bytes worth of pagetable (32 pages).
- */
- if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) ||
- ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE)))
- {
- rets = (unsigned long)mmap((caddr_t)(SPARSE_BASE + (Base << 5)),
- Size << 5, prot, MAP_SHARED, fd,
- (off_t) _bus_base_sparse() + (Base << 5));
- }
-
- close(fd);
-
- if (ret == (unsigned long)MAP_FAILED) {
- FatalError("xf86MapVidMemSparse: Could not (dense) mmap fb (%s)\n",
- strerror(errno));
- }
-
- if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) ||
- ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE)))
- {
- if (rets == (unsigned long)MAP_FAILED ||
- rets != (SPARSE_BASE + (Base << 5)))
- {
- FatalError("mapVidMemSparse: Could not (sparse) mmap fb (%s)\n",
- strerror(errno));
- }
- }
-
-#if 1
- if (rets)
- xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx"
- " to DENSE at 0x%lx and SPARSE at 0x%lx\n",
- Base, Size, ret, rets);
- else
- xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx"
- " to DENSE only at 0x%lx\n",
- Base, Size, ret);
-
-#endif
- return (pointer) ret;
-}
-
-static void
-unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
-{
- unsigned long Offset = (unsigned long)Base - DENSE_BASE;
-#if 1
- xf86Msg(X_INFO,"unmapVidMemSparse: unmapping Base 0x%lx Size 0x%lx\n",
- Base, Size);
-#endif
- /* Unmap DENSE always. */
- munmap((caddr_t)Base, Size);
-
- /* Unmap SPARSE always, and ignore error in case we did not map it. */
- munmap((caddr_t)(SPARSE_BASE + (Offset << 5)), Size << 5);
-}
-
-static int
-readSparse8(pointer Base, register unsigned long Offset)
-{
- register unsigned long result, shift;
- register unsigned long msb;
-
- mem_barrier();
- Offset += (unsigned long)Base - DENSE_BASE;
- shift = (Offset & 0x3) << 3;
- if (Offset >= (hae_thresh)) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
-
- mem_barrier();
- result = *(vuip) (SPARSE_BASE + (Offset << 5));
- result >>= shift;
- return 0xffUL & result;
-}
-
-static int
-readSparse16(pointer Base, register unsigned long Offset)
-{
- register unsigned long result, shift;
- register unsigned long msb;
-
- mem_barrier();
- Offset += (unsigned long)Base - DENSE_BASE;
- shift = (Offset & 0x2) << 3;
- if (Offset >= hae_thresh) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
-
- mem_barrier();
- result = *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2)));
- result >>= shift;
- return 0xffffUL & result;
-}
-
-static int
-readSparse32(pointer Base, register unsigned long Offset)
-{
- /* NOTE: this is really using DENSE. */
- mem_barrier();
- return *(vuip)((unsigned long)Base+(Offset));
-}
-
-static void
-writeSparse8(int Value, pointer Base, register unsigned long Offset)
-{
- register unsigned long msb;
- register unsigned int b = Value & 0xffU;
-
- write_mem_barrier();
- Offset += (unsigned long)Base - DENSE_BASE;
- if (Offset >= hae_thresh) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
-
- write_mem_barrier();
- *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101;
-}
-
-static void
-writeSparse16(int Value, pointer Base, register unsigned long Offset)
-{
- register unsigned long msb;
- register unsigned int w = Value & 0xffffU;
-
- write_mem_barrier();
- Offset += (unsigned long)Base - DENSE_BASE;
- if (Offset >= hae_thresh) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
-
- write_mem_barrier();
- *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2))) = w * 0x00010001;
-}
-
-static void
-writeSparse32(int Value, pointer Base, register unsigned long Offset)
-{
- /* NOTE: this is really using DENSE. */
- write_mem_barrier();
- *(vuip)((unsigned long)Base + (Offset)) = Value;
- return;
-}
-
-static void
-writeSparseNB8(int Value, pointer Base, register unsigned long Offset)
-{
- register unsigned long msb;
- register unsigned int b = Value & 0xffU;
-
- Offset += (unsigned long)Base - DENSE_BASE;
- if (Offset >= hae_thresh) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
- *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101;
-}
-
-static void
-writeSparseNB16(int Value, pointer Base, register unsigned long Offset)
-{
- register unsigned long msb;
- register unsigned int w = Value & 0xffffU;
-
- Offset += (unsigned long)Base - DENSE_BASE;
- if (Offset >= hae_thresh) {
- msb = Offset & hae_mask;
- Offset -= msb;
- if (msb_set != msb) {
- sethae(msb);
- msb_set = msb;
- }
- }
- *(vuip)(SPARSE_BASE+(Offset<<5)+(1<<(5-2))) = w * 0x00010001;
-}
-
-static void
-writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
-{
- /* NOTE: this is really using DENSE. */
- *(vuip)((unsigned long)Base + (Offset)) = Value;
- return;
-}
-
-void (*xf86WriteMmio8)(int Value, pointer Base, unsigned long Offset)
- = writeDense8;
-void (*xf86WriteMmio16)(int Value, pointer Base, unsigned long Offset)
- = writeDense16;
-void (*xf86WriteMmio32)(int Value, pointer Base, unsigned long Offset)
- = writeDense32;
-void (*xf86WriteMmioNB8)(int Value, pointer Base, unsigned long Offset)
- = writeDenseNB8;
-void (*xf86WriteMmioNB16)(int Value, pointer Base, unsigned long Offset)
- = writeDenseNB16;
-void (*xf86WriteMmioNB32)(int Value, pointer Base, unsigned long Offset)
- = writeDenseNB32;
-int (*xf86ReadMmio8)(pointer Base, unsigned long Offset)
- = readDense8;
-int (*xf86ReadMmio16)(pointer Base, unsigned long Offset)
- = readDense16;
-int (*xf86ReadMmio32)(pointer Base, unsigned long Offset)
- = readDense32;
-
-#endif /* __alpha__ */
+/* + * Copyright 1992 by Orest Zborowski <obz@Kodak.com> + * Copyright 1993 by David Wexelblat <dwex@goblin.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 names of Orest Zborowski and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Orest Zborowski + * and David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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 <errno.h> +#include <string.h> + +#include <X11/X.h> +#include "input.h" +#include "scrnintstr.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" +#ifdef __alpha__ +#include "shared/xf86Axp.h" +#endif + +#ifdef HAS_MTRR_SUPPORT +#include <asm/mtrr.h> +#endif + +static Bool ExtendedEnabled = FALSE; + +#ifdef __ia64__ + +#include "compiler.h" +#include <sys/io.h> + +#elif !defined(__powerpc__) && \ + !defined(__mc68000__) && \ + !defined(__sparc__) && \ + !defined(__mips__) && \ + !defined(__nds32__) && \ + !defined(__arm__) + +/* + * Due to conflicts with "compiler.h", don't rely on <sys/io.h> to declare + * these. + */ +extern int ioperm(unsigned long __from, unsigned long __num, int __turn_on); +extern int iopl(int __level); + +#endif + +#ifdef __alpha__ +# define BUS_BASE bus_base +#else +#define BUS_BASE (0) +#endif /* __alpha__ */ + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +static pointer mapVidMem(int, unsigned long, unsigned long, int); +static void unmapVidMem(int, pointer, unsigned long); +#if defined (__alpha__) +extern void sethae(unsigned long hae); +extern unsigned long _bus_base __P ((void)) __attribute__ ((const)); +extern unsigned long _bus_base_sparse __P ((void)) __attribute__ ((const)); + +static pointer mapVidMemSparse(int, unsigned long, unsigned long, int); +extern axpDevice lnxGetAXP(void); +static void unmapVidMemSparse(int, pointer, unsigned long); +static axpDevice axpSystem = -1; +static Bool needSparse; +static unsigned long hae_thresh; +static unsigned long hae_mask; +static unsigned long bus_base; +#endif + +#ifdef HAS_MTRR_SUPPORT + +#define SPLIT_WC_REGIONS 1 + +static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType); +static void undoWC(int, pointer); + +/* The file desc for /proc/mtrr. Once opened, left opened, and the mtrr + driver will clean up when we exit. */ +#define MTRR_FD_UNOPENED (-1) /* We have yet to open /proc/mtrr */ +#define MTRR_FD_PROBLEM (-2) /* We tried to open /proc/mtrr, but had + a problem. */ +static int mtrr_fd = MTRR_FD_UNOPENED; + +/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0, + and will fail on Linux 2.2 with MTRR support configured out, + so verbosity should be chosen appropriately. */ +static Bool +mtrr_open(int verbosity) +{ + /* Only report absence of /proc/mtrr once. */ + static Bool warned = FALSE; + + if (mtrr_fd == MTRR_FD_UNOPENED) { + mtrr_fd = open("/proc/mtrr", O_WRONLY); + + if (mtrr_fd < 0) + mtrr_fd = MTRR_FD_PROBLEM; + } + + if (mtrr_fd == MTRR_FD_PROBLEM) { + /* To make sure we only ever warn once, need to check + verbosity outside xf86MsgVerb */ + if (!warned && verbosity <= xf86GetVerbosity()) { + xf86MsgVerb(X_WARNING, verbosity, + "System lacks support for changing MTRRs\n"); + warned = TRUE; + } + + return FALSE; + } + else + return TRUE; +} + +/* + * We maintain a list of WC regions for each physical mapping so they can + * be undone when unmapping. + */ + +struct mtrr_wc_region { + struct mtrr_sentry sentry; + Bool added; /* added WC or removed it */ + struct mtrr_wc_region * next; +}; + + +static struct mtrr_wc_region * +mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size, + MessageType from) +{ + /* Some BIOS writers thought that setting wc over the mmio + region of a graphics devices was a good idea. Try to fix + it. */ + + struct mtrr_gentry gent; + struct mtrr_wc_region *wcreturn = NULL, *wcr; + int count, ret=0; + + /* Linux 2.0 users should not get a warning without -verbose */ + if (!mtrr_open(2)) + return NULL; + + for (gent.regnum = 0; + ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0; + gent.regnum++) { + if (gent.type != MTRR_TYPE_WRCOMB + || gent.base + gent.size <= base + || base + size <= gent.base) + continue; + + /* Found an overlapping region. Delete it. */ + + wcr = malloc(sizeof(*wcr)); + if (!wcr) + return NULL; + wcr->sentry.base = gent.base; + wcr->sentry.size = gent.size; + wcr->sentry.type = MTRR_TYPE_WRCOMB; + wcr->added = FALSE; + + count = 3; + while (count-- && + (ret = ioctl(mtrr_fd, MTRRIOC_KILL_ENTRY, &(wcr->sentry))) < 0); + + if (ret >= 0) { + xf86DrvMsg(screenNum, from, + "Removed MMIO write-combining range " + "(0x%lx,0x%lx)\n", + (unsigned long) gent.base, (unsigned long) gent.size); + wcr->next = wcreturn; + wcreturn = wcr; + gent.regnum--; + } else { + free(wcr); + xf86DrvMsgVerb(screenNum, X_WARNING, 0, + "Failed to remove MMIO " + "write-combining range (0x%lx,0x%lx)\n", + gent.base, (unsigned long) gent.size); + } + } + return wcreturn; +} + + +static struct mtrr_wc_region * +mtrr_remove_offending(int screenNum, unsigned long base, unsigned long size, + MessageType from) +{ + struct mtrr_gentry gent; + struct mtrr_wc_region *wcreturn = NULL, **wcr; + + if (!mtrr_open(2)) + return NULL; + + wcr = &wcreturn; + for (gent.regnum = 0; + ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0; gent.regnum++ ) { + if (gent.type == MTRR_TYPE_WRCOMB + && ((gent.base >= base && gent.base + gent.size < base + size) || + (gent.base > base && gent.base + gent.size <= base + size))) { + *wcr = mtrr_cull_wc_region(screenNum, gent.base, gent.size, from); + if (*wcr) gent.regnum--; + while(*wcr) { + wcr = &((*wcr)->next); + } + } + } + return wcreturn; +} + + +static struct mtrr_wc_region * +mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size, + MessageType from) +{ + struct mtrr_wc_region **wcr, *wcreturn, *curwcr; + + /* + * There can be only one.... + */ + + wcreturn = mtrr_remove_offending(screenNum, base, size, from); + wcr = &wcreturn; + while (*wcr) { + wcr = &((*wcr)->next); + } + + /* Linux 2.0 should not warn, unless the user explicitly asks for + WC. */ + + if (!mtrr_open(from == X_CONFIG ? 0 : 2)) + return wcreturn; + + *wcr = curwcr = malloc(sizeof(**wcr)); + if (!curwcr) + return wcreturn; + + curwcr->sentry.base = base; + curwcr->sentry.size = size; + curwcr->sentry.type = MTRR_TYPE_WRCOMB; + curwcr->added = TRUE; + curwcr->next = NULL; + +#if SPLIT_WC_REGIONS + /* + * Splits up the write-combining region if it is not aligned on a + * size boundary. + */ + + { + unsigned long lbase, d_size = 1; + unsigned long n_size = size; + unsigned long n_base = base; + + for (lbase = n_base, d_size = 1; !(lbase & 1); + lbase = lbase >> 1, d_size <<= 1); + while (d_size > n_size) + d_size = d_size >> 1; + DebugF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1); + n_base += d_size; + n_size -= d_size; + if (n_size) { + xf86DrvMsgVerb(screenNum,X_INFO,3,"Splitting WC range: " + "base: 0x%lx, size: 0x%lx\n",base,size); + curwcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from); + } + curwcr->sentry.size = d_size; + } + + /*****************************************************************/ +#endif /* SPLIT_WC_REGIONS */ + + if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &curwcr->sentry) >= 0) { + /* Avoid printing on every VT switch */ + if (xf86ServerIsInitialising()) { + xf86DrvMsg(screenNum, from, + "Write-combining range (0x%lx,0x%lx)\n", + base, size); + } + return wcreturn; + } + else { + *wcr = curwcr->next; + free(curwcr); + + /* Don't complain about the VGA region: MTRR fixed + regions aren't currently supported, but might be in + the future. */ + if ((unsigned long)base >= 0x100000) { + xf86DrvMsgVerb(screenNum, X_WARNING, 0, + "Failed to set up write-combining range " + "(0x%lx,0x%lx)\n", base, size); + } + return wcreturn; + } +} + +static void +mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr) +{ + struct mtrr_wc_region *p, *prev; + + if (mtrr_fd >= 0) { + p = wcr; + while (p) { + if (p->added) + ioctl(mtrr_fd, MTRRIOC_DEL_ENTRY, &p->sentry); + prev = p; + p = p->next; + free(prev); + } + } +} + +static pointer +setWC(int screenNum, unsigned long base, unsigned long size, Bool enable, + MessageType from) +{ + if (enable) + return mtrr_add_wc_region(screenNum, base, size, from); + else + return mtrr_cull_wc_region(screenNum, base, size, from); +} + +static void +undoWC(int screenNum, pointer regioninfo) +{ + mtrr_undo_wc_region(screenNum, regioninfo); +} + +#endif /* HAS_MTRR_SUPPORT */ + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + pVidMem->linearSupported = TRUE; +#ifdef __alpha__ + if (axpSystem == -1) { + axpSystem = lnxGetAXP(); + if ((needSparse = (_bus_base_sparse() > 0))) { + hae_thresh = xf86AXPParams[axpSystem].hae_thresh; + hae_mask = xf86AXPParams[axpSystem].hae_mask; + } + bus_base = _bus_base(); + } + if (needSparse) { + xf86Msg(X_INFO,"Machine needs sparse mapping\n"); + pVidMem->mapMem = mapVidMemSparse; + pVidMem->unmapMem = unmapVidMemSparse; + } else { + xf86Msg(X_INFO,"Machine type has 8/16 bit access\n"); + pVidMem->mapMem = mapVidMem; + pVidMem->unmapMem = unmapVidMem; + } +#else + pVidMem->mapMem = mapVidMem; + pVidMem->unmapMem = unmapVidMem; +#endif /* __alpha__ */ + + +#ifdef HAS_MTRR_SUPPORT + pVidMem->setWC = setWC; + pVidMem->undoWC = undoWC; +#endif + pVidMem->initialised = TRUE; +} + +#ifdef __sparc__ +/* Basically, you simply cannot do this on Sparc. You have to do something portable + * like use /dev/fb* or mmap() on /proc/bus/pci/X/Y nodes. -DaveM + */ +static pointer mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + return NULL; +} +#else +static pointer +mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + pointer base; + int fd; + int mapflags = MAP_SHARED; + int prot; + memType realBase, alignOff; + + realBase = Base & ~(getpagesize() - 1); + alignOff = Base - realBase; + DebugF("base: %lx, realBase: %lx, alignOff: %lx \n", + Base,realBase,alignOff); + +#if defined(__ia64__) || defined(__arm__) || defined(__s390__) +#ifndef MAP_WRITECOMBINED +#define MAP_WRITECOMBINED 0x00010000 +#endif +#ifndef MAP_NONCACHED +#define MAP_NONCACHED 0x00020000 +#endif + if(flags & VIDMEM_FRAMEBUFFER) + mapflags |= MAP_WRITECOMBINED; + else + mapflags |= MAP_NONCACHED; +#endif + +#if 0 + /* this will disappear when people upgrade their kernels */ + fd = open(DEV_MEM, + ((flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR) | O_SYNC); +#else + fd = open(DEV_MEM, (flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR); +#endif + if (fd < 0) + { + FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n", + strerror(errno)); + } + + if (flags & VIDMEM_READONLY) + prot = PROT_READ; + else + prot = PROT_READ | PROT_WRITE; + + /* This requires linux-0.99.pl10 or above */ + base = mmap((caddr_t)0, Size + alignOff, prot, mapflags, fd, + (off_t)realBase + BUS_BASE); + close(fd); + if (base == MAP_FAILED) { + FatalError("xf86MapVidMem: Could not mmap framebuffer" + " (0x%08lx,0x%lx) (%s)\n", Base, Size, + strerror(errno)); + } + DebugF("base: %lx aligned base: %lx\n",base, (char *)base + alignOff); + return (char *)base + alignOff; +} +#endif /* !(__sparc__) */ + +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + memType alignOff = (memType)Base + - ((memType)Base & ~(getpagesize() - 1)); + + DebugF("alignment offset: %lx\n",alignOff); + munmap((caddr_t)((memType)Base - alignOff), (Size + alignOff)); +} + + +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ + +#if defined(__powerpc__) +volatile unsigned char *ioBase = NULL; + +#ifndef __NR_pciconfig_iobase +#define __NR_pciconfig_iobase 200 +#endif + +#endif + +Bool +xf86EnableIO(void) +{ +#if defined(__powerpc__) + int fd; + unsigned int ioBase_phys; +#endif + + if (ExtendedEnabled) + return TRUE; + +#if defined(__powerpc__) + ioBase_phys = syscall(__NR_pciconfig_iobase, 2, 0, 0); + + fd = open("/dev/mem", O_RDWR); + if (ioBase == NULL) { + ioBase = (volatile unsigned char *)mmap(0, 0x20000, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, + ioBase_phys); +/* Should this be fatal or just a warning? */ +#if 0 + if (ioBase == MAP_FAILED) { + xf86Msg(X_WARNING, + "xf86EnableIOPorts: Failed to map iobase (%s)\n", + strerror(errno)); + return FALSE; + } +#endif + } + close(fd); +#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__arm__) && !defined(__m32r__) && !defined(__nds32__) + if (ioperm(0, 1024, 1) || iopl(3)) { + if (errno == ENODEV) + ErrorF("xf86EnableIOPorts: no I/O ports found\n"); + else + FatalError("xf86EnableIOPorts: failed to set IOPL" + " for I/O (%s)\n", strerror(errno)); + return FALSE; + } +# if !defined(__alpha__) + /* XXX: this is actually not trapping anything because of iopl(3) + * above */ + ioperm(0x40,4,0); /* trap access to the timer chip */ + ioperm(0x60,4,0); /* trap access to the keyboard controller */ +# endif +#endif + ExtendedEnabled = TRUE; + + return TRUE; +} + +void +xf86DisableIO(void) +{ + if (!ExtendedEnabled) + return; +#if defined(__powerpc__) + munmap(ioBase, 0x20000); + ioBase = NULL; +#elif !defined(__mc68000__) && !defined(__sparc__) && !defined(__mips__) && !defined(__sh__) && !defined(__hppa__) && !defined(__arm__) && !defined(__s390__) && !defined(__m32r__) && !defined(__nds32__) + iopl(0); + ioperm(0, 1024, 0); +#endif + ExtendedEnabled = FALSE; + + return; +} + +#if defined (__alpha__) + +#define vuip volatile unsigned int * + +extern int readDense8(pointer Base, register unsigned long Offset); +extern int readDense16(pointer Base, register unsigned long Offset); +extern int readDense32(pointer Base, register unsigned long Offset); +extern void +writeDenseNB8(int Value, pointer Base, register unsigned long Offset); +extern void +writeDenseNB16(int Value, pointer Base, register unsigned long Offset); +extern void +writeDenseNB32(int Value, pointer Base, register unsigned long Offset); +extern void +writeDense8(int Value, pointer Base, register unsigned long Offset); +extern void +writeDense16(int Value, pointer Base, register unsigned long Offset); +extern void +writeDense32(int Value, pointer Base, register unsigned long Offset); + +static int readSparse8(pointer Base, register unsigned long Offset); +static int readSparse16(pointer Base, register unsigned long Offset); +static int readSparse32(pointer Base, register unsigned long Offset); +static void +writeSparseNB8(int Value, pointer Base, register unsigned long Offset); +static void +writeSparseNB16(int Value, pointer Base, register unsigned long Offset); +static void +writeSparseNB32(int Value, pointer Base, register unsigned long Offset); +static void +writeSparse8(int Value, pointer Base, register unsigned long Offset); +static void +writeSparse16(int Value, pointer Base, register unsigned long Offset); +static void +writeSparse32(int Value, pointer Base, register unsigned long Offset); + +#define DENSE_BASE 0x2ff00000000UL +#define SPARSE_BASE 0x30000000000UL + +static unsigned long msb_set = 0; + +static pointer +mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + int fd, prot; + unsigned long ret, rets = 0; + + static Bool was_here = FALSE; + + if (!was_here) { + was_here = TRUE; + + xf86WriteMmio8 = writeSparse8; + xf86WriteMmio16 = writeSparse16; + xf86WriteMmio32 = writeSparse32; + xf86WriteMmioNB8 = writeSparseNB8; + xf86WriteMmioNB16 = writeSparseNB16; + xf86WriteMmioNB32 = writeSparseNB32; + xf86ReadMmio8 = readSparse8; + xf86ReadMmio16 = readSparse16; + xf86ReadMmio32 = readSparse32; + } + + fd = open(DEV_MEM, (flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR); + if (fd < 0) { + FatalError("xf86MapVidMem: failed to open " DEV_MEM " (%s)\n", + strerror(errno)); + } + +#if 0 + xf86Msg(X_INFO,"mapVidMemSparse: try Base 0x%lx size 0x%lx flags 0x%x\n", + Base, Size, flags); +#endif + + if (flags & VIDMEM_READONLY) + prot = PROT_READ; + else + prot = PROT_READ | PROT_WRITE; + + /* This requirers linux-0.99.pl10 or above */ + + /* + * Always do DENSE mmap, since read32/write32 currently require it. + */ + ret = (unsigned long)mmap((caddr_t)(DENSE_BASE + Base), Size, + prot, MAP_SHARED, fd, + (off_t) (bus_base + Base)); + + /* + * Do SPARSE mmap only when MMIO and not MMIO_32BIT, or FRAMEBUFFER + * and SPARSE (which should require the use of read/write macros). + * + * By not SPARSE mmapping an 8MB framebuffer, we can save approx. 256K + * bytes worth of pagetable (32 pages). + */ + if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) || + ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE))) + { + rets = (unsigned long)mmap((caddr_t)(SPARSE_BASE + (Base << 5)), + Size << 5, prot, MAP_SHARED, fd, + (off_t) _bus_base_sparse() + (Base << 5)); + } + + close(fd); + + if (ret == (unsigned long)MAP_FAILED) { + FatalError("xf86MapVidMemSparse: Could not (dense) mmap fb (%s)\n", + strerror(errno)); + } + + if (((flags & VIDMEM_MMIO) && !(flags & VIDMEM_MMIO_32BIT)) || + ((flags & VIDMEM_FRAMEBUFFER) && (flags & VIDMEM_SPARSE))) + { + if (rets == (unsigned long)MAP_FAILED || + rets != (SPARSE_BASE + (Base << 5))) + { + FatalError("mapVidMemSparse: Could not (sparse) mmap fb (%s)\n", + strerror(errno)); + } + } + +#if 1 + if (rets) + xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx" + " to DENSE at 0x%lx and SPARSE at 0x%lx\n", + Base, Size, ret, rets); + else + xf86Msg(X_INFO,"mapVidMemSparse: mapped Base 0x%lx size 0x%lx" + " to DENSE only at 0x%lx\n", + Base, Size, ret); + +#endif + return (pointer) ret; +} + +static void +unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size) +{ + unsigned long Offset = (unsigned long)Base - DENSE_BASE; +#if 1 + xf86Msg(X_INFO,"unmapVidMemSparse: unmapping Base 0x%lx Size 0x%lx\n", + Base, Size); +#endif + /* Unmap DENSE always. */ + munmap((caddr_t)Base, Size); + + /* Unmap SPARSE always, and ignore error in case we did not map it. */ + munmap((caddr_t)(SPARSE_BASE + (Offset << 5)), Size << 5); +} + +static int +readSparse8(pointer Base, register unsigned long Offset) +{ + register unsigned long result, shift; + register unsigned long msb; + + mem_barrier(); + Offset += (unsigned long)Base - DENSE_BASE; + shift = (Offset & 0x3) << 3; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + + mem_barrier(); + result = *(vuip) (SPARSE_BASE + (Offset << 5)); + result >>= shift; + return 0xffUL & result; +} + +static int +readSparse16(pointer Base, register unsigned long Offset) +{ + register unsigned long result, shift; + register unsigned long msb; + + mem_barrier(); + Offset += (unsigned long)Base - DENSE_BASE; + shift = (Offset & 0x2) << 3; + if (Offset >= hae_thresh) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + + mem_barrier(); + result = *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2))); + result >>= shift; + return 0xffffUL & result; +} + +static int +readSparse32(pointer Base, register unsigned long Offset) +{ + /* NOTE: this is really using DENSE. */ + mem_barrier(); + return *(vuip)((unsigned long)Base+(Offset)); +} + +static void +writeSparse8(int Value, pointer Base, register unsigned long Offset) +{ + register unsigned long msb; + register unsigned int b = Value & 0xffU; + + write_mem_barrier(); + Offset += (unsigned long)Base - DENSE_BASE; + if (Offset >= hae_thresh) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + + write_mem_barrier(); + *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101; +} + +static void +writeSparse16(int Value, pointer Base, register unsigned long Offset) +{ + register unsigned long msb; + register unsigned int w = Value & 0xffffU; + + write_mem_barrier(); + Offset += (unsigned long)Base - DENSE_BASE; + if (Offset >= hae_thresh) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + + write_mem_barrier(); + *(vuip)(SPARSE_BASE + (Offset<<5) + (1<<(5-2))) = w * 0x00010001; +} + +static void +writeSparse32(int Value, pointer Base, register unsigned long Offset) +{ + /* NOTE: this is really using DENSE. */ + write_mem_barrier(); + *(vuip)((unsigned long)Base + (Offset)) = Value; + return; +} + +static void +writeSparseNB8(int Value, pointer Base, register unsigned long Offset) +{ + register unsigned long msb; + register unsigned int b = Value & 0xffU; + + Offset += (unsigned long)Base - DENSE_BASE; + if (Offset >= hae_thresh) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip) (SPARSE_BASE + (Offset << 5)) = b * 0x01010101; +} + +static void +writeSparseNB16(int Value, pointer Base, register unsigned long Offset) +{ + register unsigned long msb; + register unsigned int w = Value & 0xffffU; + + Offset += (unsigned long)Base - DENSE_BASE; + if (Offset >= hae_thresh) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip)(SPARSE_BASE+(Offset<<5)+(1<<(5-2))) = w * 0x00010001; +} + +static void +writeSparseNB32(int Value, pointer Base, register unsigned long Offset) +{ + /* NOTE: this is really using DENSE. */ + *(vuip)((unsigned long)Base + (Offset)) = Value; + return; +} + +void (*xf86WriteMmio8)(int Value, pointer Base, unsigned long Offset) + = writeDense8; +void (*xf86WriteMmio16)(int Value, pointer Base, unsigned long Offset) + = writeDense16; +void (*xf86WriteMmio32)(int Value, pointer Base, unsigned long Offset) + = writeDense32; +void (*xf86WriteMmioNB8)(int Value, pointer Base, unsigned long Offset) + = writeDenseNB8; +void (*xf86WriteMmioNB16)(int Value, pointer Base, unsigned long Offset) + = writeDenseNB16; +void (*xf86WriteMmioNB32)(int Value, pointer Base, unsigned long Offset) + = writeDenseNB32; +int (*xf86ReadMmio8)(pointer Base, unsigned long Offset) + = readDense8; +int (*xf86ReadMmio16)(pointer Base, unsigned long Offset) + = readDense16; +int (*xf86ReadMmio32)(pointer Base, unsigned long Offset) + = readDense32; + +#endif /* __alpha__ */ diff --git a/xorg-server/hw/xfree86/os-support/shared/bios_mmap.c b/xorg-server/hw/xfree86/os-support/shared/bios_mmap.c index a5887f578..b7b35d9db 100644 --- a/xorg-server/hw/xfree86/os-support/shared/bios_mmap.c +++ b/xorg-server/hw/xfree86/os-support/shared/bios_mmap.c @@ -1,141 +1,137 @@ -/*
- * Copyright 1993 by David Wexelblat <dwex@goblin.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 David Wexelblat not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. David Wexelblat makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL DAVID WEXELBLAT 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 "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
-/*
- * Read BIOS via mmap()ing DEV_MEM
- */
-
-#ifndef __alpha__
-int
-xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
- int Len)
-{
- int fd;
- unsigned char *ptr;
- int psize;
- int mlen;
-
- if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
- {
- xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
- DEV_MEM, strerror(errno));
- return -1;
- }
- psize = getpagesize();
- Offset += Base & (psize - 1);
- Base &= ~(psize - 1);
- mlen = (Offset + Len + psize - 1) & ~(psize - 1);
- ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ,
- MAP_SHARED, fd, (off_t)Base);
- if (ptr == MAP_FAILED)
- {
- xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed (%s)\n",
- DEV_MEM, strerror(errno));
- close(fd);
- return -1;
- }
- DebugF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
- Base, ptr[0] | (ptr[1] << 8));
- (void)memcpy(Buf, (void *)(ptr + Offset), Len);
- (void)munmap((caddr_t)ptr, mlen);
- (void)close(fd);
- return Len;
-}
-
-#else /* __alpha__ */
-
- /*
- * We trick "mmap" into mapping BUS memory for us via BUS_BASE,
- * which is the KSEG address of the start of the DENSE memory
- * area.
- */
-
- /*
- * NOTE: there prolly ought to be more validity checks and all
- * re: boundaries and sizes and such...
- */
-
-#ifdef linux
-
-extern unsigned long _bus_base(void);
-#define BUS_BASE _bus_base()
-
-#else
-
-extern u_int64_t dense_base(void);
-#define BUS_BASE dense_base()
-
-#endif
-
-int
-xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
- int Len)
-{
- caddr_t base;
- int fd;
- int psize;
- int mlen;
-
- if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
- {
- xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
- DEV_MEM, strerror(errno));
- return -1;
- }
-
- psize = getpagesize();
- Offset += Base & (psize - 1);
- Base &= ~(psize - 1);
- mlen = (Offset + Len + psize - 1) & ~(psize - 1);
- base = mmap((caddr_t)0, mlen, PROT_READ,
- MAP_SHARED, fd, (off_t)(Base + BUS_BASE));
-
- if (base == MAP_FAILED)
- {
- xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to mmap %s (%s)\n",
- DEV_MEM, strerror(errno));
- return -1;
- }
-
- xf86SlowBCopyFromBus((unsigned char *)(base+Offset), Buf, Len);
-
- munmap((caddr_t)base, mlen);
- close(fd);
- return Len;
-}
-
-#endif /* __alpha__ */
+/* + * Copyright 1993 by David Wexelblat <dwex@goblin.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 David Wexelblat not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. David Wexelblat makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL DAVID WEXELBLAT 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 "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +/* + * Read BIOS via mmap()ing DEV_MEM + */ + +#ifndef __alpha__ +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + int fd; + unsigned char *ptr; + int psize; + int mlen; + + if ((fd = open(DEV_MEM, O_RDONLY)) < 0) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + return -1; + } + psize = getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, fd, (off_t)Base); + if (ptr == MAP_FAILED) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed (%s)\n", + DEV_MEM, strerror(errno)); + close(fd); + return -1; + } + DebugF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", + Base, ptr[0] | (ptr[1] << 8)); + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); + (void)close(fd); + return Len; +} + +#else /* __alpha__ */ + + /* + * We trick "mmap" into mapping BUS memory for us via BUS_BASE, + * which is the KSEG address of the start of the DENSE memory + * area. + */ + + /* + * NOTE: there prolly ought to be more validity checks and all + * re: boundaries and sizes and such... + */ + +#ifdef linux + +extern unsigned long _bus_base(void); +#define BUS_BASE _bus_base() + +#else + +extern u_int64_t dense_base(void); +#define BUS_BASE dense_base() + +#endif + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + caddr_t base; + int fd; + int psize; + int mlen; + + if ((fd = open(DEV_MEM, O_RDONLY)) < 0) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + return -1; + } + + psize = getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + base = mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, fd, (off_t)(Base + BUS_BASE)); + + if (base == MAP_FAILED) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to mmap %s (%s)\n", + DEV_MEM, strerror(errno)); + return -1; + } + + xf86SlowBCopyFromBus((unsigned char *)(base+Offset), Buf, Len); + + munmap((caddr_t)base, mlen); + close(fd); + return Len; +} + +#endif /* __alpha__ */ diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h index 1d5906084..0a5861f49 100644 --- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h +++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h @@ -230,20 +230,13 @@ # include <sys/mman.h> # include <sys/stat.h> -# if defined(__bsdi__) -# include <sys/param.h> -# if (_BSDI_VERSION < 199510) -# include <i386/isa/vgaioctl.h> -# endif -# endif /* __bsdi__ */ - #endif /* CSRG_BASED */ /**************************************************************************/ /* Kernel of *BSD */ /**************************************************************************/ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) + defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) # include <sys/param.h> # if defined(__FreeBSD_version) && !defined(__FreeBSD_kernel_version) @@ -252,12 +245,6 @@ # if !defined(LINKKIT) /* Don't need this stuff for the Link Kit */ -# if defined(__bsdi__) -# include <i386/isa/pcconsioctl.h> -# define CONSOLE_X_MODE_ON PCCONIOCRAW -# define CONSOLE_X_MODE_OFF PCCONIOCCOOK -# define CONSOLE_X_BELL PCCONIOCBEEP -# else /* __bsdi__ */ # ifdef SYSCONS_SUPPORT # define COMPAT_SYSCONS # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) @@ -328,7 +315,6 @@ #ifndef CONSOLE_GET_MEM_INFO # define CONSOLE_GET_MEM_INFO _IOR('t',159,struct map_info) #endif -# endif /* __bsdi__ */ # endif /* !LINKKIT */ #if defined(USE_I386_IOPL) || defined(USE_AMD64_IOPL) @@ -337,8 +323,7 @@ # define CLEARDTR_SUPPORT -#endif -/* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ || __bsdi__ */ +#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ */ /**************************************************************************/ /* IRIX */ @@ -378,8 +363,8 @@ #define DEV_MEM "/dev/mem" #endif -#ifndef VT_SYSREQ_DEFAULT -#define VT_SYSREQ_DEFAULT FALSE +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) #endif #define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) diff --git a/xorg-server/hw/xfree86/parser/scan.c b/xorg-server/hw/xfree86/parser/scan.c index b36e58e0f..99b325717 100644 --- a/xorg-server/hw/xfree86/parser/scan.c +++ b/xorg-server/hw/xfree86/parser/scan.c @@ -1,1167 +1,1176 @@ -/*
- * 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.
- *
- */
-/*
- * 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).
- */
-
-
-/* View/edit this file with tab stops set to 4 */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <X11/Xdefs.h>
-#include <X11/Xfuncproto.h>
-
-#if defined(_POSIX_SOURCE)
-#include <limits.h>
-#else
-#define _POSIX_SOURCE
-#include <limits.h>
-#undef _POSIX_SOURCE
-#endif /* _POSIX_SOURCE */
-
-#if !defined(MAXHOSTNAMELEN)
-#define MAXHOSTNAMELEN 32
-#endif /* !MAXHOSTNAMELEN */
-
-/* For PATH_MAX */
-#include "misc.h"
-
-#include "Configint.h"
-#include "xf86tokens.h"
-
-#define CONFIG_BUF_LEN 1024
-#define CONFIG_MAX_FILES 64
-
-static int StringToToken (char *, xf86ConfigSymTabRec *);
-
-static struct {
- FILE *file;
- char *path;
-} configFiles[CONFIG_MAX_FILES];
-static const char **builtinConfig = NULL;
-static int builtinIndex = 0;
-static int configPos = 0; /* current readers position */
-static int configLineNo = 0; /* linenumber */
-static char *configBuf, *configRBuf; /* buffer for lines */
-static char *configPath; /* path to config file */
-static char *configDirPath; /* path to config dir */
-static char *configSection = NULL; /* name of current section being parsed */
-static int numFiles = 0; /* number of config files */
-static int curFileIndex = 0; /* index of current config file */
-static int pushToken = LOCK_TOKEN;
-static int eol_seen = 0; /* private state to handle comments */
-LexRec val;
-
-/*
- * xf86getNextLine --
- *
- * read from the configFiles FILE stream until we encounter a new
- * line; this is effectively just a big wrapper for fgets(3).
- *
- * xf86getToken() assumes that we will read up to the next
- * newline; we need to grow configBuf and configRBuf as needed to
- * support that.
- */
-
-static char*
-xf86getNextLine(void)
-{
- static int configBufLen = CONFIG_BUF_LEN;
- char *tmpConfigBuf, *tmpConfigRBuf;
- int c, i, pos = 0, eolFound = 0;
- char *ret = NULL;
-
- /*
- * reallocate the string if it was grown last time (i.e., is no
- * longer CONFIG_BUF_LEN); we malloc the new strings first, so
- * that if either of the mallocs fail, we can fall back on the
- * existing buffer allocations
- */
-
- if (configBufLen != CONFIG_BUF_LEN) {
-
- tmpConfigBuf = malloc(CONFIG_BUF_LEN);
- tmpConfigRBuf = malloc(CONFIG_BUF_LEN);
-
- if (!tmpConfigBuf || !tmpConfigRBuf) {
-
- /*
- * at least one of the mallocs failed; keep the old buffers
- * and free any partial allocations
- */
-
- free(tmpConfigBuf);
- free(tmpConfigRBuf);
-
- } else {
-
- /*
- * malloc succeeded; free the old buffers and use the new
- * buffers
- */
-
- configBufLen = CONFIG_BUF_LEN;
-
- free(configBuf);
- free(configRBuf);
-
- configBuf = tmpConfigBuf;
- configRBuf = tmpConfigRBuf;
- }
- }
-
- /* read in another block of chars */
-
- do {
- ret = fgets(configBuf + pos, configBufLen - pos - 1,
- configFiles[curFileIndex].file);
-
- if (!ret) {
- /*
- * if the file doesn't end in a newline, add one
- * and trigger another read
- */
- if (pos != 0) {
- strcpy(&configBuf[pos], "\n");
- ret = configBuf;
- } else
- break;
- }
-
- /* search for EOL in the new block of chars */
-
- for (i = pos; i < (configBufLen - 1); i++) {
- c = configBuf[i];
-
- if (c == '\0') break;
-
- if ((c == '\n') || (c == '\r')) {
- eolFound = 1;
- break;
- }
- }
-
- /*
- * if we didn't find EOL, then grow the string and
- * read in more
- */
-
- if (!eolFound) {
-
- tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN);
- tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN);
-
- if (!tmpConfigBuf || !tmpConfigRBuf) {
-
- /*
- * at least one of the reallocations failed; use the
- * new allocation that succeeded, but we have to
- * fallback to the previous configBufLen size and use
- * the string we have, even though we don't have an
- * EOL
- */
-
- if (tmpConfigBuf) configBuf = tmpConfigBuf;
- if (tmpConfigRBuf) configRBuf = tmpConfigRBuf;
-
- break;
-
- } else {
-
- /* reallocation succeeded */
-
- configBuf = tmpConfigBuf;
- configRBuf = tmpConfigRBuf;
- pos = i;
- configBufLen += CONFIG_BUF_LEN;
- }
- }
-
- } while (!eolFound);
-
- return ret;
-}
-
-/*
- * xf86getToken --
- * Read next Token from the config file. Handle the global variable
- * pushToken.
- */
-int
-xf86getToken (xf86ConfigSymTabRec * tab)
-{
- int c, i;
-
- /*
- * First check whether pushToken has a different value than LOCK_TOKEN.
- * In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the
- * oth * case the next token must be read from the input.
- */
- if (pushToken == EOF_TOKEN)
- return EOF_TOKEN;
- else if (pushToken == LOCK_TOKEN)
- {
- /*
- * eol_seen is only set for the first token after a newline.
- */
- eol_seen = 0;
-
- c = configBuf[configPos];
-
- /*
- * Get start of next Token. EOF is handled,
- * whitespaces are skipped.
- */
-
-again:
- if (!c)
- {
- char *ret;
- if (numFiles > 0)
- ret = xf86getNextLine();
- else {
- if (builtinConfig[builtinIndex] == NULL)
- ret = NULL;
- else {
- ret = strncpy(configBuf, builtinConfig[builtinIndex],
- CONFIG_BUF_LEN);
- builtinIndex++;
- }
- }
- if (ret == NULL)
- {
- /*
- * if necessary, move to the next file and
- * read the first line
- */
- if (curFileIndex + 1 < numFiles) {
- curFileIndex++;
- configLineNo = 0;
- goto again;
- }
- else
- return pushToken = EOF_TOKEN;
- }
- configLineNo++;
- configPos = 0;
- eol_seen = 1;
- }
-
- i = 0;
- for (;;) {
- c = configBuf[configPos++];
- configRBuf[i++] = c;
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- continue;
- case '\n':
- i = 0;
- continue;
- }
- break;
- }
- if (c == '\0')
- goto again;
-
- if (c == '#')
- {
- do
- {
- configRBuf[i++] = (c = configBuf[configPos++]);
- }
- while ((c != '\n') && (c != '\r') && (c != '\0'));
- configRBuf[i] = '\0';
- /* XXX no private copy.
- * Use xf86addComment when setting a comment.
- */
- val.str = configRBuf;
- return COMMENT;
- }
-
- /* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */
- else if ((c == ',') && !isalpha (configBuf[configPos]))
- {
- return COMMA;
- }
- else if ((c == '-') && !isalpha (configBuf[configPos]))
- {
- return DASH;
- }
-
- /*
- * Numbers are returned immediately ...
- */
- if (isdigit (c))
- {
- int base;
-
- if (c == '0')
- if ((configBuf[configPos] == 'x') ||
- (configBuf[configPos] == 'X'))
- {
- base = 16;
- val.numType = PARSE_HEX;
- }
- else
- {
- base = 8;
- val.numType = PARSE_OCTAL;
- }
- else
- {
- base = 10;
- val.numType = PARSE_DECIMAL;
- }
-
- configRBuf[0] = c;
- i = 1;
- while (isdigit (c = configBuf[configPos++]) ||
- (c == '.') || (c == 'x') || (c == 'X') ||
- ((base == 16) && (((c >= 'a') && (c <= 'f')) ||
- ((c >= 'A') && (c <= 'F')))))
- configRBuf[i++] = c;
- configPos--; /* GJA -- one too far */
- configRBuf[i] = '\0';
- val.num = strtoul (configRBuf, NULL, 0);
- val.realnum = atof (configRBuf);
- return NUMBER;
- }
-
- /*
- * All Strings START with a \" ...
- */
- else if (c == '\"')
- {
- i = -1;
- do
- {
- configRBuf[++i] = (c = configBuf[configPos++]);
- }
- while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0'));
- configRBuf[i] = '\0';
- val.str = malloc (strlen (configRBuf) + 1);
- strcpy (val.str, configRBuf); /* private copy ! */
- return STRING;
- }
-
- /*
- * ... and now we MUST have a valid token. The search is
- * handled later along with the pushed tokens.
- */
- else
- {
- configRBuf[0] = c;
- i = 0;
- do
- {
- configRBuf[++i] = (c = configBuf[configPos++]);
- }
- while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') && (c != '\0') && (c != '#'));
- --configPos;
- configRBuf[i] = '\0';
- i = 0;
- }
-
- }
- else
- {
-
- /*
- * Here we deal with pushed tokens. Reinitialize pushToken again. If
- * the pushed token was NUMBER || STRING return them again ...
- */
- int temp = pushToken;
- pushToken = LOCK_TOKEN;
-
- if (temp == COMMA || temp == DASH)
- return temp;
- if (temp == NUMBER || temp == STRING)
- return temp;
- }
-
- /*
- * Joop, at last we have to lookup the token ...
- */
- if (tab)
- {
- i = 0;
- while (tab[i].token != -1)
- if (xf86nameCompare (configRBuf, tab[i].name) == 0)
- return tab[i].token;
- else
- i++;
- }
-
- return ERROR_TOKEN; /* Error catcher */
-}
-
-int
-xf86getSubToken (char **comment)
-{
- int token;
-
- for (;;) {
- token = xf86getToken(NULL);
- if (token == COMMENT) {
- if (comment)
- *comment = xf86addComment(*comment, val.str);
- }
- else
- return token;
- }
- /*NOTREACHED*/
-}
-
-int
-xf86getSubTokenWithTab (char **comment, xf86ConfigSymTabRec *tab)
-{
- int token;
-
- for (;;) {
- token = xf86getToken(tab);
- if (token == COMMENT) {
- if (comment)
- *comment = xf86addComment(*comment, val.str);
- }
- else
- return token;
- }
- /*NOTREACHED*/
-}
-
-void
-xf86unGetToken (int token)
-{
- pushToken = token;
-}
-
-char *
-xf86tokenString (void)
-{
- return configRBuf;
-}
-
-int
-xf86pathIsAbsolute(const char *path)
-{
- if (path && path[0] == '/')
- return 1;
- return 0;
-}
-
-/* A path is "safe" if it is relative and if it contains no ".." elements. */
-int
-xf86pathIsSafe(const char *path)
-{
- if (xf86pathIsAbsolute(path))
- return 0;
-
- /* Compare with ".." */
- if (!strcmp(path, ".."))
- return 0;
-
- /* Look for leading "../" */
- if (!strncmp(path, "../", 3))
- return 0;
-
- /* Look for trailing "/.." */
- if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/.."))
- return 0;
-
- /* Look for "/../" */
- if (strstr(path, "/../"))
- return 0;
-
- return 1;
-}
-
-/*
- * This function substitutes the following escape sequences:
- *
- * %A cmdline argument as an absolute path (must be absolute to match)
- * %R cmdline argument as a relative path
- * %S cmdline argument as a "safe" path (relative, and no ".." elements)
- * %X default config file name ("xorg.conf")
- * %H hostname
- * %E config file environment ($XORGCONFIG) as an absolute path
- * %F config file environment ($XORGCONFIG) as a relative path
- * %G config file environment ($XORGCONFIG) as a safe path
- * %P projroot
- * %C sysconfdir
- * %D datadir
- * %% %
- */
-
-#ifndef XCONFIGFILE
-#define XCONFIGFILE "xorg.conf"
-#endif
-#ifndef XCONFIGDIR
-#define XCONFIGDIR "xorg.conf.d"
-#endif
-#ifndef XCONFIGSUFFIX
-#define XCONFIGSUFFIX ".conf"
-#endif
-#ifndef PROJECTROOT
-#define PROJECTROOT "/usr/X11R6"
-#endif
-#ifndef SYSCONFDIR
-#define SYSCONFDIR PROJECTROOT "/etc"
-#endif
-#ifndef DATADIR
-#define DATADIR PROJECTROOT "/share"
-#endif
-#ifndef XCONFENV
-#define XCONFENV "XORGCONFIG"
-#endif
-
-#define BAIL_OUT do { \
- free(result); \
- return NULL; \
- } while (0)
-
-#define CHECK_LENGTH do { \
- if (l > PATH_MAX) { \
- BAIL_OUT; \
- } \
- } while (0)
-
-#define APPEND_STR(s) do { \
- if (strlen(s) + l > PATH_MAX) { \
- BAIL_OUT; \
- } else { \
- strcpy(result + l, s); \
- l += strlen(s); \
- } \
- } while (0)
-
-static char *
-DoSubstitution(const char *template, const char *cmdline, const char *projroot,
- int *cmdlineUsed, int *envUsed,
- const char *XConfigFile)
-{
- char *result;
- int i, l;
- static const char *env = NULL;
- static char *hostname = NULL;
-
- if (!template)
- return NULL;
-
- if (cmdlineUsed)
- *cmdlineUsed = 0;
- if (envUsed)
- *envUsed = 0;
-
- result = malloc(PATH_MAX + 1);
- l = 0;
- for (i = 0; template[i]; i++) {
- if (template[i] != '%') {
- result[l++] = template[i];
- CHECK_LENGTH;
- } else {
- switch (template[++i]) {
- case 'A':
- if (cmdline && xf86pathIsAbsolute(cmdline)) {
- APPEND_STR(cmdline);
- if (cmdlineUsed)
- *cmdlineUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'R':
- if (cmdline && !xf86pathIsAbsolute(cmdline)) {
- APPEND_STR(cmdline);
- if (cmdlineUsed)
- *cmdlineUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'S':
- if (cmdline && xf86pathIsSafe(cmdline)) {
- APPEND_STR(cmdline);
- if (cmdlineUsed)
- *cmdlineUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'X':
- APPEND_STR(XConfigFile);
- break;
- case 'H':
- if (!hostname) {
- if ((hostname = malloc(MAXHOSTNAMELEN + 1))) {
- if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
- hostname[MAXHOSTNAMELEN] = '\0';
- } else {
- free(hostname);
- hostname = NULL;
- }
- }
- }
- if (hostname)
- APPEND_STR(hostname);
- break;
- case 'E':
- if (!env)
- env = getenv(XCONFENV);
- if (env && xf86pathIsAbsolute(env)) {
- APPEND_STR(env);
- if (envUsed)
- *envUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'F':
- if (!env)
- env = getenv(XCONFENV);
- if (env && !xf86pathIsAbsolute(env)) {
- APPEND_STR(env);
- if (envUsed)
- *envUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'G':
- if (!env)
- env = getenv(XCONFENV);
- if (env && xf86pathIsSafe(env)) {
- APPEND_STR(env);
- if (envUsed)
- *envUsed = 1;
- } else
- BAIL_OUT;
- break;
- case 'P':
- if (projroot && xf86pathIsAbsolute(projroot))
- APPEND_STR(projroot);
- else
- BAIL_OUT;
- break;
- case 'C':
- APPEND_STR(SYSCONFDIR);
- break;
- case 'D':
- APPEND_STR(DATADIR);
- break;
- case '%':
- result[l++] = '%';
- CHECK_LENGTH;
- break;
- default:
- fprintf(stderr, "invalid escape %%%c found in path template\n",
- template[i]);
- BAIL_OUT;
- break;
- }
- }
- }
-#ifdef DEBUG
- fprintf(stderr, "Converted `%s' to `%s'\n", template, result);
-#endif
- return result;
-}
-
-/*
- * Given some searching parameters, locate and open the xorg config file.
- */
-static char *
-OpenConfigFile(const char *path, const char *cmdline, const char *projroot,
- const char *confname)
-{
- char *filepath = NULL;
- char *pathcopy;
- const char *template;
- int cmdlineUsed = 0;
- FILE *file = NULL;
-
- pathcopy = strdup(path);
- for (template = strtok(pathcopy, ","); template && !file;
- template = strtok(NULL, ",")) {
- filepath = DoSubstitution(template, cmdline, projroot,
- &cmdlineUsed, NULL, confname);
- if (!filepath)
- continue;
- if (cmdline && !cmdlineUsed) {
- free(filepath);
- filepath = NULL;
- continue;
- }
- file = fopen(filepath, "r");
- if (!file) {
- free(filepath);
- filepath = NULL;
- }
- }
-
- free(pathcopy);
- if (file) {
- configFiles[numFiles].file = file;
- configFiles[numFiles].path = strdup(filepath);
- numFiles++;
- }
- return filepath;
-}
-
-/*
- * Match non-hidden files in the xorg config directory with a .conf
- * suffix. This filter is passed to scandir(3).
- */
-static int
-ConfigFilter(const struct dirent *de)
-{
- const char *name = de->d_name;
- size_t len;
- size_t suflen = strlen(XCONFIGSUFFIX);
-
- if (!name || name[0] == '.')
- return 0;
- len = strlen(name);
- if(len <= suflen)
- return 0;
- if (strcmp(&name[len-suflen], XCONFIGSUFFIX) != 0)
- return 0;
- return 1;
-}
-
-static Bool
-AddConfigDirFiles(const char *dirpath, struct dirent **list, int num)
-{
- int i;
- Bool openedFile = FALSE;
- Bool warnOnce = FALSE;
-
- for (i = 0; i < num; i++) {
- char *path;
- FILE *file;
-
- if (numFiles >= CONFIG_MAX_FILES) {
- if (!warnOnce) {
- ErrorF("Maximum number of configuration "
- "files opened\n");
- warnOnce = TRUE;
- }
- free(list[i]);
- continue;
- }
-
- path = malloc(PATH_MAX + 1);
- snprintf(path, PATH_MAX + 1, "%s/%s", dirpath,
- list[i]->d_name);
- free(list[i]);
- file = fopen(path, "r");
- if (!file) {
- free(path);
- continue;
- }
- openedFile = TRUE;
-
- configFiles[numFiles].file = file;
- configFiles[numFiles].path = path;
- numFiles++;
- }
-
- return openedFile;
-}
-
-/*
- * Given some searching parameters, locate and open the xorg config
- * directory. The directory does not need to contain config files.
- */
-static char *
-OpenConfigDir(const char *path, const char *cmdline, const char *projroot,
- const char *confname)
-{
- char *dirpath, *pathcopy;
- const char *template;
- Bool found = FALSE;
- int cmdlineUsed = 0;
-
- pathcopy = strdup(path);
- for (template = strtok(pathcopy, ","); template && !found;
- template = strtok(NULL, ",")) {
- struct dirent **list = NULL;
- int num;
-
- dirpath = DoSubstitution(template, cmdline, projroot,
- &cmdlineUsed, NULL, confname);
- if (!dirpath)
- continue;
- if (cmdline && !cmdlineUsed) {
- free(dirpath);
- dirpath = NULL;
- continue;
- }
-
- /* match files named *.conf */
- num = scandir(dirpath, &list, ConfigFilter, alphasort);
- found = AddConfigDirFiles(dirpath, list, num);
- if (!found) {
- free(dirpath);
- dirpath = NULL;
- free(list);
- }
- }
-
- free(pathcopy);
- return dirpath;
-}
-
-/*
- * xf86initConfigFiles -- Setup global variables and buffers.
- */
-void
-xf86initConfigFiles(void)
-{
- curFileIndex = 0;
- configPos = 0;
- configLineNo = 0;
- pushToken = LOCK_TOKEN;
-
- configBuf = malloc(CONFIG_BUF_LEN);
- configRBuf = malloc(CONFIG_BUF_LEN);
- configBuf[0] = '\0'; /* sanity ... */
-}
-
-/*
- * xf86openConfigFile --
- *
- * This function take a config file search path (optional), a command-line
- * specified file name (optional) and the ProjectRoot path (optional) and
- * locates and opens a config file based on that information. If a
- * command-line file name is specified, then this function fails if none
- * of the located files.
- *
- * The return value is a pointer to the actual name of the file that was
- * opened. When no file is found, the return value is NULL.
- *
- * The escape sequences allowed in the search path are defined above.
- *
- */
-
-#ifndef DEFAULT_CONF_PATH
-#define DEFAULT_CONF_PATH "/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
-
-const char *
-xf86openConfigFile(const char *path, const char *cmdline, const char *projroot)
-{
- if (!path || !path[0])
- path = DEFAULT_CONF_PATH;
- if (!projroot || !projroot[0])
- projroot = PROJECTROOT;
-
- /* Search for a config file */
- configPath = OpenConfigFile(path, cmdline, projroot, XCONFIGFILE);
- return configPath;
-}
-
-/*
- * xf86openConfigDirFiles --
- *
- * This function take a config directory search path (optional), a
- * command-line specified directory name (optional) and the ProjectRoot path
- * (optional) and locates and opens a config directory based on that
- * information. If a command-line name is specified, then this function
- * fails if it is not found.
- *
- * The return value is a pointer to the actual name of the direcoty that was
- * opened. When no directory is found, the return value is NULL.
- *
- * The escape sequences allowed in the search path are defined above.
- *
- */
-const char *
-xf86openConfigDirFiles(const char *path, const char *cmdline,
- const char *projroot)
-{
- if (!path || !path[0])
- path = DEFAULT_CONF_PATH;
- if (!projroot || !projroot[0])
- projroot = PROJECTROOT;
-
- /* Search for the multiconf directory */
- configDirPath = OpenConfigDir(path, cmdline, projroot, XCONFIGDIR);
- return configDirPath;
-}
-
-void
-xf86closeConfigFile (void)
-{
- int i;
-
- free (configPath);
- configPath = NULL;
- free (configDirPath);
- configDirPath = NULL;
- free (configRBuf);
- configRBuf = NULL;
- free (configBuf);
- configBuf = NULL;
-
- if (numFiles == 0) {
- builtinConfig = NULL;
- builtinIndex = 0;
- }
- for (i = 0; i < numFiles; i++) {
- fclose(configFiles[i].file);
- configFiles[i].file = NULL;
- free(configFiles[i].path);
- configFiles[i].path = NULL;
- }
- numFiles = 0;
-}
-
-void
-xf86setBuiltinConfig(const char *config[])
-{
- builtinConfig = config;
-}
-
-void
-xf86parseError (char *format,...)
-{
- va_list ap;
- char *filename = numFiles ? configFiles[curFileIndex].path :
- "<builtin configuration>";
-
- ErrorF ("Parse error on line %d of section %s in file %s\n\t",
- configLineNo, configSection, filename);
- va_start (ap, format);
- VErrorF (format, ap);
- va_end (ap);
-
- ErrorF ("\n");
-}
-
-void
-xf86validationError (char *format,...)
-{
- va_list ap;
- char *filename = numFiles ? configFiles[curFileIndex].path :
- "<builtin configuration>";
-
- ErrorF ("Data incomplete in file %s\n\t", filename);
- va_start (ap, format);
- VErrorF (format, ap);
- va_end (ap);
-
- ErrorF ("\n");
-}
-
-void
-xf86setSection (char *section)
-{
- free(configSection);
- configSection = strdup(section);
-}
-
-/*
- * xf86getToken --
- * Lookup a string if it is actually a token in disguise.
- */
-int
-xf86getStringToken (xf86ConfigSymTabRec * tab)
-{
- return StringToToken (val.str, tab);
-}
-
-static int
-StringToToken (char *str, xf86ConfigSymTabRec * tab)
-{
- int i;
-
- for (i = 0; tab[i].token != -1; i++)
- {
- if (!xf86nameCompare (tab[i].name, str))
- return tab[i].token;
- }
- return ERROR_TOKEN;
-}
-
-
-/*
- * Compare two names. The characters '_', ' ', and '\t' are ignored
- * in the comparison.
- */
-int
-xf86nameCompare (const char *s1, const char *s2)
-{
- char c1, c2;
-
- if (!s1 || *s1 == 0) {
- if (!s2 || *s2 == 0)
- return 0;
- else
- return 1;
- }
-
- while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
- s1++;
- while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
- s2++;
- c1 = (isupper (*s1) ? tolower (*s1) : *s1);
- c2 = (isupper (*s2) ? tolower (*s2) : *s2);
- while (c1 == c2)
- {
- if (c1 == '\0')
- return 0;
- s1++;
- s2++;
- while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
- s1++;
- while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
- s2++;
- c1 = (isupper (*s1) ? tolower (*s1) : *s1);
- c2 = (isupper (*s2) ? tolower (*s2) : *s2);
- }
- return c1 - c2;
-}
-
-char *
-xf86addComment(char *cur, char *add)
-{
- char *str;
- int len, curlen, iscomment, hasnewline = 0, endnewline;
-
- if (add == NULL || add[0] == '\0')
- return cur;
-
- if (cur) {
- curlen = strlen(cur);
- if (curlen)
- hasnewline = cur[curlen - 1] == '\n';
- eol_seen = 0;
- }
- else
- curlen = 0;
-
- str = add;
- iscomment = 0;
- while (*str) {
- if (*str != ' ' && *str != '\t')
- break;
- ++str;
- }
- iscomment = (*str == '#');
-
- len = strlen(add);
- endnewline = add[len - 1] == '\n';
- len += 1 + iscomment + (!hasnewline) + (!endnewline) + eol_seen;
-
- if ((str = realloc(cur, len + curlen)) == NULL)
- return cur;
-
- cur = str;
-
- if (eol_seen || (curlen && !hasnewline))
- cur[curlen++] = '\n';
- if (!iscomment)
- cur[curlen++] = '#';
- strcpy(cur + curlen, add);
- if (!endnewline)
- strcat(cur, "\n");
-
- return cur;
-}
-
-Bool
-xf86getBoolValue(Bool *val, const char *str)
-{
- if (!val || !str)
- return FALSE;
- if (*str == '\0') {
- *val = TRUE;
- } else {
- if (xf86nameCompare(str, "1") == 0)
- *val = TRUE;
- else if (xf86nameCompare(str, "on") == 0)
- *val = TRUE;
- else if (xf86nameCompare(str, "true") == 0)
- *val = TRUE;
- else if (xf86nameCompare(str, "yes") == 0)
- *val = TRUE;
- else if (xf86nameCompare(str, "0") == 0)
- *val = FALSE;
- else if (xf86nameCompare(str, "off") == 0)
- *val = FALSE;
- else if (xf86nameCompare(str, "false") == 0)
- *val = FALSE;
- else if (xf86nameCompare(str, "no") == 0)
- *val = FALSE;
- else
- return FALSE;
- }
- return TRUE;
-}
+/* + * 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. + * + */ +/* + * 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). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <dirent.h> +#include <unistd.h> +#include <stdarg.h> +#include <X11/Xdefs.h> +#include <X11/Xfuncproto.h> + +#if defined(_POSIX_SOURCE) +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif /* _POSIX_SOURCE */ + +#if !defined(MAXHOSTNAMELEN) +#define MAXHOSTNAMELEN 32 +#endif /* !MAXHOSTNAMELEN */ + +/* For PATH_MAX */ +#include "misc.h" + +#include "Configint.h" +#include "xf86tokens.h" + +#define CONFIG_BUF_LEN 1024 +#define CONFIG_MAX_FILES 64 + +static int StringToToken (char *, xf86ConfigSymTabRec *); + +static struct { + FILE *file; + char *path; +} configFiles[CONFIG_MAX_FILES]; +static const char **builtinConfig = NULL; +static int builtinIndex = 0; +static int configPos = 0; /* current readers position */ +static int configLineNo = 0; /* linenumber */ +static char *configBuf, *configRBuf; /* buffer for lines */ +static char *configPath; /* path to config file */ +static char *configDirPath; /* path to config dir */ +static char *configSection = NULL; /* name of current section being parsed */ +static int numFiles = 0; /* number of config files */ +static int curFileIndex = 0; /* index of current config file */ +static int pushToken = LOCK_TOKEN; +static int eol_seen = 0; /* private state to handle comments */ +LexRec val; + +/* + * xf86getNextLine -- + * + * read from the configFiles FILE stream until we encounter a new + * line; this is effectively just a big wrapper for fgets(3). + * + * xf86getToken() assumes that we will read up to the next + * newline; we need to grow configBuf and configRBuf as needed to + * support that. + */ + +static char* +xf86getNextLine(void) +{ + static int configBufLen = CONFIG_BUF_LEN; + char *tmpConfigBuf, *tmpConfigRBuf; + int c, i, pos = 0, eolFound = 0; + char *ret = NULL; + + /* + * reallocate the string if it was grown last time (i.e., is no + * longer CONFIG_BUF_LEN); we malloc the new strings first, so + * that if either of the mallocs fail, we can fall back on the + * existing buffer allocations + */ + + if (configBufLen != CONFIG_BUF_LEN) { + + tmpConfigBuf = malloc(CONFIG_BUF_LEN); + tmpConfigRBuf = malloc(CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the mallocs failed; keep the old buffers + * and free any partial allocations + */ + + free(tmpConfigBuf); + free(tmpConfigRBuf); + + } else { + + /* + * malloc succeeded; free the old buffers and use the new + * buffers + */ + + configBufLen = CONFIG_BUF_LEN; + + free(configBuf); + free(configRBuf); + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + } + } + + /* read in another block of chars */ + + do { + ret = fgets(configBuf + pos, configBufLen - pos - 1, + configFiles[curFileIndex].file); + + if (!ret) { + /* + * if the file doesn't end in a newline, add one + * and trigger another read + */ + if (pos != 0) { + strcpy(&configBuf[pos], "\n"); + ret = configBuf; + } else + break; + } + + /* search for EOL in the new block of chars */ + + for (i = pos; i < (configBufLen - 1); i++) { + c = configBuf[i]; + + if (c == '\0') break; + + if ((c == '\n') || (c == '\r')) { + eolFound = 1; + break; + } + } + + /* + * if we didn't find EOL, then grow the string and + * read in more + */ + + if (!eolFound) { + + tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN); + tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the reallocations failed; use the + * new allocation that succeeded, but we have to + * fallback to the previous configBufLen size and use + * the string we have, even though we don't have an + * EOL + */ + + if (tmpConfigBuf) configBuf = tmpConfigBuf; + if (tmpConfigRBuf) configRBuf = tmpConfigRBuf; + + break; + + } else { + + /* reallocation succeeded */ + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + pos = i; + configBufLen += CONFIG_BUF_LEN; + } + } + + } while (!eolFound); + + return ret; +} + +/* + * xf86getToken -- + * Read next Token from the config file. Handle the global variable + * pushToken. + */ +int +xf86getToken (xf86ConfigSymTabRec * tab) +{ + int c, i; + + /* + * First check whether pushToken has a different value than LOCK_TOKEN. + * In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the + * oth * case the next token must be read from the input. + */ + if (pushToken == EOF_TOKEN) + return EOF_TOKEN; + else if (pushToken == LOCK_TOKEN) + { + /* + * eol_seen is only set for the first token after a newline. + */ + eol_seen = 0; + + c = configBuf[configPos]; + + /* + * Get start of next Token. EOF is handled, + * whitespaces are skipped. + */ + +again: + if (!c) + { + char *ret; + if (numFiles > 0) + ret = xf86getNextLine(); + else { + if (builtinConfig[builtinIndex] == NULL) + ret = NULL; + else { + ret = strncpy(configBuf, builtinConfig[builtinIndex], + CONFIG_BUF_LEN); + builtinIndex++; + } + } + if (ret == NULL) + { + /* + * if necessary, move to the next file and + * read the first line + */ + if (curFileIndex + 1 < numFiles) { + curFileIndex++; + configLineNo = 0; + goto again; + } + else + return pushToken = EOF_TOKEN; + } + configLineNo++; + configPos = 0; + eol_seen = 1; + } + + i = 0; + for (;;) { + c = configBuf[configPos++]; + configRBuf[i++] = c; + switch (c) { + case ' ': + case '\t': + case '\r': + continue; + case '\n': + i = 0; + continue; + } + break; + } + if (c == '\0') + goto again; + + if (c == '#') + { + do + { + configRBuf[i++] = (c = configBuf[configPos++]); + } + while ((c != '\n') && (c != '\r') && (c != '\0')); + configRBuf[i] = '\0'; + /* XXX no private copy. + * Use xf86addComment when setting a comment. + */ + val.str = configRBuf; + return COMMENT; + } + + /* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */ + else if ((c == ',') && !isalpha (configBuf[configPos])) + { + return COMMA; + } + else if ((c == '-') && !isalpha (configBuf[configPos])) + { + return DASH; + } + + /* + * Numbers are returned immediately ... + */ + if (isdigit (c)) + { + int base; + + if (c == '0') + if ((configBuf[configPos] == 'x') || + (configBuf[configPos] == 'X')) + { + base = 16; + val.numType = PARSE_HEX; + } + else + { + base = 8; + val.numType = PARSE_OCTAL; + } + else + { + base = 10; + val.numType = PARSE_DECIMAL; + } + + configRBuf[0] = c; + i = 1; + while (isdigit (c = configBuf[configPos++]) || + (c == '.') || (c == 'x') || (c == 'X') || + ((base == 16) && (((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F'))))) + configRBuf[i++] = c; + configPos--; /* GJA -- one too far */ + configRBuf[i] = '\0'; + val.num = strtoul (configRBuf, NULL, 0); + val.realnum = atof (configRBuf); + return NUMBER; + } + + /* + * All Strings START with a \" ... + */ + else if (c == '\"') + { + i = -1; + do + { + configRBuf[++i] = (c = configBuf[configPos++]); + } + while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0')); + configRBuf[i] = '\0'; + val.str = malloc (strlen (configRBuf) + 1); + strcpy (val.str, configRBuf); /* private copy ! */ + return STRING; + } + + /* + * ... and now we MUST have a valid token. The search is + * handled later along with the pushed tokens. + */ + else + { + configRBuf[0] = c; + i = 0; + do + { + configRBuf[++i] = (c = configBuf[configPos++]); + } + while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') && (c != '\0') && (c != '#')); + --configPos; + configRBuf[i] = '\0'; + i = 0; + } + + } + else + { + + /* + * Here we deal with pushed tokens. Reinitialize pushToken again. If + * the pushed token was NUMBER || STRING return them again ... + */ + int temp = pushToken; + pushToken = LOCK_TOKEN; + + if (temp == COMMA || temp == DASH) + return temp; + if (temp == NUMBER || temp == STRING) + return temp; + } + + /* + * Joop, at last we have to lookup the token ... + */ + if (tab) + { + i = 0; + while (tab[i].token != -1) + if (xf86nameCompare (configRBuf, tab[i].name) == 0) + return tab[i].token; + else + i++; + } + + return ERROR_TOKEN; /* Error catcher */ +} + +int +xf86getSubToken (char **comment) +{ + int token; + + for (;;) { + token = xf86getToken(NULL); + if (token == COMMENT) { + if (comment) + *comment = xf86addComment(*comment, val.str); + } + else + return token; + } + /*NOTREACHED*/ +} + +int +xf86getSubTokenWithTab (char **comment, xf86ConfigSymTabRec *tab) +{ + int token; + + for (;;) { + token = xf86getToken(tab); + if (token == COMMENT) { + if (comment) + *comment = xf86addComment(*comment, val.str); + } + else + return token; + } + /*NOTREACHED*/ +} + +void +xf86unGetToken (int token) +{ + pushToken = token; +} + +char * +xf86tokenString (void) +{ + return configRBuf; +} + +int +xf86pathIsAbsolute(const char *path) +{ + if (path && path[0] == '/') + return 1; + return 0; +} + +/* A path is "safe" if it is relative and if it contains no ".." elements. */ +int +xf86pathIsSafe(const char *path) +{ + if (xf86pathIsAbsolute(path)) + return 0; + + /* Compare with ".." */ + if (!strcmp(path, "..")) + return 0; + + /* Look for leading "../" */ + if (!strncmp(path, "../", 3)) + return 0; + + /* Look for trailing "/.." */ + if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/..")) + return 0; + + /* Look for "/../" */ + if (strstr(path, "/../")) + return 0; + + return 1; +} + +/* + * This function substitutes the following escape sequences: + * + * %A cmdline argument as an absolute path (must be absolute to match) + * %R cmdline argument as a relative path + * %S cmdline argument as a "safe" path (relative, and no ".." elements) + * %X default config file name ("xorg.conf") + * %H hostname + * %E config file environment ($XORGCONFIG) as an absolute path + * %F config file environment ($XORGCONFIG) as a relative path + * %G config file environment ($XORGCONFIG) as a safe path + * %P projroot + * %C sysconfdir + * %D datadir + * %% % + */ + +#ifndef XCONFIGFILE +#define XCONFIGFILE "xorg.conf" +#endif +#ifndef XCONFIGDIR +#define XCONFIGDIR "xorg.conf.d" +#endif +#ifndef XCONFIGSUFFIX +#define XCONFIGSUFFIX ".conf" +#endif +#ifndef PROJECTROOT +#define PROJECTROOT "/usr/X11R6" +#endif +#ifndef SYSCONFDIR +#define SYSCONFDIR PROJECTROOT "/etc" +#endif +#ifndef DATADIR +#define DATADIR PROJECTROOT "/share" +#endif +#ifndef XCONFENV +#define XCONFENV "XORGCONFIG" +#endif + +#define BAIL_OUT do { \ + free(result); \ + return NULL; \ + } while (0) + +#define CHECK_LENGTH do { \ + if (l > PATH_MAX) { \ + BAIL_OUT; \ + } \ + } while (0) + +#define APPEND_STR(s) do { \ + if (strlen(s) + l > PATH_MAX) { \ + BAIL_OUT; \ + } else { \ + strcpy(result + l, s); \ + l += strlen(s); \ + } \ + } while (0) + +static char * +DoSubstitution(const char *template, const char *cmdline, const char *projroot, + int *cmdlineUsed, int *envUsed, + const char *XConfigFile) +{ + char *result; + int i, l; + static const char *env = NULL; + static char *hostname = NULL; + + if (!template) + return NULL; + + if (cmdlineUsed) + *cmdlineUsed = 0; + if (envUsed) + *envUsed = 0; + + result = malloc(PATH_MAX + 1); + l = 0; + for (i = 0; template[i]; i++) { + if (template[i] != '%') { + result[l++] = template[i]; + CHECK_LENGTH; + } else { + switch (template[++i]) { + case 'A': + if (cmdline && xf86pathIsAbsolute(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'R': + if (cmdline && !xf86pathIsAbsolute(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'S': + if (cmdline && xf86pathIsSafe(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'X': + APPEND_STR(XConfigFile); + break; + case 'H': + if (!hostname) { + if ((hostname = malloc(MAXHOSTNAMELEN + 1))) { + if (gethostname(hostname, MAXHOSTNAMELEN) == 0) { + hostname[MAXHOSTNAMELEN] = '\0'; + } else { + free(hostname); + hostname = NULL; + } + } + } + if (hostname) + APPEND_STR(hostname); + break; + case 'E': + if (!env) + env = getenv(XCONFENV); + if (env && xf86pathIsAbsolute(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'F': + if (!env) + env = getenv(XCONFENV); + if (env && !xf86pathIsAbsolute(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'G': + if (!env) + env = getenv(XCONFENV); + if (env && xf86pathIsSafe(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'P': + if (projroot && xf86pathIsAbsolute(projroot)) + APPEND_STR(projroot); + else + BAIL_OUT; + break; + case 'C': + APPEND_STR(SYSCONFDIR); + break; + case 'D': + APPEND_STR(DATADIR); + break; + case '%': + result[l++] = '%'; + CHECK_LENGTH; + break; + default: + fprintf(stderr, "invalid escape %%%c found in path template\n", + template[i]); + BAIL_OUT; + break; + } + } + } +#ifdef DEBUG + fprintf(stderr, "Converted `%s' to `%s'\n", template, result); +#endif + return result; +} + +/* + * Given some searching parameters, locate and open the xorg config file. + */ +static char * +OpenConfigFile(const char *path, const char *cmdline, const char *projroot, + const char *confname) +{ + char *filepath = NULL; + char *pathcopy; + const char *template; + int cmdlineUsed = 0; + FILE *file = NULL; + + pathcopy = strdup(path); + for (template = strtok(pathcopy, ","); template && !file; + template = strtok(NULL, ",")) { + filepath = DoSubstitution(template, cmdline, projroot, + &cmdlineUsed, NULL, confname); + if (!filepath) + continue; + if (cmdline && !cmdlineUsed) { + free(filepath); + filepath = NULL; + continue; + } + file = fopen(filepath, "r"); + if (!file) { + free(filepath); + filepath = NULL; + } + } + + free(pathcopy); + if (file) { + configFiles[numFiles].file = file; + configFiles[numFiles].path = strdup(filepath); + numFiles++; + } + return filepath; +} + +/* + * Match non-hidden files in the xorg config directory with a .conf + * suffix. This filter is passed to scandir(3). + */ +static int +ConfigFilter(const struct dirent *de) +{ + const char *name = de->d_name; + size_t len; + size_t suflen = strlen(XCONFIGSUFFIX); + + if (!name || name[0] == '.') + return 0; + len = strlen(name); + if(len <= suflen) + return 0; + if (strcmp(&name[len-suflen], XCONFIGSUFFIX) != 0) + return 0; + return 1; +} + +static Bool +AddConfigDirFiles(const char *dirpath, struct dirent **list, int num) +{ + int i; + Bool openedFile = FALSE; + Bool warnOnce = FALSE; + + for (i = 0; i < num; i++) { + char *path; + FILE *file; + + if (numFiles >= CONFIG_MAX_FILES) { + if (!warnOnce) { + ErrorF("Maximum number of configuration " + "files opened\n"); + warnOnce = TRUE; + } + free(list[i]); + continue; + } + + path = malloc(PATH_MAX + 1); + snprintf(path, PATH_MAX + 1, "%s/%s", dirpath, + list[i]->d_name); + free(list[i]); + file = fopen(path, "r"); + if (!file) { + free(path); + continue; + } + openedFile = TRUE; + + configFiles[numFiles].file = file; + configFiles[numFiles].path = path; + numFiles++; + } + + return openedFile; +} + +/* + * Given some searching parameters, locate and open the xorg config + * directory. The directory does not need to contain config files. + */ +static char * +OpenConfigDir(const char *path, const char *cmdline, const char *projroot, + const char *confname) +{ + char *dirpath, *pathcopy; + const char *template; + Bool found = FALSE; + int cmdlineUsed = 0; + + pathcopy = strdup(path); + for (template = strtok(pathcopy, ","); template && !found; + template = strtok(NULL, ",")) { + struct dirent **list = NULL; + int num; + + dirpath = DoSubstitution(template, cmdline, projroot, + &cmdlineUsed, NULL, confname); + if (!dirpath) + continue; + if (cmdline && !cmdlineUsed) { + free(dirpath); + dirpath = NULL; + continue; + } + + /* match files named *.conf */ + num = scandir(dirpath, &list, ConfigFilter, alphasort); + found = AddConfigDirFiles(dirpath, list, num); + if (!found) { + free(dirpath); + dirpath = NULL; + free(list); + } + } + + free(pathcopy); + return dirpath; +} + +/* + * xf86initConfigFiles -- Setup global variables and buffers. + */ +void +xf86initConfigFiles(void) +{ + curFileIndex = 0; + configPos = 0; + configLineNo = 0; + pushToken = LOCK_TOKEN; + + configBuf = malloc(CONFIG_BUF_LEN); + configRBuf = malloc(CONFIG_BUF_LEN); + configBuf[0] = '\0'; /* sanity ... */ +} + +/* + * xf86openConfigFile -- + * + * This function take a config file search path (optional), a command-line + * specified file name (optional) and the ProjectRoot path (optional) and + * locates and opens a config file based on that information. If a + * command-line file name is specified, then this function fails if none + * of the located files. + * + * The return value is a pointer to the actual name of the file that was + * opened. When no file is found, the return value is NULL. + * + * The escape sequences allowed in the search path are defined above. + * + */ + +#ifndef DEFAULT_CONF_PATH +#define DEFAULT_CONF_PATH "/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 + +const char * +xf86openConfigFile(const char *path, const char *cmdline, const char *projroot) +{ + if (!path || !path[0]) + path = DEFAULT_CONF_PATH; + if (!projroot || !projroot[0]) + projroot = PROJECTROOT; + + /* Search for a config file */ + configPath = OpenConfigFile(path, cmdline, projroot, XCONFIGFILE); + return configPath; +} + +/* + * xf86openConfigDirFiles -- + * + * This function take a config directory search path (optional), a + * command-line specified directory name (optional) and the ProjectRoot path + * (optional) and locates and opens a config directory based on that + * information. If a command-line name is specified, then this function + * fails if it is not found. + * + * The return value is a pointer to the actual name of the direcoty that was + * opened. When no directory is found, the return value is NULL. + * + * The escape sequences allowed in the search path are defined above. + * + */ +const char * +xf86openConfigDirFiles(const char *path, const char *cmdline, + const char *projroot) +{ + if (!path || !path[0]) + path = DEFAULT_CONF_PATH; + if (!projroot || !projroot[0]) + projroot = PROJECTROOT; + + /* Search for the multiconf directory */ + configDirPath = OpenConfigDir(path, cmdline, projroot, XCONFIGDIR); + return configDirPath; +} + +void +xf86closeConfigFile (void) +{ + int i; + + free (configPath); + configPath = NULL; + free (configDirPath); + configDirPath = NULL; + free (configRBuf); + configRBuf = NULL; + free (configBuf); + configBuf = NULL; + + if (numFiles == 0) { + builtinConfig = NULL; + builtinIndex = 0; + } + for (i = 0; i < numFiles; i++) { + fclose(configFiles[i].file); + configFiles[i].file = NULL; + free(configFiles[i].path); + configFiles[i].path = NULL; + } + numFiles = 0; +} + +void +xf86setBuiltinConfig(const char *config[]) +{ + builtinConfig = config; +} + +void +xf86parseError (char *format,...) +{ + va_list ap; + char *filename = numFiles ? configFiles[curFileIndex].path : + "<builtin configuration>"; + + ErrorF ("Parse error on line %d of section %s in file %s\n\t", + configLineNo, configSection, filename); + va_start (ap, format); + VErrorF (format, ap); + va_end (ap); + + ErrorF ("\n"); +} + +void +xf86validationError (char *format,...) +{ + va_list ap; + char *filename = numFiles ? configFiles[curFileIndex].path : + "<builtin configuration>"; + + ErrorF ("Data incomplete in file %s\n\t", filename); + va_start (ap, format); + VErrorF (format, ap); + va_end (ap); + + ErrorF ("\n"); +} + +void +xf86setSection (char *section) +{ + free(configSection); + configSection = strdup(section); +} + +/* + * xf86getToken -- + * Lookup a string if it is actually a token in disguise. + */ +int +xf86getStringToken (xf86ConfigSymTabRec * tab) +{ + return StringToToken (val.str, tab); +} + +static int +StringToToken (char *str, xf86ConfigSymTabRec * tab) +{ + int i; + + for (i = 0; tab[i].token != -1; i++) + { + if (!xf86nameCompare (tab[i].name, str)) + return tab[i].token; + } + return ERROR_TOKEN; +} + + +/* + * Compare two names. The characters '_', ' ', and '\t' are ignored + * in the comparison. + */ +int +xf86nameCompare (const char *s1, const char *s2) +{ + char c1, c2; + + if (!s1 || *s1 == 0) { + if (!s2 || *s2 == 0) + return 0; + else + return 1; + } + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + while (c1 == c2) + { + if (c1 == '\0') + return 0; + s1++; + s2++; + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + } + return c1 - c2; +} + +char * +xf86addComment(char *cur, char *add) +{ + char *str; + int len, curlen, iscomment, hasnewline = 0, insnewline, endnewline; + + if (add == NULL || add[0] == '\0') + return cur; + + if (cur) { + curlen = strlen(cur); + if (curlen) + hasnewline = cur[curlen - 1] == '\n'; + eol_seen = 0; + } + else + curlen = 0; + + str = add; + iscomment = 0; + while (*str) { + if (*str != ' ' && *str != '\t') + break; + ++str; + } + iscomment = (*str == '#'); + + len = strlen(add); + endnewline = add[len - 1] == '\n'; + + insnewline = eol_seen || (curlen && !hasnewline); + if (insnewline) + len++; + if (!iscomment) + len++; + if (!endnewline) + len++; + + /* Allocate + 1 char for '\0' terminator. */ + str = realloc(cur, curlen + len + 1); + if (!str) + return cur; + + cur = str; + + if (insnewline) + cur[curlen++] = '\n'; + if (!iscomment) + cur[curlen++] = '#'; + strcpy(cur + curlen, add); + if (!endnewline) + strcat(cur, "\n"); + + return cur; +} + +Bool +xf86getBoolValue(Bool *val, const char *str) +{ + if (!val || !str) + return FALSE; + if (*str == '\0') { + *val = TRUE; + } else { + if (xf86nameCompare(str, "1") == 0) + *val = TRUE; + else if (xf86nameCompare(str, "on") == 0) + *val = TRUE; + else if (xf86nameCompare(str, "true") == 0) + *val = TRUE; + else if (xf86nameCompare(str, "yes") == 0) + *val = TRUE; + else if (xf86nameCompare(str, "0") == 0) + *val = FALSE; + else if (xf86nameCompare(str, "off") == 0) + *val = FALSE; + else if (xf86nameCompare(str, "false") == 0) + *val = FALSE; + else if (xf86nameCompare(str, "no") == 0) + *val = FALSE; + else + return FALSE; + } + return TRUE; +} |