aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2011-11-04 08:57:20 +0100
committermarha <marha@users.sourceforge.net>2011-11-04 08:57:20 +0100
commit02f377d5e2dd18537d0807ad63675a0970b5a37d (patch)
tree1814c826db4d95a30ad71431d9c84b8d2611ec18 /xorg-server/hw
parent6f4feafd4d22beaabfb0202e66b0dea9047ee084 (diff)
downloadvcxsrv-02f377d5e2dd18537d0807ad63675a0970b5a37d.tar.gz
vcxsrv-02f377d5e2dd18537d0807ad63675a0970b5a37d.tar.bz2
vcxsrv-02f377d5e2dd18537d0807ad63675a0970b5a37d.zip
xserver pixman mesa git update 4 nov 2011
Diffstat (limited to 'xorg-server/hw')
-rw-r--r--xorg-server/hw/dmx/doc/dmx.xml9
-rw-r--r--xorg-server/hw/xfree86/common/xf86Cursor.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86RandR.c3
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c40
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.h1
-rw-r--r--xorg-server/hw/xfree86/common/xf86pciBus.c10
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.c2
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/alpha_video.c69
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/arm_video.c7
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/bsd_init.c1
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/i386_video.c5
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/ppc_video.c9
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/sparc64_video.c4
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_video.c1758
-rw-r--r--xorg-server/hw/xfree86/os-support/shared/bios_mmap.c278
-rw-r--r--xorg-server/hw/xfree86/os-support/xf86_OSlib.h23
-rw-r--r--xorg-server/hw/xfree86/parser/scan.c2343
-rw-r--r--xorg-server/hw/xquartz/applewm.c4
-rw-r--r--xorg-server/hw/xquartz/xpr/appledri.c4
-rw-r--r--xorg-server/hw/xwin/InitOutput.c66
-rw-r--r--xorg-server/hw/xwin/XWin.exe.manifest37
-rw-r--r--xorg-server/hw/xwin/ddraw.h2
-rw-r--r--xorg-server/hw/xwin/win.h3
-rw-r--r--xorg-server/hw/xwin/winclipboardwndproc.c48
-rw-r--r--xorg-server/hw/xwin/winglobals.c255
-rw-r--r--xorg-server/hw/xwin/winmonitors.c28
-rw-r--r--xorg-server/hw/xwin/winmultiwindowwndproc.c4
-rw-r--r--xorg-server/hw/xwin/winprocarg.c32
-rw-r--r--xorg-server/hw/xwin/winwin32rootlesswndproc.c2662
-rw-r--r--xorg-server/hw/xwin/winwindowswm.c4
-rw-r--r--xorg-server/hw/xwin/winwndproc.c4
31 files changed, 3765 insertions, 3952 deletions
diff --git a/xorg-server/hw/dmx/doc/dmx.xml b/xorg-server/hw/dmx/doc/dmx.xml
index ce472c2bf..845eec97a 100644
--- a/xorg-server/hw/dmx/doc/dmx.xml
+++ b/xorg-server/hw/dmx/doc/dmx.xml
@@ -967,17 +967,10 @@ event queue. It is simply passed the event to be queued.
</para>
<para>The cursor position should be updated when motion events are
-enqueued, by calling either miPointerAbsoluteCursor() or
-miPointerDeltaCursor():
+enqueued by calling miPointerDeltaCursor():
<variablelist>
<varlistentry>
-<term>miPointerAbsoluteCursor()</term>
-<listitem>
-<para>This MI function is used to move the
-cursor to the absolute coordinates provided.
-</para></listitem></varlistentry>
-<varlistentry>
<term>miPointerDeltaCursor()</term>
<listitem>
<para>This MI function is used to move the cursor
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;
+}
diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c
index 27fb125d3..55976c454 100644
--- a/xorg-server/hw/xquartz/applewm.c
+++ b/xorg-server/hw/xquartz/applewm.c
@@ -725,10 +725,12 @@ AppleWMExtensionInit(
NULL,
StandardMinorOpcode)))
{
+ size_t i;
WMReqCode = (unsigned char)extEntry->base;
WMErrorBase = extEntry->errorBase;
WMEventBase = extEntry->eventBase;
- EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
+ for (i=0; i < AppleWMNumberEvents; i++)
+ EventSwapVector[WMEventBase + i] = (EventSwapPtr) SNotifyEvent;
appleWMProcs = procsPtr;
}
}
diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c
index 6b4a8a383..44c132abc 100644
--- a/xorg-server/hw/xquartz/xpr/appledri.c
+++ b/xorg-server/hw/xquartz/xpr/appledri.c
@@ -529,9 +529,11 @@ AppleDRIExtensionInit(void)
SProcAppleDRIDispatch,
AppleDRIResetProc,
StandardMinorOpcode))) {
+ size_t i;
DRIReqCode = (unsigned char)extEntry->base;
DRIErrorBase = extEntry->errorBase;
DRIEventBase = extEntry->eventBase;
- EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent;
+ for (i=0; i < AppleDRINumberEvents; i++)
+ EventSwapVector[DRIEventBase + i] = (EventSwapPtr) SNotifyEvent;
}
}
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c
index 4fe5053b3..770439258 100644
--- a/xorg-server/hw/xwin/InitOutput.c
+++ b/xorg-server/hw/xwin/InitOutput.c
@@ -70,12 +70,6 @@ extern HWND g_hwndClipboard;
extern Bool g_fClipboard;
#endif
-
-/*
- module handle for dynamically loaded comctl32 library
-*/
-static HMODULE g_hmodCommonControls = NULL;
-
/*
* Function prototypes
*/
@@ -235,14 +229,6 @@ ddxGiveUp (enum ExitCode error)
* we are guaranteed to not need the DirectDraw functions.
*/
winReleaseDDProcAddresses();
-
- /* Unload our TrackMouseEvent function pointer */
- if (g_hmodCommonControls != NULL)
- {
- FreeLibrary (g_hmodCommonControls);
- g_hmodCommonControls = NULL;
- g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
- }
/* Free concatenated command line */
free(g_pszCommandLine);
@@ -602,34 +588,17 @@ winFixupPaths (void)
}
if (getenv("HOME") == NULL)
{
- HMODULE shfolder;
- SHGETFOLDERPATHPROC shgetfolderpath = NULL;
char buffer[MAX_PATH + 5];
strncpy(buffer, "HOME=", 5);
- /* Try to load SHGetFolderPath from shfolder.dll and shell32.dll */
-
- shfolder = LoadLibrary("shfolder.dll");
- /* fallback to shell32.dll */
- if (shfolder == NULL)
- shfolder = LoadLibrary("shell32.dll");
-
- /* resolve SHGetFolderPath */
- if (shfolder != NULL)
- shgetfolderpath = (SHGETFOLDERPATHPROC)GetProcAddress(shfolder, "SHGetFolderPathA");
-
/* query appdata directory */
- if (shgetfolderpath &&
- shgetfolderpath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0,
- buffer + 5) == 0)
- {
+ if (SHGetFolderPathA(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, buffer + 5) == 0)
+ {
putenv(buffer);
} else
{
winMsg (X_ERROR, "Can not determine HOME directory\n");
- }
- if (shfolder != NULL)
- FreeLibrary(shfolder);
+ }
}
if (!g_fLogFileChanged) {
static char buffer[MAX_PATH];
@@ -839,10 +808,10 @@ winUseMsg (void)
"\theight and initial position for that screen. Additionally\n"
"\ta monitor number can be specified to start the server on,\n"
"\tat which point, all coordinates become relative to that\n"
- "\tmonitor (Not for Windows NT4 and 95). Examples:\n"
- "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n"
- "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n"
- "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
+ "\tmonitor. Examples:\n"
+ "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n"
+ "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n"
+ "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
ErrorF ("-silent-dup-error\n"
"\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n"
@@ -979,27 +948,6 @@ InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
/* Detect supported engines */
winDetectSupportedEngines ();
- /* Load common controls library */
- g_hmodCommonControls = LoadLibraryEx ("comctl32.dll", NULL, 0);
-
- /* Load TrackMouseEvent function pointer */
- g_fpTrackMouseEvent = GetProcAddress (g_hmodCommonControls,
- "_TrackMouseEvent");
- if (g_fpTrackMouseEvent == NULL)
- {
- winErrorFVerb (1, "InitOutput - Could not get pointer to function\n"
- "\t_TrackMouseEvent in comctl32.dll. Try installing\n"
- "\tInternet Explorer 3.0 or greater if you have not\n"
- "\talready.\n");
-
- /* Free the library since we won't need it */
- FreeLibrary (g_hmodCommonControls);
- g_hmodCommonControls = NULL;
-
- /* Set function pointer to point to no operation function */
- g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
- }
-
/* Store the instance handle */
g_hInstance = GetModuleHandle (NULL);
diff --git a/xorg-server/hw/xwin/XWin.exe.manifest b/xorg-server/hw/xwin/XWin.exe.manifest
index 5668383a9..a0d4d7dae 100644
--- a/xorg-server/hw/xwin/XWin.exe.manifest
+++ b/xorg-server/hw/xwin/XWin.exe.manifest
@@ -1,16 +1,21 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
- <description>The XWin X Windows server for Cygwin.</description>
- <dependency>
- <dependentAssembly>
- <assemblyIdentity
- type="win32"
- name="Microsoft.Windows.Common-Controls"
- version="6.0.0.0"
- processorArchitecture="X86"
- publicKeyToken="6595b64144ccf1df"
- language="*"
- />
- </dependentAssembly>
- </dependency>
-</assembly>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <description>The XWin X Windows server for Cygwin.</description>
+ <dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="X86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+ </dependency>
+ <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+</assembly>
diff --git a/xorg-server/hw/xwin/ddraw.h b/xorg-server/hw/xwin/ddraw.h
index 2eb7c2674..9d87b2b95 100644
--- a/xorg-server/hw/xwin/ddraw.h
+++ b/xorg-server/hw/xwin/ddraw.h
@@ -1449,7 +1449,7 @@ DECLARE_INTERFACE_(IDirectDraw4,IUnknown)
#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c))
/*** IDirectDraw4 methods ***/
#define IDirectDraw4_GetSurfaceFromDC(p,a,b) ICOM_CALL_(GetSurfaceFromDC,p,(p,a,b))
-#define IDirectDraw4_RestoreAllSurfaces(pc) ICOM_CALL_(RestoreAllSurfaces,p,(p))
+#define IDirectDraw4_RestoreAllSurfaces(p) ICOM_CALL_(RestoreAllSurfaces,p,(p))
#define IDirectDraw4_TestCooperativeLevel(p) ICOM_CALL_(TestCooperativeLevel,p,(p))
#define IDirectDraw4_GetDeviceIdentifier(p,a,b) ICOM_CALL_(GetDeviceIdentifier,p,(p,a,b))
diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h
index 9bee9b64f..e2e946fb5 100644
--- a/xorg-server/hw/xwin/win.h
+++ b/xorg-server/hw/xwin/win.h
@@ -64,7 +64,7 @@
#define WIN_DEFAULT_BLACKPIXEL 0
#define WIN_DEFAULT_LINEBIAS 0
#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */
-#define WIN_DEFAULT_DPI 75
+#define WIN_DEFAULT_DPI 96
#define WIN_DEFAULT_REFRESH 0
#define WIN_DEFAULT_WIN_KILL TRUE
#define WIN_DEFAULT_UNIX_KILL FALSE
@@ -673,7 +673,6 @@ extern DeviceIntPtr g_pwinKeyboard;
extern FARPROC g_fpDirectDrawCreate;
extern FARPROC g_fpDirectDrawCreateClipper;
-extern FARPROC g_fpTrackMouseEvent;
/*
diff --git a/xorg-server/hw/xwin/winclipboardwndproc.c b/xorg-server/hw/xwin/winclipboardwndproc.c
index 9394b04db..03da7f41c 100644
--- a/xorg-server/hw/xwin/winclipboardwndproc.c
+++ b/xorg-server/hw/xwin/winclipboardwndproc.c
@@ -56,8 +56,6 @@ extern void *g_pClipboardDisplay;
extern Window g_iClipboardWindow;
extern Atom g_atomLastOwnedSelection;
-/* BPS - g_hwndClipboard needed for X app->Windows paste fix */
-extern HWND g_hwndClipboard;
/*
* Local function prototypes
@@ -143,12 +141,6 @@ winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay,
* Process a given Windows message
*/
-/* BPS - Define our own message, which we'll post to ourselves to facilitate
- * resetting the delayed rendering mechanism after each paste from X app to
- * Windows app. TODO - Perhaps move to win.h with the other WM_USER messages.
- */
-#define WM_USER_PASTE_COMPLETE (WM_USER + 1003)
-
LRESULT CALLBACK
winClipboardWindowProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
@@ -343,6 +335,8 @@ winClipboardWindowProc (HWND hwnd, UINT message,
* previous XSetSelectionOwner messages.
*/
XSync (pDisplay, FALSE);
+
+ winDebug("winClipboardWindowProc - XSync done.\n");
/* Release PRIMARY selection if owned */
iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY);
@@ -540,13 +534,6 @@ winClipboardWindowProc (HWND hwnd, UINT message,
ErrorF("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
}
- /* BPS - Post ourselves a user message whose handler will reset the
- * delayed rendering mechanism after the paste is complete. This is
- * necessary because calling SetClipboardData() with a NULL argument
- * here will cause the data we just put on the clipboard to be lost!
- */
- PostMessage(g_hwndClipboard, WM_USER_PASTE_COMPLETE, 0, 0);
-
/* Special handling for WM_RENDERALLFORMATS */
if (message == WM_RENDERALLFORMATS)
{
@@ -564,37 +551,6 @@ winClipboardWindowProc (HWND hwnd, UINT message,
winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
return 0;
}
- /* BPS - This WM_USER message is posted by us. It gives us the opportunity
- * to reset the delayed rendering mechanism after each and every paste
- * from an X app to a Windows app. Without such a mechanism, subsequent
- * changes of selection in the X app owning the selection are not
- * reflected in pastes into Windows apps, since Windows won't send us the
- * WM_RENDERFORMAT message unless someone has set changed data (or NULL)
- * on the clipboard. */
- case WM_USER_PASTE_COMPLETE:
- {
- if (hwnd != GetClipboardOwner ())
- /* In case we've lost the selection since posting the message */
- return 0;
- winDebug ("winClipboardWindowProc - WM_USER_PASTE_COMPLETE\n");
-
- /* Set up for another delayed rendering callback */
- OpenClipboard (g_hwndClipboard);
-
- /* Take ownership of the Windows clipboard */
- EmptyClipboard ();
-
- /* Advertise Unicode if we support it */
- if (g_fUnicodeSupport)
- SetClipboardData (CF_UNICODETEXT, NULL);
-
- /* Always advertise regular text */
- SetClipboardData (CF_TEXT, NULL);
-
- /* Release the clipboard */
- CloseClipboard ();
- }
- return 0;
}
/* Let Windows perform default processing for unhandled messages */
diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c
index 80d946c5d..631f12e21 100644
--- a/xorg-server/hw/xwin/winglobals.c
+++ b/xorg-server/hw/xwin/winglobals.c
@@ -1,131 +1,124 @@
-/*
- *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
- *Copyright (C) Colin Harrison 2005-2008
- *
- *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 HAROLD L HUNT II 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 Harold L Hunt II
- *shall not be used in advertising or otherwise to promote the sale, use
- *or other dealings in this Software without prior written authorization
- *from Harold L Hunt II.
- *
- * Authors: Harold L Hunt II
- * Colin Harrison
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-
-
-/*
- * General global variables
- */
-
-int g_iNumScreens = 0;
-winScreenInfo * g_ScreenInfo = 0;
-#ifdef HAS_DEVWINDOWS
-int g_fdMessageQueue = WIN_FD_INVALID;
-#endif
-DevPrivateKeyRec g_iScreenPrivateKeyRec;
-DevPrivateKeyRec g_iCmapPrivateKeyRec;
-DevPrivateKeyRec g_iGCPrivateKeyRec;
-DevPrivateKeyRec g_iPixmapPrivateKeyRec;
-DevPrivateKeyRec g_iWindowPrivateKeyRec;
-unsigned long g_ulServerGeneration = 0;
-DWORD g_dwEnginesSupported = 0;
-HINSTANCE g_hInstance = 0;
-HWND g_hDlgDepthChange = NULL;
-HWND g_hDlgExit = NULL;
-HWND g_hDlgAbout = NULL;
-const char * g_pszQueryHost = NULL;
-Bool g_fXdmcpEnabled = FALSE;
-Bool g_fAuthEnabled = FALSE;
-HICON g_hIconX = NULL;
-HICON g_hSmallIconX = NULL;
-#ifndef RELOCATE_PROJECTROOT
-const char * g_pszLogFile = DEFAULT_LOGDIR "/XWin.%s.log";
-#else
-const char * g_pszLogFile = "XWin.log";
-Bool g_fLogFileChanged = FALSE;
-#endif
-int g_iLogVerbose = 2;
-Bool g_fLogInited = FALSE;
-char * g_pszCommandLine = NULL;
-Bool g_fSilentFatalError = FALSE;
-DWORD g_dwCurrentThreadID = 0;
-Bool g_fKeyboardHookLL = FALSE;
-Bool g_fNoHelpMessageBox = FALSE;
-Bool g_fSoftwareCursor = FALSE;
-Bool g_fSilentDupError = FALSE;
-Bool g_fNativeGl = FALSE;
-
-/*
- * Global variables for dynamically loaded libraries and
- * their function pointers
- */
-
-FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
-
-
-#ifdef XWIN_CLIPBOARD
-/*
- * Wrapped DIX functions
- */
-winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
-winDispatchProcPtr winProcQueryTreeOrig = NULL;
-winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
-
-
-/*
- * Clipboard variables
- */
-
-Bool g_fUnicodeClipboard = TRUE;
-Bool g_fClipboard = TRUE;
-Bool g_fClipboardLaunched = FALSE;
-Bool g_fClipboardStarted = FALSE;
-pthread_t g_ptClipboardProc;
-HWND g_hwndClipboard = NULL;
-void *g_pClipboardDisplay = NULL;
-Window g_iClipboardWindow = None;
-Atom g_atomLastOwnedSelection = None;
-#endif
-
-
-/*
- * Re-initialize global variables that are invalidated
- * by a server reset.
- */
-
-void
-winInitializeGlobals (void)
-{
- g_dwCurrentThreadID = GetCurrentThreadId ();
-#ifdef XWIN_CLIPBOARD
- g_fClipboardLaunched = FALSE;
- g_fClipboardStarted = FALSE;
- g_iClipboardWindow = None;
- g_pClipboardDisplay = NULL;
- g_atomLastOwnedSelection = None;
- g_hwndClipboard = NULL;
-#endif
-}
+/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * General global variables
+ */
+
+int g_iNumScreens = 0;
+winScreenInfo * g_ScreenInfo = 0;
+#ifdef HAS_DEVWINDOWS
+int g_fdMessageQueue = WIN_FD_INVALID;
+#endif
+DevPrivateKeyRec g_iScreenPrivateKeyRec;
+DevPrivateKeyRec g_iCmapPrivateKeyRec;
+DevPrivateKeyRec g_iGCPrivateKeyRec;
+DevPrivateKeyRec g_iPixmapPrivateKeyRec;
+DevPrivateKeyRec g_iWindowPrivateKeyRec;
+unsigned long g_ulServerGeneration = 0;
+DWORD g_dwEnginesSupported = 0;
+HINSTANCE g_hInstance = 0;
+HWND g_hDlgDepthChange = NULL;
+HWND g_hDlgExit = NULL;
+HWND g_hDlgAbout = NULL;
+const char * g_pszQueryHost = NULL;
+Bool g_fXdmcpEnabled = FALSE;
+Bool g_fAuthEnabled = FALSE;
+HICON g_hIconX = NULL;
+HICON g_hSmallIconX = NULL;
+#ifndef RELOCATE_PROJECTROOT
+const char * g_pszLogFile = DEFAULT_LOGDIR "/XWin.%s.log";
+#else
+const char * g_pszLogFile = "XWin.log";
+Bool g_fLogFileChanged = FALSE;
+#endif
+int g_iLogVerbose = 2;
+Bool g_fLogInited = FALSE;
+char * g_pszCommandLine = NULL;
+Bool g_fSilentFatalError = FALSE;
+DWORD g_dwCurrentThreadID = 0;
+Bool g_fKeyboardHookLL = FALSE;
+Bool g_fNoHelpMessageBox = FALSE;
+Bool g_fSoftwareCursor = FALSE;
+Bool g_fSilentDupError = FALSE;
+Bool g_fNativeGl = FALSE;
+
+
+#ifdef XWIN_CLIPBOARD
+/*
+ * Wrapped DIX functions
+ */
+winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
+winDispatchProcPtr winProcQueryTreeOrig = NULL;
+winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
+
+
+/*
+ * Clipboard variables
+ */
+
+Bool g_fUnicodeClipboard = TRUE;
+Bool g_fClipboard = TRUE;
+Bool g_fClipboardLaunched = FALSE;
+Bool g_fClipboardStarted = FALSE;
+pthread_t g_ptClipboardProc;
+HWND g_hwndClipboard = NULL;
+void *g_pClipboardDisplay = NULL;
+Window g_iClipboardWindow = None;
+Atom g_atomLastOwnedSelection = None;
+#endif
+
+
+/*
+ * Re-initialize global variables that are invalidated
+ * by a server reset.
+ */
+
+void
+winInitializeGlobals (void)
+{
+ g_dwCurrentThreadID = GetCurrentThreadId ();
+#ifdef XWIN_CLIPBOARD
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_atomLastOwnedSelection = None;
+ g_hwndClipboard = NULL;
+#endif
+}
diff --git a/xorg-server/hw/xwin/winmonitors.c b/xorg-server/hw/xwin/winmonitors.c
index a9d46f90e..967ae6d35 100644
--- a/xorg-server/hw/xwin/winmonitors.c
+++ b/xorg-server/hw/xwin/winmonitors.c
@@ -53,30 +53,8 @@ wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _d
return TRUE;
}
-typedef WINAPI wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
-ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors;
-
-wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data);
-
Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
{
- /* Load EnumDisplayMonitors from DLL */
- HMODULE user32;
- FARPROC func;
- user32 = LoadLibrary("user32.dll");
- if (user32 == NULL)
- {
- winW32Error(2, "Could not open user32.dll");
- return FALSE;
- }
- func = GetProcAddress(user32, "EnumDisplayMonitors");
- if (func == NULL)
- {
- winW32Error(2, "Could not resolve EnumDisplayMonitors: ");
- return FALSE;
- }
- _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func;
-
/* prepare data */
if (data == NULL)
return FALSE;
@@ -84,9 +62,5 @@ Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
data->requestedMonitor = index;
/* query information */
- _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
-
- /* cleanup */
- FreeLibrary(user32);
- return TRUE;
+ return EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
}
diff --git a/xorg-server/hw/xwin/winmultiwindowwndproc.c b/xorg-server/hw/xwin/winmultiwindowwndproc.c
index fb1938b3a..3d23e9746 100644
--- a/xorg-server/hw/xwin/winmultiwindowwndproc.c
+++ b/xorg-server/hw/xwin/winmultiwindowwndproc.c
@@ -549,8 +549,8 @@ winTopLevelWindowProc (HWND hwnd, UINT message,
tme.hwndTrack = hwnd;
/* Call the tracking function */
- if (!(*g_fpTrackMouseEvent) (&tme))
- ErrorF ("winTopLevelWindowProc - _TrackMouseEvent failed\n");
+ if (!TrackMouseEvent(&tme))
+ ErrorF ("winTopLevelWindowProc - TrackMouseEvent failed\n");
/* Flag that we are tracking now */
s_fTracking = TRUE;
diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c
index ddfe1f5b7..2b6949ed1 100644
--- a/xorg-server/hw/xwin/winprocarg.c
+++ b/xorg-server/hw/xwin/winprocarg.c
@@ -88,12 +88,27 @@ winInitializeScreenDefaults(void)
dwWidth = GetSystemMetrics (SM_CXSCREEN);
dwHeight = GetSystemMetrics (SM_CYSCREEN);
- winErrorFVerb (2, "winInitializeScreenDefaults - w %d h %d\n",
- (int) dwWidth, (int) dwHeight);
+ winErrorFVerb(2, "winInitializeScreenDefaults - primary monitor w %d h %d\n", (int) dwWidth, (int) dwHeight);
- /* Set a default DPI, if no parameter was passed */
+ /* Set a default DPI, if no '-dpi' option was used */
if (monitorResolution == 0)
- monitorResolution = WIN_DEFAULT_DPI;
+ {
+ HDC hdc = GetDC(NULL);
+ if (hdc)
+ {
+ int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
+ int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
+
+ winErrorFVerb(2, "winInitializeDefaultScreens - native DPI x %d y %d\n", dpiX, dpiY);
+ monitorResolution = dpiY;
+ ReleaseDC(NULL, hdc);
+ }
+ else
+ {
+ winErrorFVerb(1, "winInitializeDefaultScreens - Failed to retrieve native DPI, falling back to default of %d DPI\n", WIN_DEFAULT_DPI);
+ monitorResolution = WIN_DEFAULT_DPI;
+ }
+ }
defaultScreenInfo.iMonitor = 1;
defaultScreenInfo.dwWidth = dwWidth;
@@ -311,8 +326,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data))
{
- ErrorF ("ddxProcessArgument - screen - "
- "Querying monitors is not supported on NT4 and Win95\n");
+ ErrorF ("ddxProcessArgument - screen - Querying monitors failed\n");
} else if (data.bMonitorSpecifiedExists == TRUE)
{
winErrorFVerb(2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
@@ -368,8 +382,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data))
{
- ErrorF ("ddxProcessArgument - screen - "
- "Querying monitors is not supported on NT4 and Win95\n");
+ ErrorF ("ddxProcessArgument - screen - Querying monitors failed\n");
} else if (data.bMonitorSpecifiedExists == TRUE)
{
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
@@ -396,8 +409,7 @@ ddxProcessArgument (int argc, char *argv[], int i)
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data))
{
- ErrorF ("ddxProcessArgument - screen - "
- "Querying monitors is not supported on NT4 and Win95\n");
+ ErrorF ("ddxProcessArgument - screen - Querying monitors failed\n");
} else if (data.bMonitorSpecifiedExists == TRUE)
{
winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
diff --git a/xorg-server/hw/xwin/winwin32rootlesswndproc.c b/xorg-server/hw/xwin/winwin32rootlesswndproc.c
index 47a1abe73..c60a76cba 100644
--- a/xorg-server/hw/xwin/winwin32rootlesswndproc.c
+++ b/xorg-server/hw/xwin/winwin32rootlesswndproc.c
@@ -1,1331 +1,1331 @@
-/*
- *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
- *
- *Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- *"Software"), to deal in the Software without restriction, including
- *without limitation the rights to use, copy, modify, merge, publish,
- *distribute, sublicense, and/or sell copies of the Software, and to
- *permit persons to whom the Software is furnished to do so, subject to
- *the following conditions:
- *
- *The above copyright notice and this permission notice shall be
- *included in all copies or substantial portions of the Software.
- *
- *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT 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 XFree86 Project
- *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 XFree86 Project.
- *
- * Authors: Kensuke Matsuzaki
- * Earle F. Philhower, III
- * Harold L Hunt II
- */
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <winuser.h>
-#define _WINDOWSWM_SERVER_
-#include <X11/extensions/windowswmstr.h>
-#include "dixevents.h"
-#include "propertyst.h"
-#include <X11/Xatom.h>
-#include "winmultiwindowclass.h"
-#include "winmsg.h"
-#include "inputstr.h"
-
-
-/*
- * Constant defines
- */
-
-#define MOUSE_ACTIVATE_DEFAULT TRUE
-#define RAISE_ON_CLICK_DEFAULT FALSE
-
-
-/*
- * Local globals
- */
-
-static UINT_PTR g_uipMousePollingTimerID = 0;
-
-
-/*
- * Local function
- */
-
-DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK)
-DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
-/* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
-
-/*
- * ConstrainSize - Taken from TWM sources - Respects hints for sizing
- */
-#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
-static void
-ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp)
-{
- int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
- int baseWidth, baseHeight;
- int dwidth = *widthp, dheight = *heightp;
-
- if (hints.flags & PMinSize)
- {
- minWidth = hints.min_width;
- minHeight = hints.min_height;
- }
- else if (hints.flags & PBaseSize)
- {
- minWidth = hints.base_width;
- minHeight = hints.base_height;
- }
- else
- minWidth = minHeight = 1;
-
- if (hints.flags & PBaseSize)
- {
- baseWidth = hints.base_width;
- baseHeight = hints.base_height;
- }
- else if (hints.flags & PMinSize)
- {
- baseWidth = hints.min_width;
- baseHeight = hints.min_height;
- }
- else
- baseWidth = baseHeight = 0;
-
- if (hints.flags & PMaxSize)
- {
- maxWidth = hints.max_width;
- maxHeight = hints.max_height;
- }
- else
- {
- maxWidth = MAXINT;
- maxHeight = MAXINT;
- }
-
- if (hints.flags & PResizeInc)
- {
- xinc = hints.width_inc;
- yinc = hints.height_inc;
- }
- else
- xinc = yinc = 1;
-
- /*
- * First, clamp to min and max values
- */
- if (dwidth < minWidth)
- dwidth = minWidth;
- if (dheight < minHeight)
- dheight = minHeight;
-
- if (dwidth > maxWidth)
- dwidth = maxWidth;
- if (dheight > maxHeight)
- dheight = maxHeight;
-
- /*
- * Second, fit to base + N * inc
- */
- dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
- dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
-
- /*
- * Third, adjust for aspect ratio
- */
-
- /*
- * The math looks like this:
- *
- * minAspectX dwidth maxAspectX
- * ---------- <= ------- <= ----------
- * minAspectY dheight maxAspectY
- *
- * If that is multiplied out, then the width and height are
- * invalid in the following situations:
- *
- * minAspectX * dheight > minAspectY * dwidth
- * maxAspectX * dheight < maxAspectY * dwidth
- *
- */
-
- if (hints.flags & PAspect)
- {
- if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth)
- {
- delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc);
- if (dwidth + delta <= maxWidth)
- dwidth += delta;
- else
- {
- delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc);
- if (dheight - delta >= minHeight)
- dheight -= delta;
- }
- }
-
- if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth)
- {
- delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc);
- if (dheight + delta <= maxHeight)
- dheight += delta;
- else
- {
- delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc);
- if (dwidth - delta >= minWidth)
- dwidth -= delta;
- }
- }
- }
-
- /* Return computed values */
- *widthp = dwidth;
- *heightp = dheight;
-}
-#undef makemult
-
-
-
-/*
- * ValidateSizing - Ensures size request respects hints
- */
-static int
-ValidateSizing (HWND hwnd, WindowPtr pWin,
- WPARAM wParam, LPARAM lParam)
-{
- WinXSizeHints sizeHints;
- RECT *rect;
- int iWidth, iHeight, iTopBorder;
- POINT pt;
-
- /* Invalid input checking */
- if (pWin==NULL || lParam==0)
- {
- ErrorF ("Invalid input checking\n");
- return FALSE;
- }
-
- /* No size hints, no checking */
- if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints))
- {
- ErrorF ("No size hints, no checking\n");
- return FALSE;
- }
-
- /* Avoid divide-by-zero */
- if (sizeHints.flags & PResizeInc)
- {
- if (sizeHints.width_inc == 0) sizeHints.width_inc = 1;
- if (sizeHints.height_inc == 0) sizeHints.height_inc = 1;
- }
-
- rect = (RECT*)lParam;
-
- iWidth = rect->right - rect->left;
- iHeight = rect->bottom - rect->top;
-
- /* Get title bar height, there must be an easier way?! */
- pt.x = pt.y = 0;
- ClientToScreen(hwnd, &pt);
- iTopBorder = pt.y - rect->top;
-
- /* Now remove size of any borders */
- iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
- iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
-
- /* Constrain the size to legal values */
- ConstrainSize (sizeHints, &iWidth, &iHeight);
-
- /* Add back the borders */
- iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
- iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
-
- /* Adjust size according to where we're dragging from */
- switch(wParam) {
- case WMSZ_TOP:
- case WMSZ_TOPRIGHT:
- case WMSZ_BOTTOM:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_RIGHT:
- rect->right = rect->left + iWidth;
- break;
- default:
- rect->left = rect->right - iWidth;
- break;
- }
- switch(wParam) {
- case WMSZ_BOTTOM:
- case WMSZ_BOTTOMRIGHT:
- case WMSZ_BOTTOMLEFT:
- case WMSZ_RIGHT:
- case WMSZ_LEFT:
- rect->bottom = rect->top + iHeight;
- break;
- default:
- rect->top = rect->bottom - iHeight;
- break;
- }
- return TRUE;
-}
-
-
-/*
- * IsRaiseOnClick
- */
-
-static Bool
-IsRaiseOnClick (WindowPtr pWin)
-{
-
- struct _Window *pwin;
- struct _Property *prop;
- /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
- * Which pointer's current window do we want? */
- WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer);
-
- if (!pWin)
- {
- ErrorF ("IsRaiseOnClick - no prop use default value:%d\n",
- RAISE_ON_CLICK_DEFAULT);
- return RAISE_ON_CLICK_DEFAULT;
- }
-
- pwin = (struct _Window*) pWin;
-
- if (pwin->optional)
- prop = (struct _Property *) pwin->optional->userProps;
- else
- prop = NULL;
-
- while (prop)
- {
- if (prop->propertyName == AtmWindowsWmRaiseOnClick ()
- && prop->type == XA_INTEGER
- && prop->format == 32)
- {
- return *(int*)prop->data;
- }
- else
- prop = prop->next;
- }
-
- if (pWin != pRoot)
- {
- return IsRaiseOnClick (pRoot);
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("IsRaiseOnClick - no prop use default value:%d\n",
- RAISE_ON_CLICK_DEFAULT);
-#endif
- return RAISE_ON_CLICK_DEFAULT;
- }
-}
-
-
-/*
- * IsMouseActive
- */
-
-static Bool
-IsMouseActive (WindowPtr pWin)
-{
-
- struct _Window *pwin;
- struct _Property *prop;
- /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
- * Which pointer's current window do we want? */
- WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer);
-
- if (!pWin)
- {
- ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n",
- MOUSE_ACTIVATE_DEFAULT);
- return MOUSE_ACTIVATE_DEFAULT;
- }
-
- pwin = (struct _Window*) pWin;
-
- if (pwin->optional)
- prop = (struct _Property *) pwin->optional->userProps;
- else
- prop = NULL;
-
- while (prop)
- {
- if (prop->propertyName == AtmWindowsWMMouseActivate ()
- && prop->type == XA_INTEGER
- && prop->format == 32)
- {
- return *(int*)prop->data;
- }
- else
- prop = prop->next;
- }
-
- if (pWin != pRoot)
- {
- return IsMouseActive (pRoot);
- }
- else
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("IsMouseActive - no prop use default value:%d\n",
- MOUSE_ACTIVATE_DEFAULT);
-#endif
- return MOUSE_ACTIVATE_DEFAULT;
- }
-}
-
-
-/*
- * winMWExtWMWindowProc - Window procedure
- */
-
-LRESULT CALLBACK
-winMWExtWMWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- WindowPtr pWin = NULL;
- win32RootlessWindowPtr pRLWinPriv = NULL;
- ScreenPtr pScreen = NULL;
- winPrivScreenPtr pScreenPriv = NULL;
- winScreenInfo *pScreenInfo = NULL;
- HWND hwndScreen = NULL;
- POINT ptMouse;
- static Bool s_fTracking = FALSE;
- HDC hdcUpdate;
- PAINTSTRUCT ps;
- LPWINDOWPOS pWinPos = NULL;
- RECT rcClient;
- winWMMessageRec wmMsg;
- Bool fWMMsgInitialized = FALSE;
-
- /* Check if the Windows window property for our X window pointer is valid */
- if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
- {
- pWin = pRLWinPriv->pFrame->win;
- pScreen = pWin->drawable.pScreen;
- if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
- if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
- if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen;
-
- wmMsg.msg = 0;
- wmMsg.hwndWindow = hwnd;
- wmMsg.iWindow = (Window)pWin->drawable.id;
-
- wmMsg.iX = pRLWinPriv->pFrame->x;
- wmMsg.iY = pRLWinPriv->pFrame->y;
- wmMsg.iWidth = pRLWinPriv->pFrame->width;
- wmMsg.iHeight = pRLWinPriv->pFrame->height;
-
- fWMMsgInitialized = TRUE;
-#if CYGDEBUG
- winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);
-
- winDebug ("\thWnd %08X\n", hwnd);
- winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
- winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
- winDebug ("\thwndScreen %08X\n", hwndScreen);
- winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
- pRLWinPriv, message, wParam, lParam);
-#endif
- }
- /* Branch on message type */
- switch (message)
- {
- case WM_CREATE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
-#endif
- /* */
- SetProp (hwnd,
- WIN_WINDOW_PROP,
- (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
- return 0;
-
- case WM_CLOSE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
-#endif
- /* Tell window-manager to close window */
- if (pRLWinPriv->fClose)
- {
- DestroyWindow (hwnd);
- }
- else
- {
- if (winIsInternalWMRunning(pScreenInfo))
- {
- /* Tell our Window Manager thread to kill the window */
- wmMsg.msg = WM_WM_KILL;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMCloseWindow,
- pWin->drawable.id,
- 0, 0, 0, 0);
- }
- return 0;
-
- case WM_DESTROY:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
-#endif
- /* Free the shaodw DC; which allows the bitmap to be freed */
- DeleteDC (pRLWinPriv->hdcShadow);
- pRLWinPriv->hdcShadow = NULL;
-
- /* Free the shadow bitmap */
- DeleteObject (pRLWinPriv->hbmpShadow);
- pRLWinPriv->hbmpShadow = NULL;
-
- /* Free the screen DC */
- ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
- pRLWinPriv->hdcScreen = NULL;
-
- /* Free shadow buffer info header */
- free (pRLWinPriv->pbmihShadow);
- pRLWinPriv->pbmihShadow = NULL;
-
- pRLWinPriv->fResized = FALSE;
- pRLWinPriv->pfb = NULL;
- free (pRLWinPriv);
- RemoveProp (hwnd, WIN_WINDOW_PROP);
- break;
-
- case WM_MOUSEMOVE:
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
-#endif
- /* Unpack the client area mouse coordinates */
- ptMouse.x = GET_X_LPARAM(lParam);
- ptMouse.y = GET_Y_LPARAM(lParam);
-
- /* Translate the client area mouse coordinates to screen coordinates */
- ClientToScreen (hwnd, &ptMouse);
-
- /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
- ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
- ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
-
- /* We can't do anything without privates */
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
-
- /* Has the mouse pointer crossed screens? */
- if (pScreen != miPointerGetScreen(inputInfo.pointer))
- miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen,
- ptMouse.x - pScreenInfo->dwXOffset,
- ptMouse.y - pScreenInfo->dwYOffset);
-
- /* Are we tracking yet? */
- if (!s_fTracking)
- {
- TRACKMOUSEEVENT tme;
-
- /* Setup data structure */
- ZeroMemory (&tme, sizeof (tme));
- tme.cbSize = sizeof (tme);
- tme.dwFlags = TME_LEAVE;
- tme.hwndTrack = hwnd;
-
- /* Call the tracking function */
- if (!(*g_fpTrackMouseEvent) (&tme))
- ErrorF ("winMWExtWMWindowProc - _TrackMouseEvent failed\n");
-
- /* Flag that we are tracking now */
- s_fTracking = TRUE;
- }
-
- /* Kill the timer used to poll mouse events */
- if (g_uipMousePollingTimerID != 0)
- {
- KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
- g_uipMousePollingTimerID = 0;
- }
-
- /* Deliver absolute cursor position to X Server */
- winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
- ptMouse.y - pScreenInfo->dwYOffset);
-
- return 0;
-
- case WM_NCMOUSEMOVE:
-#if CYGMULTIWINDOW_DEBUG && 0
- winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
-#endif
- /*
- * We break instead of returning 0 since we need to call
- * DefWindowProc to get the mouse cursor changes
- * and min/max/close button highlighting in Windows XP.
- * The Platform SDK says that you should return 0 if you
- * process this message, but it fails to mention that you
- * will give up any default functionality if you do return 0.
- */
-
- /* We can't do anything without privates */
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
-
- /*
- * Timer to poll mouse events. This is needed to make
- * programs like xeyes follow the mouse properly.
- */
- if (g_uipMousePollingTimerID == 0)
- g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
- WIN_POLLING_MOUSE_TIMER_ID,
- MOUSE_POLLING_INTERVAL,
- NULL);
- break;
-
- case WM_MOUSELEAVE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
-#endif
- /* Mouse has left our client area */
-
- /* Flag that we are no longer tracking */
- s_fTracking = FALSE;
-
- /*
- * Timer to poll mouse events. This is needed to make
- * programs like xeyes follow the mouse properly.
- */
- if (g_uipMousePollingTimerID == 0)
- g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
- WIN_POLLING_MOUSE_TIMER_ID,
- MOUSE_POLLING_INTERVAL,
- NULL);
- return 0;
-
- case WM_LBUTTONDBLCLK:
- case WM_LBUTTONDOWN:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- SetCapture (hwnd);
- return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
-
- case WM_LBUTTONUP:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- ReleaseCapture ();
- return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);
-
- case WM_MBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- SetCapture (hwnd);
- return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
-
- case WM_MBUTTONUP:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- ReleaseCapture ();
- return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
-
- case WM_RBUTTONDBLCLK:
- case WM_RBUTTONDOWN:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- SetCapture (hwnd);
- return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
-
- case WM_RBUTTONUP:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
-#endif
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- ReleaseCapture ();
- return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);
-
- case WM_XBUTTONDBLCLK:
- case WM_XBUTTONDOWN:
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- SetCapture (hwnd);
- return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
- case WM_XBUTTONUP:
- if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
- break;
- ReleaseCapture ();
- return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
-
- case WM_MOUSEWHEEL:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
-#endif
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
-
- case WM_MOUSEACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
-#endif
-#if 1
- /* Check if this window needs to be made active when clicked */
- if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
- "MA_NOACTIVATE\n");
-#endif
-
- /* */
- return MA_NOACTIVATE;
- }
-#endif
- if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
- return MA_NOACTIVATE;
-
- break;
-
- case WM_KILLFOCUS:
- /* Pop any pressed keys since we are losing keyboard focus */
- winKeybdReleaseKeys ();
- return 0;
-
- case WM_SYSDEADCHAR:
- case WM_DEADCHAR:
- /*
- * NOTE: We do nothing with WM_*CHAR messages,
- * nor does the root window, so we can just toss these messages.
- */
- return 0;
-
- case WM_SYSKEYDOWN:
- case WM_KEYDOWN:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
-#endif
-
- /*
- * Don't pass Alt-F4 key combo to root window,
- * let Windows translate to WM_CLOSE and close this top-level window.
- *
- * NOTE: We purposely don't check the fUseWinKillKey setting because
- * it should only apply to the key handling for the root window,
- * not for top-level window-manager windows.
- *
- * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
- * because that is a key combo that no X app should be expecting to
- * receive, since it has historically been used to shutdown the X server.
- * Passing Ctrl-Alt-Backspace to the root window preserves that
- * behavior, assuming that -unixkill has been passed as a parameter.
- */
- if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
- break;
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
-
- case WM_SYSKEYUP:
- case WM_KEYUP:
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
-#endif
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
-
- case WM_HOTKEY:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
-#endif
-
- /* Pass the message to the root window */
- SendMessage (hwndScreen, message, wParam, lParam);
- return 0;
-
- case WM_ERASEBKGND:
-#if CYGDEBUG
- winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n");
-#endif
- /*
- * Pretend that we did erase the background but we don't care,
- * since we repaint the entire region anyhow
- * This avoids some flickering when resizing.
- */
- return TRUE;
-
- case WM_PAINT:
-
- /* BeginPaint gives us an hdc that clips to the invalidated region */
- hdcUpdate = BeginPaint (hwnd, &ps);
-
- /* Try to copy from the shadow buffer */
- if (!BitBlt (hdcUpdate,
- ps.rcPaint.left, ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left,
- ps.rcPaint.bottom - ps.rcPaint.top,
- pRLWinPriv->hdcShadow,
- ps.rcPaint.left, ps.rcPaint.top,
- SRCCOPY))
- {
- LPVOID lpMsgBuf;
-
- /* Display a fancy error message */
- FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError (),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf,
- 0, NULL);
-
- ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
- (LPSTR)lpMsgBuf);
- LocalFree (lpMsgBuf);
- }
-
- /* EndPaint frees the DC */
- EndPaint (hwnd, &ps);
- break;
-
- case WM_ACTIVATE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
-#endif
- if (LOWORD(wParam) != WA_INACTIVE)
- {
- if (winIsInternalWMRunning(pScreenInfo))
- {
-#if 0
- /* Raise the window to the top in Z order */
- wmMsg.msg = WM_WM_RAISE;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
-#endif
- /* Tell our Window Manager thread to activate the window */
- wmMsg.msg = WM_WM_ACTIVATE;
- if (fWMMsgInitialized)
- if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMActivateWindow,
- pWin->drawable.id,
- 0, 0,
- 0, 0);
- }
- return 0;
-
-#if 1
- case WM_WINDOWPOSCHANGING:
- pWinPos = (LPWINDOWPOS)lParam;
- if (!(pWinPos->flags & SWP_NOZORDER))
- {
- if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
-#endif
- break;
- }
-
- if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
-#endif
- break;
- }
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("Win %08x forbid to change z order (%08x).\n",
- (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
-#endif
- pWinPos->flags |= SWP_NOZORDER;
- }
- break;
-#endif
-
- case WM_MOVE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
- if (g_fNoConfigureWindow) break;
-#if 0
- /* Bail if Windows window is not actually moving */
- if (pRLWinPriv->dwX == (short) LOWORD(lParam)
- && pRLWinPriv->dwY == (short) HIWORD(lParam))
- break;
-
- /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
- {
- WINDOWPLACEMENT windPlace;
- windPlace.length = sizeof (WINDOWPLACEMENT);
-
- /* Get current window placement */
- GetWindowPlacement (hwnd, &windPlace);
-
- /* Bail if maximizing */
- if (windPlace.showCmd == SW_MAXIMIZE
- || windPlace.showCmd == SW_SHOWMAXIMIZED)
- break;
- }
-#endif
-
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
-#endif
- if (!pRLWinPriv->fMovingOrSizing)
- {
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMMoveXWindow (pWin,
- (LOWORD(lParam) - wBorderWidth (pWin)
- - GetSystemMetrics (SM_XVIRTUALSCREEN)),
- (HIWORD(lParam) - wBorderWidth (pWin)
- - GetSystemMetrics (SM_YVIRTUALSCREEN)));
- }
- return 0;
-
- case WM_SHOWWINDOW:
-#if CYGMULTIWINDOW_DEBUG || TRUE
- winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
- /* Bail out if the window is being hidden */
- if (!wParam)
- return 0;
-
- if (!pScreenInfo->fInternalWM)//XXXX
- return 0;
-
- winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
-
- if (winIsInternalWMRunning(pScreenInfo))
- {
-#if CYGMULTIWINDOW_DEBUG || TRUE
- winDebug ("\tMapWindow\n");
-#endif
- /* Tell X to map the window */
- MapWindow (pWin, wClient(pWin));
-
- if (!pRLWinPriv->pFrame->win->overrideRedirect)
- /* Bring the Windows window to the foreground */
- SetForegroundWindow (hwnd);
-
- /* Setup the Window Manager message */
- wmMsg.msg = WM_WM_MAP;
- wmMsg.iWidth = pRLWinPriv->pFrame->width;
- wmMsg.iHeight = pRLWinPriv->pFrame->height;
-
- /* Tell our Window Manager thread to map the window */
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- break;
-
- case WM_SIZING:
- /* Need to legalize the size according to WM_NORMAL_HINTS */
- /* for applications like xterm */
- return ValidateSizing (hwnd, pWin, wParam, lParam);
-
- case WM_WINDOWPOSCHANGED:
- {
- pWinPos = (LPWINDOWPOS) lParam;
-#if CYGMULTIWINDOW_DEBUG
- winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
- winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
- (pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
- (pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
- (pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
- (pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
- (pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
- (pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
- (pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
- (pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
- (pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
- (pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
- (pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
- (pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
- winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
- winDebug("\textend: (%d, %d, %d, %d)\n",
- pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);
-
-#endif
- if (pWinPos->flags & SWP_HIDEWINDOW) break;
-
- /* Reorder if window z order was changed */
- if ((pScreenPriv != NULL)
- && !(pWinPos->flags & SWP_NOZORDER)
- && !(pWinPos->flags & SWP_SHOWWINDOW)
- && winIsInternalWMRunning(pScreenInfo))
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\twindow z order was changed\n");
-#endif
- if (pWinPos->hwndInsertAfter == HWND_TOP
- ||pWinPos->hwndInsertAfter == HWND_TOPMOST
- ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\traise to top\n");
-#endif
- /* Raise the window to the top in Z order */
- wmMsg.msg = WM_WM_RAISE;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
-#if 1
- else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
- {
- }
- else
- {
- /* Check if this window is top of X windows. */
- HWND hWndAbove = NULL;
- DWORD dwCurrentProcessID = GetCurrentProcessId ();
- DWORD dwWindowProcessID = 0;
-
- for (hWndAbove = pWinPos->hwndInsertAfter;
- hWndAbove != NULL;
- hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
- {
- /* Ignore other XWin process's window */
- GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);
-
- if ((dwWindowProcessID == dwCurrentProcessID)
- && GetProp (hWndAbove, WIN_WINDOW_PROP)
- && !IsWindowVisible (hWndAbove)
- && !IsIconic (hWndAbove) ) /* ignore minimized windows */
- break;
- }
- /* If this is top of X windows in Windows stack,
- raise it in X stack. */
- if (hWndAbove == NULL)
- {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\traise to top\n");
-#endif
- /* Raise the window to the top in Z order */
- wmMsg.msg = WM_WM_RAISE;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- }
-#endif
- }
-
- if (!(pWinPos->flags & SWP_NOSIZE)) {
- if (IsIconic(hwnd)){
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tIconic -> MINIMIZED\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- {
- /* Raise the window to the top in Z order */
- wmMsg.msg = WM_WM_LOWER;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMMinimizeWindow,
- pWin->drawable.id,
- 0, 0, 0, 0);
- } else if (IsZoomed(hwnd)){
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tZoomed -> MAXIMIZED\n");
-#endif
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMMaximizeWindow,
- pWin->drawable.id,
- 0, 0, 0, 0);
- } else {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tnone -> RESTORED\n");
-#endif
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMRestoreWindow,
- pWin->drawable.id,
- 0, 0, 0, 0);
- }
- }
- if (!g_fNoConfigureWindow ) {
-
- if (!pRLWinPriv->fMovingOrSizing
- /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
- GetClientRect (hwnd, &rcClient);
- MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
-
- if (!(pWinPos->flags & SWP_NOMOVE)
- &&!(pWinPos->flags & SWP_NOSIZE)) {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tmove & resize\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMMoveResizeXWindow (pWin,
- rcClient.left - wBorderWidth (pWin)
- - GetSystemMetrics (SM_XVIRTUALSCREEN),
- rcClient.top - wBorderWidth (pWin)
- - GetSystemMetrics (SM_YVIRTUALSCREEN),
- rcClient.right - rcClient.left
- - wBorderWidth (pWin)*2,
- rcClient.bottom - rcClient.top
- - wBorderWidth (pWin)*2);
- } else if (!(pWinPos->flags & SWP_NOMOVE)) {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tmove\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMMoveResizeXWindow (pWin,
- rcClient.left - wBorderWidth (pWin)
- - GetSystemMetrics (SM_XVIRTUALSCREEN),
- rcClient.top - wBorderWidth (pWin)
- - GetSystemMetrics (SM_YVIRTUALSCREEN),
- rcClient.right - rcClient.left
- - wBorderWidth (pWin)*2,
- rcClient.bottom - rcClient.top
- - wBorderWidth (pWin)*2);
- } else if (!(pWinPos->flags & SWP_NOMOVE)) {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tmove\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMMoveXWindow (pWin,
- rcClient.left - wBorderWidth (pWin)
- - GetSystemMetrics (SM_XVIRTUALSCREEN),
- rcClient.top - wBorderWidth (pWin)
- - GetSystemMetrics (SM_YVIRTUALSCREEN));
- } else if (!(pWinPos->flags & SWP_NOSIZE)) {
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tresize\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMResizeXWindow (pWin,
- rcClient.right - rcClient.left
- - wBorderWidth (pWin)*2,
- rcClient.bottom - rcClient.top
- - wBorderWidth (pWin)*2);
- }
- }
- }
- }
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
-#endif
- return 0;
-
- case WM_SIZE:
- /* see dix/window.c */
- /* FIXME: Maximize/Restore? */
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
-#endif
- if (g_fNoConfigureWindow) break;
-
- /* Branch on type of resizing occurring */
- switch (wParam)
- {
- case SIZE_MINIMIZED:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tSIZE_MINIMIZED\n");
-#endif
- if (winIsInternalWMRunning(pScreenInfo))
- {
- /* Raise the window to the top in Z order */
- wmMsg.msg = WM_WM_LOWER;
- if (fWMMsgInitialized)
- winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
- }
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMMinimizeWindow,
- pWin->drawable.id,
- 0, 0,
- LOWORD(lParam), HIWORD(lParam));
- break;
-
- case SIZE_RESTORED:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tSIZE_RESTORED\n");
-#endif
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMRestoreWindow,
- pWin->drawable.id,
- 0, 0,
- LOWORD(lParam), HIWORD(lParam));
- break;
-
- case SIZE_MAXIMIZED:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("\tSIZE_MAXIMIZED\n");
-#endif
- winWindowsWMSendEvent(WindowsWMControllerNotify,
- WindowsWMControllerNotifyMask,
- 1,
- WindowsWMMaximizeWindow,
- pWin->drawable.id,
- 0, 0,
- LOWORD(lParam), HIWORD(lParam));
- break;
- }
-
- /* Perform the resize and notify the X client */
- if (!pRLWinPriv->fMovingOrSizing)
- {
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMResizeXWindow (pWin,
- (short) LOWORD(lParam)
- - wBorderWidth (pWin)*2,
- (short) HIWORD(lParam)
- - wBorderWidth (pWin)*2);
- }
- break;
-
- case WM_ACTIVATEAPP:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
- if (wParam)
- {
- if (winIsInternalWMRunning(pScreenInfo))
- {
- }
- else
- {
- }
- winWindowsWMSendEvent(WindowsWMActivationNotify,
- WindowsWMActivationNotifyMask,
- 1,
- WindowsWMIsActive,
- pWin->drawable.id,
- 0, 0,
- 0, 0);
- }
- else
- {
- winWindowsWMSendEvent(WindowsWMActivationNotify,
- WindowsWMActivationNotifyMask,
- 1,
- WindowsWMIsInactive,
- pWin->drawable.id,
- 0, 0,
- 0, 0);
- }
- break;
-
- case WM_SETCURSOR:
- if (LOWORD(lParam) == HTCLIENT)
- {
- if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
- return TRUE;
- }
- break;
-
- case WM_ENTERSIZEMOVE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
- pRLWinPriv->fMovingOrSizing = TRUE;
- break;
-
- case WM_EXITSIZEMOVE:
-#if CYGMULTIWINDOW_DEBUG
- winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
- (unsigned int)GetTickCount ());
-#endif
- pRLWinPriv->fMovingOrSizing = FALSE;
-
- GetClientRect (hwnd, &rcClient);
-
- MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
-
- if (winIsInternalWMRunning(pScreenInfo))
- winAdjustXWindow (pWin, hwnd);
-
- winMWExtWMMoveResizeXWindow (pWin,
- rcClient.left - wBorderWidth (pWin)
- - GetSystemMetrics (SM_XVIRTUALSCREEN),
- rcClient.top - wBorderWidth (pWin)
- - GetSystemMetrics (SM_YVIRTUALSCREEN),
- rcClient.right - rcClient.left
- - wBorderWidth (pWin)*2,
- rcClient.bottom - rcClient.top
- - wBorderWidth (pWin)*2);
- break;
-
- case WM_MANAGE:
- ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
- break;
-
- case WM_UNMANAGE:
- ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
- break;
-
- default:
- break;
- }
-
- return DefWindowProc (hwnd, message, wParam, lParam);
-}
+/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ *Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ *"Software"), to deal in the Software without restriction, including
+ *without limitation the rights to use, copy, modify, merge, publish,
+ *distribute, sublicense, and/or sell copies of the Software, and to
+ *permit persons to whom the Software is furnished to do so, subject to
+ *the following conditions:
+ *
+ *The above copyright notice and this permission notice shall be
+ *included in all copies or substantial portions of the Software.
+ *
+ *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT 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 XFree86 Project
+ *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 XFree86 Project.
+ *
+ * Authors: Kensuke Matsuzaki
+ * Earle F. Philhower, III
+ * Harold L Hunt II
+ */
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include <winuser.h>
+#define _WINDOWSWM_SERVER_
+#include <X11/extensions/windowswmstr.h>
+#include "dixevents.h"
+#include "propertyst.h"
+#include <X11/Xatom.h>
+#include "winmultiwindowclass.h"
+#include "winmsg.h"
+#include "inputstr.h"
+
+
+/*
+ * Constant defines
+ */
+
+#define MOUSE_ACTIVATE_DEFAULT TRUE
+#define RAISE_ON_CLICK_DEFAULT FALSE
+
+
+/*
+ * Local globals
+ */
+
+static UINT_PTR g_uipMousePollingTimerID = 0;
+
+
+/*
+ * Local function
+ */
+
+DEFINE_ATOM_HELPER(AtmWindowsWmRaiseOnClick, WINDOWSWM_RAISE_ON_CLICK)
+DEFINE_ATOM_HELPER(AtmWindowsWMMouseActivate, WINDOWSWM_MOUSE_ACTIVATE)
+/* DEFINE_ATOM_HELPER(AtmWindowsWMClientWindow, WINDOWSWM_CLIENT_WINDOW) */
+
+/*
+ * ConstrainSize - Taken from TWM sources - Respects hints for sizing
+ */
+#define makemult(a,b) ((b==1) ? (a) : (((int)((a)/(b))) * (b)) )
+static void
+ConstrainSize (WinXSizeHints hints, int *widthp, int *heightp)
+{
+ int minWidth, minHeight, maxWidth, maxHeight, xinc, yinc, delta;
+ int baseWidth, baseHeight;
+ int dwidth = *widthp, dheight = *heightp;
+
+ if (hints.flags & PMinSize)
+ {
+ minWidth = hints.min_width;
+ minHeight = hints.min_height;
+ }
+ else if (hints.flags & PBaseSize)
+ {
+ minWidth = hints.base_width;
+ minHeight = hints.base_height;
+ }
+ else
+ minWidth = minHeight = 1;
+
+ if (hints.flags & PBaseSize)
+ {
+ baseWidth = hints.base_width;
+ baseHeight = hints.base_height;
+ }
+ else if (hints.flags & PMinSize)
+ {
+ baseWidth = hints.min_width;
+ baseHeight = hints.min_height;
+ }
+ else
+ baseWidth = baseHeight = 0;
+
+ if (hints.flags & PMaxSize)
+ {
+ maxWidth = hints.max_width;
+ maxHeight = hints.max_height;
+ }
+ else
+ {
+ maxWidth = MAXINT;
+ maxHeight = MAXINT;
+ }
+
+ if (hints.flags & PResizeInc)
+ {
+ xinc = hints.width_inc;
+ yinc = hints.height_inc;
+ }
+ else
+ xinc = yinc = 1;
+
+ /*
+ * First, clamp to min and max values
+ */
+ if (dwidth < minWidth)
+ dwidth = minWidth;
+ if (dheight < minHeight)
+ dheight = minHeight;
+
+ if (dwidth > maxWidth)
+ dwidth = maxWidth;
+ if (dheight > maxHeight)
+ dheight = maxHeight;
+
+ /*
+ * Second, fit to base + N * inc
+ */
+ dwidth = ((dwidth - baseWidth) / xinc * xinc) + baseWidth;
+ dheight = ((dheight - baseHeight) / yinc * yinc) + baseHeight;
+
+ /*
+ * Third, adjust for aspect ratio
+ */
+
+ /*
+ * The math looks like this:
+ *
+ * minAspectX dwidth maxAspectX
+ * ---------- <= ------- <= ----------
+ * minAspectY dheight maxAspectY
+ *
+ * If that is multiplied out, then the width and height are
+ * invalid in the following situations:
+ *
+ * minAspectX * dheight > minAspectY * dwidth
+ * maxAspectX * dheight < maxAspectY * dwidth
+ *
+ */
+
+ if (hints.flags & PAspect)
+ {
+ if (hints.min_aspect.x * dheight > hints.min_aspect.y * dwidth)
+ {
+ delta = makemult(hints.min_aspect.x * dheight / hints.min_aspect.y - dwidth, xinc);
+ if (dwidth + delta <= maxWidth)
+ dwidth += delta;
+ else
+ {
+ delta = makemult(dheight - dwidth*hints.min_aspect.y/hints.min_aspect.x, yinc);
+ if (dheight - delta >= minHeight)
+ dheight -= delta;
+ }
+ }
+
+ if (hints.max_aspect.x * dheight < hints.max_aspect.y * dwidth)
+ {
+ delta = makemult(dwidth * hints.max_aspect.y / hints.max_aspect.x - dheight, yinc);
+ if (dheight + delta <= maxHeight)
+ dheight += delta;
+ else
+ {
+ delta = makemult(dwidth - hints.max_aspect.x*dheight/hints.max_aspect.y, xinc);
+ if (dwidth - delta >= minWidth)
+ dwidth -= delta;
+ }
+ }
+ }
+
+ /* Return computed values */
+ *widthp = dwidth;
+ *heightp = dheight;
+}
+#undef makemult
+
+
+
+/*
+ * ValidateSizing - Ensures size request respects hints
+ */
+static int
+ValidateSizing (HWND hwnd, WindowPtr pWin,
+ WPARAM wParam, LPARAM lParam)
+{
+ WinXSizeHints sizeHints;
+ RECT *rect;
+ int iWidth, iHeight, iTopBorder;
+ POINT pt;
+
+ /* Invalid input checking */
+ if (pWin==NULL || lParam==0)
+ {
+ ErrorF ("Invalid input checking\n");
+ return FALSE;
+ }
+
+ /* No size hints, no checking */
+ if (!winMultiWindowGetWMNormalHints (pWin, &sizeHints))
+ {
+ ErrorF ("No size hints, no checking\n");
+ return FALSE;
+ }
+
+ /* Avoid divide-by-zero */
+ if (sizeHints.flags & PResizeInc)
+ {
+ if (sizeHints.width_inc == 0) sizeHints.width_inc = 1;
+ if (sizeHints.height_inc == 0) sizeHints.height_inc = 1;
+ }
+
+ rect = (RECT*)lParam;
+
+ iWidth = rect->right - rect->left;
+ iHeight = rect->bottom - rect->top;
+
+ /* Get title bar height, there must be an easier way?! */
+ pt.x = pt.y = 0;
+ ClientToScreen(hwnd, &pt);
+ iTopBorder = pt.y - rect->top;
+
+ /* Now remove size of any borders */
+ iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
+ iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
+
+ /* Constrain the size to legal values */
+ ConstrainSize (sizeHints, &iWidth, &iHeight);
+
+ /* Add back the borders */
+ iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
+ iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;
+
+ /* Adjust size according to where we're dragging from */
+ switch(wParam) {
+ case WMSZ_TOP:
+ case WMSZ_TOPRIGHT:
+ case WMSZ_BOTTOM:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_RIGHT:
+ rect->right = rect->left + iWidth;
+ break;
+ default:
+ rect->left = rect->right - iWidth;
+ break;
+ }
+ switch(wParam) {
+ case WMSZ_BOTTOM:
+ case WMSZ_BOTTOMRIGHT:
+ case WMSZ_BOTTOMLEFT:
+ case WMSZ_RIGHT:
+ case WMSZ_LEFT:
+ rect->bottom = rect->top + iHeight;
+ break;
+ default:
+ rect->top = rect->bottom - iHeight;
+ break;
+ }
+ return TRUE;
+}
+
+
+/*
+ * IsRaiseOnClick
+ */
+
+static Bool
+IsRaiseOnClick (WindowPtr pWin)
+{
+
+ struct _Window *pwin;
+ struct _Property *prop;
+ /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
+ * Which pointer's current window do we want? */
+ WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer);
+
+ if (!pWin)
+ {
+ ErrorF ("IsRaiseOnClick - no prop use default value:%d\n",
+ RAISE_ON_CLICK_DEFAULT);
+ return RAISE_ON_CLICK_DEFAULT;
+ }
+
+ pwin = (struct _Window*) pWin;
+
+ if (pwin->optional)
+ prop = (struct _Property *) pwin->optional->userProps;
+ else
+ prop = NULL;
+
+ while (prop)
+ {
+ if (prop->propertyName == AtmWindowsWmRaiseOnClick ()
+ && prop->type == XA_INTEGER
+ && prop->format == 32)
+ {
+ return *(int*)prop->data;
+ }
+ else
+ prop = prop->next;
+ }
+
+ if (pWin != pRoot)
+ {
+ return IsRaiseOnClick (pRoot);
+ }
+ else
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("IsRaiseOnClick - no prop use default value:%d\n",
+ RAISE_ON_CLICK_DEFAULT);
+#endif
+ return RAISE_ON_CLICK_DEFAULT;
+ }
+}
+
+
+/*
+ * IsMouseActive
+ */
+
+static Bool
+IsMouseActive (WindowPtr pWin)
+{
+
+ struct _Window *pwin;
+ struct _Property *prop;
+ /* XXX We're getting inputInfo.poniter here, but this might be really wrong.
+ * Which pointer's current window do we want? */
+ WindowPtr pRoot = GetCurrentRootWindow (inputInfo.pointer);
+
+ if (!pWin)
+ {
+ ErrorF ("IsMouseActive - pWin was NULL use default value:%d\n",
+ MOUSE_ACTIVATE_DEFAULT);
+ return MOUSE_ACTIVATE_DEFAULT;
+ }
+
+ pwin = (struct _Window*) pWin;
+
+ if (pwin->optional)
+ prop = (struct _Property *) pwin->optional->userProps;
+ else
+ prop = NULL;
+
+ while (prop)
+ {
+ if (prop->propertyName == AtmWindowsWMMouseActivate ()
+ && prop->type == XA_INTEGER
+ && prop->format == 32)
+ {
+ return *(int*)prop->data;
+ }
+ else
+ prop = prop->next;
+ }
+
+ if (pWin != pRoot)
+ {
+ return IsMouseActive (pRoot);
+ }
+ else
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("IsMouseActive - no prop use default value:%d\n",
+ MOUSE_ACTIVATE_DEFAULT);
+#endif
+ return MOUSE_ACTIVATE_DEFAULT;
+ }
+}
+
+
+/*
+ * winMWExtWMWindowProc - Window procedure
+ */
+
+LRESULT CALLBACK
+winMWExtWMWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ WindowPtr pWin = NULL;
+ win32RootlessWindowPtr pRLWinPriv = NULL;
+ ScreenPtr pScreen = NULL;
+ winPrivScreenPtr pScreenPriv = NULL;
+ winScreenInfo *pScreenInfo = NULL;
+ HWND hwndScreen = NULL;
+ POINT ptMouse;
+ static Bool s_fTracking = FALSE;
+ HDC hdcUpdate;
+ PAINTSTRUCT ps;
+ LPWINDOWPOS pWinPos = NULL;
+ RECT rcClient;
+ winWMMessageRec wmMsg;
+ Bool fWMMsgInitialized = FALSE;
+
+ /* Check if the Windows window property for our X window pointer is valid */
+ if ((pRLWinPriv = (win32RootlessWindowPtr)GetProp (hwnd, WIN_WINDOW_PROP)) != NULL)
+ {
+ pWin = pRLWinPriv->pFrame->win;
+ pScreen = pWin->drawable.pScreen;
+ if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
+ if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
+ if (pScreenPriv) hwndScreen = pScreenPriv->hwndScreen;
+
+ wmMsg.msg = 0;
+ wmMsg.hwndWindow = hwnd;
+ wmMsg.iWindow = (Window)pWin->drawable.id;
+
+ wmMsg.iX = pRLWinPriv->pFrame->x;
+ wmMsg.iY = pRLWinPriv->pFrame->y;
+ wmMsg.iWidth = pRLWinPriv->pFrame->width;
+ wmMsg.iHeight = pRLWinPriv->pFrame->height;
+
+ fWMMsgInitialized = TRUE;
+#if CYGDEBUG
+ winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam);
+
+ winDebug ("\thWnd %08X\n", hwnd);
+ winDebug ("\tpScreenPriv %08X\n", pScreenPriv);
+ winDebug ("\tpScreenInfo %08X\n", pScreenInfo);
+ winDebug ("\thwndScreen %08X\n", hwndScreen);
+ winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n",
+ pRLWinPriv, message, wParam, lParam);
+#endif
+ }
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_CREATE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_CREATE\n");
+#endif
+ /* */
+ SetProp (hwnd,
+ WIN_WINDOW_PROP,
+ (HANDLE)((LPCREATESTRUCT) lParam)->lpCreateParams);
+ return 0;
+
+ case WM_CLOSE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_CLOSE %d\n", pRLWinPriv->fClose);
+#endif
+ /* Tell window-manager to close window */
+ if (pRLWinPriv->fClose)
+ {
+ DestroyWindow (hwnd);
+ }
+ else
+ {
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+ /* Tell our Window Manager thread to kill the window */
+ wmMsg.msg = WM_WM_KILL;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMCloseWindow,
+ pWin->drawable.id,
+ 0, 0, 0, 0);
+ }
+ return 0;
+
+ case WM_DESTROY:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_DESTROY\n");
+#endif
+ /* Free the shaodw DC; which allows the bitmap to be freed */
+ DeleteDC (pRLWinPriv->hdcShadow);
+ pRLWinPriv->hdcShadow = NULL;
+
+ /* Free the shadow bitmap */
+ DeleteObject (pRLWinPriv->hbmpShadow);
+ pRLWinPriv->hbmpShadow = NULL;
+
+ /* Free the screen DC */
+ ReleaseDC (pRLWinPriv->hWnd, pRLWinPriv->hdcScreen);
+ pRLWinPriv->hdcScreen = NULL;
+
+ /* Free shadow buffer info header */
+ free (pRLWinPriv->pbmihShadow);
+ pRLWinPriv->pbmihShadow = NULL;
+
+ pRLWinPriv->fResized = FALSE;
+ pRLWinPriv->pfb = NULL;
+ free (pRLWinPriv);
+ RemoveProp (hwnd, WIN_WINDOW_PROP);
+ break;
+
+ case WM_MOUSEMOVE:
+#if CYGMULTIWINDOW_DEBUG && 0
+ winDebug ("winMWExtWMWindowProc - WM_MOUSEMOVE\n");
+#endif
+ /* Unpack the client area mouse coordinates */
+ ptMouse.x = GET_X_LPARAM(lParam);
+ ptMouse.y = GET_Y_LPARAM(lParam);
+
+ /* Translate the client area mouse coordinates to screen coordinates */
+ ClientToScreen (hwnd, &ptMouse);
+
+ /* Screen Coords from (-X, -Y) -> Root Window (0, 0) */
+ ptMouse.x -= GetSystemMetrics (SM_XVIRTUALSCREEN);
+ ptMouse.y -= GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* We can't do anything without privates */
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+
+ /* Has the mouse pointer crossed screens? */
+ if (pScreen != miPointerGetScreen(inputInfo.pointer))
+ miPointerSetScreen (inputInfo.pointer, pScreenInfo->dwScreen,
+ ptMouse.x - pScreenInfo->dwXOffset,
+ ptMouse.y - pScreenInfo->dwYOffset);
+
+ /* Are we tracking yet? */
+ if (!s_fTracking)
+ {
+ TRACKMOUSEEVENT tme;
+
+ /* Setup data structure */
+ ZeroMemory (&tme, sizeof (tme));
+ tme.cbSize = sizeof (tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+
+ /* Call the tracking function */
+ if (!TrackMouseEvent(&tme))
+ ErrorF ("winMWExtWMWindowProc - TrackMouseEvent failed\n");
+
+ /* Flag that we are tracking now */
+ s_fTracking = TRUE;
+ }
+
+ /* Kill the timer used to poll mouse events */
+ if (g_uipMousePollingTimerID != 0)
+ {
+ KillTimer (pScreenPriv->hwndScreen, WIN_POLLING_MOUSE_TIMER_ID);
+ g_uipMousePollingTimerID = 0;
+ }
+
+ /* Deliver absolute cursor position to X Server */
+ winEnqueueMotion(ptMouse.x - pScreenInfo->dwXOffset,
+ ptMouse.y - pScreenInfo->dwYOffset);
+
+ return 0;
+
+ case WM_NCMOUSEMOVE:
+#if CYGMULTIWINDOW_DEBUG && 0
+ winDebug ("winMWExtWMWindowProc - WM_NCMOUSEMOVE\n");
+#endif
+ /*
+ * We break instead of returning 0 since we need to call
+ * DefWindowProc to get the mouse cursor changes
+ * and min/max/close button highlighting in Windows XP.
+ * The Platform SDK says that you should return 0 if you
+ * process this message, but it fails to mention that you
+ * will give up any default functionality if you do return 0.
+ */
+
+ /* We can't do anything without privates */
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+
+ /*
+ * Timer to poll mouse events. This is needed to make
+ * programs like xeyes follow the mouse properly.
+ */
+ if (g_uipMousePollingTimerID == 0)
+ g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
+ WIN_POLLING_MOUSE_TIMER_ID,
+ MOUSE_POLLING_INTERVAL,
+ NULL);
+ break;
+
+ case WM_MOUSELEAVE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MOUSELEAVE\n");
+#endif
+ /* Mouse has left our client area */
+
+ /* Flag that we are no longer tracking */
+ s_fTracking = FALSE;
+
+ /*
+ * Timer to poll mouse events. This is needed to make
+ * programs like xeyes follow the mouse properly.
+ */
+ if (g_uipMousePollingTimerID == 0)
+ g_uipMousePollingTimerID = SetTimer (pScreenPriv->hwndScreen,
+ WIN_POLLING_MOUSE_TIMER_ID,
+ MOUSE_POLLING_INTERVAL,
+ NULL);
+ return 0;
+
+ case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDOWN:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_LBUTTONDBLCLK\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ SetCapture (hwnd);
+ return winMouseButtonsHandle (pScreen, ButtonPress, Button1, wParam);
+
+ case WM_LBUTTONUP:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_LBUTTONUP\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ ReleaseCapture ();
+ return winMouseButtonsHandle (pScreen, ButtonRelease, Button1, wParam);
+
+ case WM_MBUTTONDBLCLK:
+ case WM_MBUTTONDOWN:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MBUTTONDBLCLK\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ SetCapture (hwnd);
+ return winMouseButtonsHandle (pScreen, ButtonPress, Button2, wParam);
+
+ case WM_MBUTTONUP:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MBUTTONUP\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ ReleaseCapture ();
+ return winMouseButtonsHandle (pScreen, ButtonRelease, Button2, wParam);
+
+ case WM_RBUTTONDBLCLK:
+ case WM_RBUTTONDOWN:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_RBUTTONDBLCLK\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ SetCapture (hwnd);
+ return winMouseButtonsHandle (pScreen, ButtonPress, Button3, wParam);
+
+ case WM_RBUTTONUP:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_RBUTTONUP\n");
+#endif
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ ReleaseCapture ();
+ return winMouseButtonsHandle (pScreen, ButtonRelease, Button3, wParam);
+
+ case WM_XBUTTONDBLCLK:
+ case WM_XBUTTONDOWN:
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ SetCapture (hwnd);
+ return winMouseButtonsHandle (pScreen, ButtonPress, HIWORD(wParam) + 5, wParam);
+ case WM_XBUTTONUP:
+ if (pScreenPriv == NULL || pScreenInfo->fIgnoreInput)
+ break;
+ ReleaseCapture ();
+ return winMouseButtonsHandle (pScreen, ButtonRelease, HIWORD(wParam) + 5, wParam);
+
+ case WM_MOUSEWHEEL:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MOUSEWHEEL\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_MOUSEACTIVATE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE\n");
+#endif
+#if 1
+ /* Check if this window needs to be made active when clicked */
+ if (winIsInternalWMRunning(pScreenInfo) && pWin->overrideRedirect)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MOUSEACTIVATE - "
+ "MA_NOACTIVATE\n");
+#endif
+
+ /* */
+ return MA_NOACTIVATE;
+ }
+#endif
+ if (!winIsInternalWMRunning(pScreenInfo) && !IsMouseActive (pWin))
+ return MA_NOACTIVATE;
+
+ break;
+
+ case WM_KILLFOCUS:
+ /* Pop any pressed keys since we are losing keyboard focus */
+ winKeybdReleaseKeys ();
+ return 0;
+
+ case WM_SYSDEADCHAR:
+ case WM_DEADCHAR:
+ /*
+ * NOTE: We do nothing with WM_*CHAR messages,
+ * nor does the root window, so we can just toss these messages.
+ */
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_*KEYDOWN\n");
+#endif
+
+ /*
+ * Don't pass Alt-F4 key combo to root window,
+ * let Windows translate to WM_CLOSE and close this top-level window.
+ *
+ * NOTE: We purposely don't check the fUseWinKillKey setting because
+ * it should only apply to the key handling for the root window,
+ * not for top-level window-manager windows.
+ *
+ * ALSO NOTE: We do pass Ctrl-Alt-Backspace to the root window
+ * because that is a key combo that no X app should be expecting to
+ * receive, since it has historically been used to shutdown the X server.
+ * Passing Ctrl-Alt-Backspace to the root window preserves that
+ * behavior, assuming that -unixkill has been passed as a parameter.
+ */
+ if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000))
+ break;
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_*KEYUP\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_HOTKEY:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_HOTKEY\n");
+#endif
+
+ /* Pass the message to the root window */
+ SendMessage (hwndScreen, message, wParam, lParam);
+ return 0;
+
+ case WM_ERASEBKGND:
+#if CYGDEBUG
+ winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n");
+#endif
+ /*
+ * Pretend that we did erase the background but we don't care,
+ * since we repaint the entire region anyhow
+ * This avoids some flickering when resizing.
+ */
+ return TRUE;
+
+ case WM_PAINT:
+
+ /* BeginPaint gives us an hdc that clips to the invalidated region */
+ hdcUpdate = BeginPaint (hwnd, &ps);
+
+ /* Try to copy from the shadow buffer */
+ if (!BitBlt (hdcUpdate,
+ ps.rcPaint.left, ps.rcPaint.top,
+ ps.rcPaint.right - ps.rcPaint.left,
+ ps.rcPaint.bottom - ps.rcPaint.top,
+ pRLWinPriv->hdcShadow,
+ ps.rcPaint.left, ps.rcPaint.top,
+ SRCCOPY))
+ {
+ LPVOID lpMsgBuf;
+
+ /* Display a fancy error message */
+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError (),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+
+ ErrorF ("winMWExtWMWindowProc - BitBlt failed: %s\n",
+ (LPSTR)lpMsgBuf);
+ LocalFree (lpMsgBuf);
+ }
+
+ /* EndPaint frees the DC */
+ EndPaint (hwnd, &ps);
+ break;
+
+ case WM_ACTIVATE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_ACTIVATE\n");
+#endif
+ if (LOWORD(wParam) != WA_INACTIVE)
+ {
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+#if 0
+ /* Raise the window to the top in Z order */
+ wmMsg.msg = WM_WM_RAISE;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+#endif
+ /* Tell our Window Manager thread to activate the window */
+ wmMsg.msg = WM_WM_ACTIVATE;
+ if (fWMMsgInitialized)
+ if (!pWin || !pWin->overrideRedirect) /* for OOo menus */
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMActivateWindow,
+ pWin->drawable.id,
+ 0, 0,
+ 0, 0);
+ }
+ return 0;
+
+#if 1
+ case WM_WINDOWPOSCHANGING:
+ pWinPos = (LPWINDOWPOS)lParam;
+ if (!(pWinPos->flags & SWP_NOZORDER))
+ {
+ if (pRLWinPriv->fRestackingNow || pScreenPriv->fRestacking)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("Win %08x is now restacking.\n", (unsigned int)pRLWinPriv);
+#endif
+ break;
+ }
+
+ if (winIsInternalWMRunning(pScreenInfo) || IsRaiseOnClick (pWin))
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("Win %08x has WINDOWSWM_RAISE_ON_CLICK.\n", (unsigned int)pRLWinPriv);
+#endif
+ break;
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("Win %08x forbid to change z order (%08x).\n",
+ (unsigned int)pRLWinPriv, (unsigned int)pWinPos->hwndInsertAfter);
+#endif
+ pWinPos->flags |= SWP_NOZORDER;
+ }
+ break;
+#endif
+
+ case WM_MOVE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_MOVE - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+ if (g_fNoConfigureWindow) break;
+#if 0
+ /* Bail if Windows window is not actually moving */
+ if (pRLWinPriv->dwX == (short) LOWORD(lParam)
+ && pRLWinPriv->dwY == (short) HIWORD(lParam))
+ break;
+
+ /* Also bail if we're maximizing, we'll do the whole thing in WM_SIZE */
+ {
+ WINDOWPLACEMENT windPlace;
+ windPlace.length = sizeof (WINDOWPLACEMENT);
+
+ /* Get current window placement */
+ GetWindowPlacement (hwnd, &windPlace);
+
+ /* Bail if maximizing */
+ if (windPlace.showCmd == SW_MAXIMIZE
+ || windPlace.showCmd == SW_SHOWMAXIMIZED)
+ break;
+ }
+#endif
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\t(%d, %d)\n", (short) LOWORD(lParam), (short) HIWORD(lParam));
+#endif
+ if (!pRLWinPriv->fMovingOrSizing)
+ {
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMMoveXWindow (pWin,
+ (LOWORD(lParam) - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_XVIRTUALSCREEN)),
+ (HIWORD(lParam) - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_YVIRTUALSCREEN)));
+ }
+ return 0;
+
+ case WM_SHOWWINDOW:
+#if CYGMULTIWINDOW_DEBUG || TRUE
+ winDebug ("winMWExtWMWindowProc - WM_SHOWWINDOW - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+ /* Bail out if the window is being hidden */
+ if (!wParam)
+ return 0;
+
+ if (!pScreenInfo->fInternalWM)//XXXX
+ return 0;
+
+ winMWExtWMUpdateWindowDecoration (pRLWinPriv, pScreenInfo);
+
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+#if CYGMULTIWINDOW_DEBUG || TRUE
+ winDebug ("\tMapWindow\n");
+#endif
+ /* Tell X to map the window */
+ MapWindow (pWin, wClient(pWin));
+
+ if (!pRLWinPriv->pFrame->win->overrideRedirect)
+ /* Bring the Windows window to the foreground */
+ SetForegroundWindow (hwnd);
+
+ /* Setup the Window Manager message */
+ wmMsg.msg = WM_WM_MAP;
+ wmMsg.iWidth = pRLWinPriv->pFrame->width;
+ wmMsg.iHeight = pRLWinPriv->pFrame->height;
+
+ /* Tell our Window Manager thread to map the window */
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ break;
+
+ case WM_SIZING:
+ /* Need to legalize the size according to WM_NORMAL_HINTS */
+ /* for applications like xterm */
+ return ValidateSizing (hwnd, pWin, wParam, lParam);
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ pWinPos = (LPWINDOWPOS) lParam;
+#if CYGMULTIWINDOW_DEBUG
+ winDebug("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED\n");
+ winDebug("\tflags: %s%s%s%s%s%s%s%s%s%s%s%s\n",
+ (pWinPos->flags & SWP_DRAWFRAME)?"SWP_DRAWFRAME ":"",
+ (pWinPos->flags & SWP_FRAMECHANGED)?"SWP_FRAMECHANGED ":"",
+ (pWinPos->flags & SWP_HIDEWINDOW)?"SWP_HIDEWINDOW ":"",
+ (pWinPos->flags & SWP_NOACTIVATE)?"SWP_NOACTIVATE ":"",
+ (pWinPos->flags & SWP_NOCOPYBITS)?"SWP_NOCOPYBITS ":"",
+ (pWinPos->flags & SWP_NOMOVE)?"SWP_NOMOVE ":"",
+ (pWinPos->flags & SWP_NOOWNERZORDER)?"SWP_NOOWNERZORDER ":"",
+ (pWinPos->flags & SWP_NOSIZE)?"SWP_NOSIZE ":"",
+ (pWinPos->flags & SWP_NOREDRAW)?"SWP_NOREDRAW ":"",
+ (pWinPos->flags & SWP_NOSENDCHANGING)?"SWP_NOSENDCHANGING ":"",
+ (pWinPos->flags & SWP_NOZORDER)?"SWP_NOZORDER ":"",
+ (pWinPos->flags & SWP_SHOWWINDOW)?"SWP_SHOWWINDOW ":"");
+ winDebug("\tno_configure: %s\n", (g_fNoConfigureWindow?"Yes":"No"));
+ winDebug("\textend: (%d, %d, %d, %d)\n",
+ pWinPos->x, pWinPos->y, pWinPos->cx, pWinPos->cy);
+
+#endif
+ if (pWinPos->flags & SWP_HIDEWINDOW) break;
+
+ /* Reorder if window z order was changed */
+ if ((pScreenPriv != NULL)
+ && !(pWinPos->flags & SWP_NOZORDER)
+ && !(pWinPos->flags & SWP_SHOWWINDOW)
+ && winIsInternalWMRunning(pScreenInfo))
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\twindow z order was changed\n");
+#endif
+ if (pWinPos->hwndInsertAfter == HWND_TOP
+ ||pWinPos->hwndInsertAfter == HWND_TOPMOST
+ ||pWinPos->hwndInsertAfter == HWND_NOTOPMOST)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\traise to top\n");
+#endif
+ /* Raise the window to the top in Z order */
+ wmMsg.msg = WM_WM_RAISE;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+#if 1
+ else if (pWinPos->hwndInsertAfter == HWND_BOTTOM)
+ {
+ }
+ else
+ {
+ /* Check if this window is top of X windows. */
+ HWND hWndAbove = NULL;
+ DWORD dwCurrentProcessID = GetCurrentProcessId ();
+ DWORD dwWindowProcessID = 0;
+
+ for (hWndAbove = pWinPos->hwndInsertAfter;
+ hWndAbove != NULL;
+ hWndAbove = GetNextWindow (hWndAbove, GW_HWNDPREV))
+ {
+ /* Ignore other XWin process's window */
+ GetWindowThreadProcessId (hWndAbove, &dwWindowProcessID);
+
+ if ((dwWindowProcessID == dwCurrentProcessID)
+ && GetProp (hWndAbove, WIN_WINDOW_PROP)
+ && !IsWindowVisible (hWndAbove)
+ && !IsIconic (hWndAbove) ) /* ignore minimized windows */
+ break;
+ }
+ /* If this is top of X windows in Windows stack,
+ raise it in X stack. */
+ if (hWndAbove == NULL)
+ {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\traise to top\n");
+#endif
+ /* Raise the window to the top in Z order */
+ wmMsg.msg = WM_WM_RAISE;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ }
+#endif
+ }
+
+ if (!(pWinPos->flags & SWP_NOSIZE)) {
+ if (IsIconic(hwnd)){
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tIconic -> MINIMIZED\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+ /* Raise the window to the top in Z order */
+ wmMsg.msg = WM_WM_LOWER;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMMinimizeWindow,
+ pWin->drawable.id,
+ 0, 0, 0, 0);
+ } else if (IsZoomed(hwnd)){
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tZoomed -> MAXIMIZED\n");
+#endif
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMMaximizeWindow,
+ pWin->drawable.id,
+ 0, 0, 0, 0);
+ } else {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tnone -> RESTORED\n");
+#endif
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMRestoreWindow,
+ pWin->drawable.id,
+ 0, 0, 0, 0);
+ }
+ }
+ if (!g_fNoConfigureWindow ) {
+
+ if (!pRLWinPriv->fMovingOrSizing
+ /*&& (pWinPos->flags & SWP_SHOWWINDOW)*/) {
+ GetClientRect (hwnd, &rcClient);
+ MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
+
+ if (!(pWinPos->flags & SWP_NOMOVE)
+ &&!(pWinPos->flags & SWP_NOSIZE)) {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tmove & resize\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMMoveResizeXWindow (pWin,
+ rcClient.left - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_XVIRTUALSCREEN),
+ rcClient.top - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_YVIRTUALSCREEN),
+ rcClient.right - rcClient.left
+ - wBorderWidth (pWin)*2,
+ rcClient.bottom - rcClient.top
+ - wBorderWidth (pWin)*2);
+ } else if (!(pWinPos->flags & SWP_NOMOVE)) {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tmove\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMMoveResizeXWindow (pWin,
+ rcClient.left - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_XVIRTUALSCREEN),
+ rcClient.top - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_YVIRTUALSCREEN),
+ rcClient.right - rcClient.left
+ - wBorderWidth (pWin)*2,
+ rcClient.bottom - rcClient.top
+ - wBorderWidth (pWin)*2);
+ } else if (!(pWinPos->flags & SWP_NOMOVE)) {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tmove\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMMoveXWindow (pWin,
+ rcClient.left - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_XVIRTUALSCREEN),
+ rcClient.top - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_YVIRTUALSCREEN));
+ } else if (!(pWinPos->flags & SWP_NOSIZE)) {
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tresize\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMResizeXWindow (pWin,
+ rcClient.right - rcClient.left
+ - wBorderWidth (pWin)*2,
+ rcClient.bottom - rcClient.top
+ - wBorderWidth (pWin)*2);
+ }
+ }
+ }
+ }
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_WINDOWPOSCHANGED - done.\n");
+#endif
+ return 0;
+
+ case WM_SIZE:
+ /* see dix/window.c */
+ /* FIXME: Maximize/Restore? */
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_SIZE - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\t(%d, %d) %d\n", (short) LOWORD(lParam), (short) HIWORD(lParam), g_fNoConfigureWindow);
+#endif
+ if (g_fNoConfigureWindow) break;
+
+ /* Branch on type of resizing occurring */
+ switch (wParam)
+ {
+ case SIZE_MINIMIZED:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tSIZE_MINIMIZED\n");
+#endif
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+ /* Raise the window to the top in Z order */
+ wmMsg.msg = WM_WM_LOWER;
+ if (fWMMsgInitialized)
+ winSendMessageToWM (pScreenPriv->pWMInfo, &wmMsg);
+ }
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMMinimizeWindow,
+ pWin->drawable.id,
+ 0, 0,
+ LOWORD(lParam), HIWORD(lParam));
+ break;
+
+ case SIZE_RESTORED:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tSIZE_RESTORED\n");
+#endif
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMRestoreWindow,
+ pWin->drawable.id,
+ 0, 0,
+ LOWORD(lParam), HIWORD(lParam));
+ break;
+
+ case SIZE_MAXIMIZED:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("\tSIZE_MAXIMIZED\n");
+#endif
+ winWindowsWMSendEvent(WindowsWMControllerNotify,
+ WindowsWMControllerNotifyMask,
+ 1,
+ WindowsWMMaximizeWindow,
+ pWin->drawable.id,
+ 0, 0,
+ LOWORD(lParam), HIWORD(lParam));
+ break;
+ }
+
+ /* Perform the resize and notify the X client */
+ if (!pRLWinPriv->fMovingOrSizing)
+ {
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMResizeXWindow (pWin,
+ (short) LOWORD(lParam)
+ - wBorderWidth (pWin)*2,
+ (short) HIWORD(lParam)
+ - wBorderWidth (pWin)*2);
+ }
+ break;
+
+ case WM_ACTIVATEAPP:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_ACTIVATEAPP - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+ if (wParam)
+ {
+ if (winIsInternalWMRunning(pScreenInfo))
+ {
+ }
+ else
+ {
+ }
+ winWindowsWMSendEvent(WindowsWMActivationNotify,
+ WindowsWMActivationNotifyMask,
+ 1,
+ WindowsWMIsActive,
+ pWin->drawable.id,
+ 0, 0,
+ 0, 0);
+ }
+ else
+ {
+ winWindowsWMSendEvent(WindowsWMActivationNotify,
+ WindowsWMActivationNotifyMask,
+ 1,
+ WindowsWMIsInactive,
+ pWin->drawable.id,
+ 0, 0,
+ 0, 0);
+ }
+ break;
+
+ case WM_SETCURSOR:
+ if (LOWORD(lParam) == HTCLIENT)
+ {
+ if (!g_fSoftwareCursor) SetCursor (pScreenPriv->cursor.handle);
+ return TRUE;
+ }
+ break;
+
+ case WM_ENTERSIZEMOVE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_ENTERSIZEMOVE - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+ pRLWinPriv->fMovingOrSizing = TRUE;
+ break;
+
+ case WM_EXITSIZEMOVE:
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMWExtWMWindowProc - WM_EXITSIZEMOVE - %d ms\n",
+ (unsigned int)GetTickCount ());
+#endif
+ pRLWinPriv->fMovingOrSizing = FALSE;
+
+ GetClientRect (hwnd, &rcClient);
+
+ MapWindowPoints (hwnd, HWND_DESKTOP, (LPPOINT)&rcClient, 2);
+
+ if (winIsInternalWMRunning(pScreenInfo))
+ winAdjustXWindow (pWin, hwnd);
+
+ winMWExtWMMoveResizeXWindow (pWin,
+ rcClient.left - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_XVIRTUALSCREEN),
+ rcClient.top - wBorderWidth (pWin)
+ - GetSystemMetrics (SM_YVIRTUALSCREEN),
+ rcClient.right - rcClient.left
+ - wBorderWidth (pWin)*2,
+ rcClient.bottom - rcClient.top
+ - wBorderWidth (pWin)*2);
+ break;
+
+ case WM_MANAGE:
+ ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n");
+ break;
+
+ case WM_UNMANAGE:
+ ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n");
+ break;
+
+ default:
+ break;
+ }
+
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c
index 403c859e7..577614db6 100644
--- a/xorg-server/hw/xwin/winwindowswm.c
+++ b/xorg-server/hw/xwin/winwindowswm.c
@@ -629,9 +629,11 @@ winWindowsWMExtensionInit (void)
NULL,
StandardMinorOpcode)))
{
+ size_t i;
WMReqCode = (unsigned char)extEntry->base;
WMErrorBase = extEntry->errorBase;
WMEventBase = extEntry->eventBase;
- EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
+ for (i=0; i < WindowsWMNumberEvents; i++)
+ EventSwapVector[WMEventBase + i] = (EventSwapPtr) SNotifyEvent;
}
}
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c
index bccd6f9f2..a89857a14 100644
--- a/xorg-server/hw/xwin/winwndproc.c
+++ b/xorg-server/hw/xwin/winwndproc.c
@@ -776,8 +776,8 @@ winWindowProc (HWND hwnd, UINT message,
tme.hwndTrack = hwnd;
/* Call the tracking function */
- if (!(*g_fpTrackMouseEvent) (&tme))
- ErrorF ("winWindowProc - _TrackMouseEvent failed\n");
+ if (!TrackMouseEvent(&tme))
+ ErrorF ("winWindowProc - TrackMouseEvent failed\n");
/* Flag that we are tracking now */
s_fTracking = TRUE;